2013-11-20 42 views
-1

我越來越怪異的錯誤有以下功能「不在此範圍內聲明」:非小事「在此範圍內沒有宣佈」錯誤

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 
+0

沒有宣佈正確,兄弟 – JoeC

回答

5

double area = stepSize = sum = 0;僅供area聲明,並承擔stepSizesum已經聲明。他們不是。 將其更改爲

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

而且

currrentSubintervals 

currentSubintervals 

是兩回事。對此,我只能說 - WTH兄弟?

+0

+1。當然,對於'randx'和'randy'來說。 「ranx」似乎也是一個錯字。 – Angew

+0

Lol @ cu rrr entSubintervals – JoeC

0
double area = randx = randy = 0; 

可推測,你期望聲明三個變量。它不;它只是宣佈arearandx = randy = 0作爲初始化程序。您需要三個單獨的宣言:

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

或三個單獨的聲明語句。

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循環中定義了該變量,因此在調用返回時它不存在。

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 /** ??? **/; 
}