非平凡的“未在此范围内声明”错误

时间:2013-11-20 15:37:17

标签: c++ function compiler-errors scope

我在以下函数中出现了“未在此范围内声明”的错误:

double monteCarlo(void)
{
    double intervalArea = 2*(upperBound - lowerBound); // (f_max(x)) - f_min(x))*(upperBound - lowerBound) - Could be calculated from derivative, but known for this function.
    for (uint currentPoints = (numPoints/100); currentPoints < numPoints; currentPoints += (numPoints/100))
    {   
        double area = randx = randy = 0;
        uint underCurve = 0;
        gsl_rng* rndGen = gsl_rng_alloc (gsl_rng_mt19937); // Initialize random number generation
        gsl_rng_set(rndGen,timeSeed()); // Seed random number generation

        for (uint point= 1; point <= currentPoints; point++)
        {
            randx = gsl_rng_uniform(rndGen); randy = ((2*gsl_rng_uniform_pos(rndGen)) -1);
            if (randy <= f(ranx))
            {
                underCurve++;
            }
        }

        area = (underCurve/currentPoints)*intervalArea;
        output << currentSubintervals << "\t" <<  area << std::endl;
    }

    return area;
}

double trapezoidal(void)
{
    for (uint currentSubintervals = 1; currentSubintervals <= subintervals; currrentSubintervals++)
    {   
        double area = stepSize = sum = 0;

        double stepSize = ((upperBound - lowerBound)/currentSubintervals);
        double sum = (f(lowerBound) + f(upperBound))/2;

        for (uint currentInterval = 1; i < currentSubintervals; currentInterval++)
        {
            sum += f(lowerBound + (currentInterval*stepSize));
        }
        area = stepSize*sum;
        output << currentSubintervals << "\t" <<  area << std::endl;
    }

    return area;
}

我得到的错误是:

g++ -c -Wall -std=c++11 integrate.cpp -o integrate.o
integrate.cpp: In function ‘double monteCarlo()’:
integrate.cpp:118:17: error: ‘randx’ was not declared in this scope
integrate.cpp:118:25: error: ‘randy’ was not declared in this scope
integrate.cpp:126:19: error: ‘ranx’ was not declared in this scope
integrate.cpp:133:13: error: ‘currentSubintervals’ was not declared in this scope
integrate.cpp:136:9: error: ‘area’ was not declared in this scope
integrate.cpp: In function ‘double trapezoidal()’:
integrate.cpp:141:74: error: ‘currrentSubintervals’ was not declared in this scope
integrate.cpp:143:17: error: ‘stepSize’ was not declared in this scope
integrate.cpp:143:28: error: ‘sum’ was not declared in this scope
integrate.cpp:148:34: error: ‘i’ was not declared in this scope
integrate.cpp:156:9: error: ‘area’ was not declared in this scope
integrate.cpp:157:1: warning: control reaches end of non-void function [-Wreturn-type]
integrate.cpp: In function ‘double monteCarlo()’:
integrate.cpp:137:1: warning: control reaches end of non-void function [-Wreturn-type]
make: *** [integrate.o] Error 1

这是......非常奇怪,因为变量都是在函数本身中声明和使用的。我试图在MWE中重现它,但我什么都没有。

我能真正问的是......帮助吗?我不知道这里有什么问题。我已经尝试了几个小时,并且搜索了很多。

#include "integrate.hpp"

//=======================
// Globals

static uint algorithm_flag = 0; // Flag for which algoirthm to use
static std::string algorithm = "none";
static double lowerBound = 0, upperBound = 1; // "Global" bounds for algorithms
static uint subintervals = 0, numPoints = pow(2,16);
static int option_index = 0;
static std::ofstream output ("integrate.data");

//=======================
// Main

int main(int argc, char **argv)
{
    std::cout << " Numerical Integrator of cos(1/x)!\n"
                        << "-----------------------------------\n";

    if (!(handleArgs(argc, argv)))
    {
        throw std::invalid_argument(argv[option_index]);
        return -1;
    }
    std::cout << " Algorithm: "  << algorithm << std::endl
                        << " Lower Bound: " << lowerBound << std::endl
                        << " Upper Bound: " << upperBound << std::endl; 
                        switch(algorithm_flag)
                        {
                            case 1:
                                std::cout << " Number of Points: " << numPoints << std::endl << " Number of Subintervals: " << subintervals;
                                break;
                            case 2:
                                std::cout << " Number of Points: " << numPoints;
                                break;
                            case 3:
                                std::cout << " Number of Subintervals: " << subintervals;
                                break;
                        }
    std::cout << std::endl << "-----------------------------------" << std::endl;

    double area, diff, percentError, actualArea = -0.08441095055957388688903177037359518055393632433151889234592026720612077182783481670736342350213473343;

    if (algorithm_flag == 2 || algorithm_flag == 1)
    {
                std::cout << " Monte Carlo:" << std::endl;
                area = monteCarlo();
                diff = area - actualArea;
                percentError = (diff/actualArea)*100;
                std::cout   << " Calculated area:\t" << area << std::endl 
                                    << " Error:\t\t\t" << diff << std::endl
                                    << " Accuracy:\t\t" << percentError << "%" << std::endl;
    }
    else if (algorithm_flag == 3 || algorithm_flag == 1)
    {
                std::cout << " Trapezoid: " << std::endl;
                area = trapezoidal();
                diff = area - actualArea;
                percentError = (diff/actualArea)*100;
                std::cout   << " Calculated area:\t" << area << std::endl 
                                    << " Error:\t\t\t" << diff << std::endl
                                    << " Accuracy:\t\t" << percentError << "%" << std::endl;            
    }
    else
    {       
                std::cout << " Please specify a numerical integration algorithm!" << std::endl 
                                    << "\tSpecify the -m flag for Monte Carlo" << std::endl 
                                    << "\tSpecify the -t flag for Trapezoial" << std::endl 
                                    << "\tSpecify the -a flag for both algorithms" << std::endl;
                throw std::logic_error(algorithm);
                return -2;
    }   

    std::cout << std::endl << "-----------------------------------" << std::endl
                        << "Please see ./integrate.data for the full details of the integration." << std::endl;

    output.close();
    return 0;
}

//=======================
// Functions

double f(double x)
{
    double y = cos(1/x);
    return y;
}

double monteCarlo(void)
{
    double intervalArea = 2*(upperBound - lowerBound); // (f_max(x)) - f_min(x))*(upperBound - lowerBound) - Could be calculated from derivative, but known for this function.
    for (uint currentPoints = (numPoints/100); currentPoints < numPoints; currentPoints += (numPoints/100))
    {   
        double area = randx = randy = 0;
        uint underCurve = 0;
        gsl_rng* rndGen = gsl_rng_alloc (gsl_rng_mt19937); // Initialize random number generation
        gsl_rng_set(rndGen,timeSeed()); // Seed random number generation

        for (uint point= 1; point <= currentPoints; point++)
        {
            randx = gsl_rng_uniform(rndGen); randy = ((2*gsl_rng_uniform_pos(rndGen)) -1);
            if (randy <= f(ranx))
            {
                underCurve++;
            }
        }

        area = (underCurve/currentPoints)*intervalArea;
        output << currentSubintervals << "\t" <<  area << std::endl;
    }

    return area;
}

double trapezoidal(void)
{
    for (uint currentSubintervals = 1; currentSubintervals <= subintervals; currrentSubintervals++)
    {   
        double area = stepSize = sum = 0;

        double stepSize = ((upperBound - lowerBound)/currentSubintervals);
        double sum = (f(lowerBound) + f(upperBound))/2;

        for (uint currentInterval = 1; i < currentSubintervals; currentInterval++)
        {
            sum += f(lowerBound + (currentInterval*stepSize));
        }
        area = stepSize*sum;
        output << currentSubintervals << "\t" <<  area << std::endl;
    }

    return area;
}

bool handleArgs(int argc, char *argv[])
{
    int arg = 0;
    bool rtVal = true;

    while ((arg = getopt_long (argc, argv, "mtau:l:i:p:",long_options, &option_index)) != -1)
    {

        if(optarg == 0)
        {
            continue;
        }

        switch(arg)
        {
                case 'a':
                    if (algorithm_flag > 1)
                    {
                        std::cout << "Cannot specify more than one algoirthm type, please use --all for both, or use only one";
                    }
                    algorithm_flag = 1;
                    algorithm = "Monte Carlo and Trapezoidal";
                break;
            case 'm':
                    if (algorithm_flag)
                    {
                        std::cout << "Cannot specify more than one algoirthm type, please use --all for both, or use only one";
                    }
                    algorithm_flag = 2;
                    algorithm = "Monte Carlo";
                break;
            case 't':
                    if (algorithm_flag)
                    {
                        std::cout << "Cannot specify more than one algoirthm type, please use --all for both, or use only one";
                    }
                    algorithm_flag = 3;
                    algorithm = "Trapezoidal";
                break;
            case 'u':
                    upperBound = atoi(optarg);
                break;
            case 'l':
                    lowerBound = atoi(optarg);
                break;
            case 'i':
                    subintervals = atoi(optarg);
                break;
            case 'p':
                    numPoints = atoi(optarg);
                break;
            case '?':
                /* getopt already printed an error message. */
                rtVal = false;
                break;
            default:
                rtVal = false;
        }

        if(!(rtVal))
        {
            std::cout << "Invalid option " << arg;
            if (optarg)
            {
             std::cout << " with arg " << optarg;
            }
            std::cout << std::endl;
            throw std::invalid_argument(argv[option_index]);
            break;
        }
    }

    return rtVal;
}

头文件是:

//=======================
// Guard Statment
#ifndef __SAWHPP_INCLUDED__
#define __SAWHPP_INCLUDED__ 

//=======================
// Dependencies

#include <iostream>
#include <vector>
#include <string>
#include <cmath> // Math Functions Used
#include <ctime> // Random Number Seed
#include <stdexcept>
#include <fstream>

#include <cstdlib>
#include <getopt.h>
#include <gsl/gsl_rng.h> // Random Number Generation


//=======================
// Prototypes

bool handleArgs(int argc, char *argv[]);
double monteCarlo(void);
double trapezoidal(void);
double f(double x);

//=======================
// Objects and Datatypes

typedef unsigned long int ulong;
typedef unsigned int uint;

static struct option long_options[] =
{
 {"montecarlo",     no_argument,             0, 'm'},
 {"trapezoidal",    no_argument,             0, 't'},
 {"all" ,               no_argument,             0, 'a'},
 {"upper",              optional_argument, 0, 'u'},
 {"lower",              optional_argument, 0, 'l'},
 {"subintervals", optional_argument, 0, 'i'},
 {"points",             optional_argument, 0, 'p'},
 {nullptr, 0, 0, 0}
};
//=======================
// Trivial Functions

unsigned long int timeSeed()
{
    std::time_t rawtime; 
    std::tm* currentTime; 
    std::string timeString;

  std::time(&rawtime); // Seconds since 00:00:00 UTC, January 1, 1970
  currentTime = std::gmtime(&rawtime); // Convert to GMT
  std::strftime(&timeString[0],timeString.max_size(),"%Y%m%d%H%M%S",currentTime); // Convert to String

  return std::strtol(timeString.c_str(),nullptr,10); // Convert to int.
}


#endif // Guard Statment

3 个答案:

答案 0 :(得分:5)

double area = stepSize = sum = 0;只是area的声明,并且已经声明stepSizesum。他们不是。 将其更改为

double area, stepSize, sum;
area = stepSize = sum = 0;

另外

currrentSubintervals

currentSubintervals 

是两件不同的事情。对此,我只能说 - WTH兄弟?

答案 1 :(得分:0)

double area = randx = randy = 0;

可以预测,您希望声明三个变量。它没有;它只是声明arearandx = randy = 0作为初始化。你需要三个独立的声明符:

double area=0, randx=0, randy=0;

或三个单独的声明声明。

答案 2 :(得分:0)

double area = randx = randy = 0;

那是什么意思?它说“定义一个类型的变量,名为area,并使用已存在的变量randx的值对其进行初始化,这将是被分配另一个已存在的变量randy的值,该变量将被赋值为0.“

编译器不知道名称为randxrandy的任何现有变量。

我猜你真正想要的是定义三个新变量,所有这些变量都用0初始化。你可以像这样在单行中完成:

double area=0, randx=0, randy=0;

或者只是逐个定义:

double area=0;
double randx = 0;
double randy = 0;

这可能会有点打字但提高了可读性,而且人们通常会阅读程序而不是书面编写程序,因此保存一些关键笔划是不值得的。

更好的方法是在需要时定义变量,而不是更早。

然后有第二个错误:你返回一个area - 但是你只在for循环中定义了那个变量,所以当你调用return时它不存在。

double monteCarlo(void)
{
    const double intervalArea = 2*(upperBound - lowerBound); 
    for (uint currentPoints = (numPoints/100); currentPoints < numPoints; currentPoints += (numPoints/100))
    {   
        gsl_rng* rndGen = gsl_rng_alloc (gsl_rng_mt19937); // Initialize random number generation
        gsl_rng_set(rndGen,timeSeed()); // Seed random number generation

        uint underCurve = 0;
        for (uint point= 1; point <= currentPoints; point++)
        {
            double randx = gsl_rng_uniform(rndGen); 
            double randy = ((2*gsl_rng_uniform_pos(rndGen)) -1);
            if (randy <= f(randx))
            {
                underCurve++;
            }
        }

        double area = (underCurve/currentPoints)*intervalArea;
        output << currentSubintervals << "\t" <<  area << std::endl;
    }

    return /** ??? **/;
}