2013-03-24 103 views
1

這是我的代碼和問題。代碼編譯得很好。但是當我運行它。在getMenuOption()中輸入菜單選項後,彈出「Segmentation Fault(核心轉儲)」。哪裏不對? 我是一般的編程新手。感謝您提供的幫助。沒有指針的分段錯誤?

#include <stdio.h> 
#include<math.h> 

#define CALCULATE_PI 'a' 
#define CALCULATE_GEOMEAN 'b' 
#define CALCULATE_HARMMEAN 'c' 

void printInstructions (void); 
void printMenuOptions (void); 
int runMenuOption(); 
int getMenuOption(); 
int getLimit(); 
int calculatePi(); 
int calculateGeoMean(); 
int calculateHarmonicMean(); 

int main(void) 
{ 
    printInstructions(); 

    printMenuOptions(); 

    runMenuOption(getMenuOption()); 

    return 0; 

} 

void printInstructions (void) 
{ 
    printf("======================================================\n"); 
    printf("= PI, Geometric Mean, and Harmonic Mean Calculator =\n"); 
    printf("= Please refer to the menu to choose calucaltion =\n"); 
    printf("=Choose desired menu option and press enter to begin =\n"); 
    printf("=  Proceed to follow on-screen instructions  =\n"); 
    printf("======================================================\n\n\n"); 

    return; 
} 

void printMenuOptions (void) 
{ 
    printf("3 choices: Please enter a VALID letter.\n"); 
    printf("Choice 'a' = Calcualtes PI\n"); 
    printf("Choice 'b' = Calculates Geometric Mean\n"); 
    printf("Choice 'c' = Calculates Harmonic Mean\n\n"); 

    return; 
} 

int runMenuOption (int getMenuOption()) 
{ 
    char option; 
    double answer, 
      Pi = 0.0, 
      geoMean = 0.0; 

    option = getMenuOption(); 

    switch (option) 
    { 
     case CALCULATE_PI: 
      calculatePi(getLimit()); 
      answer = Pi; 
      break; 
     case CALCULATE_GEOMEAN: 
      calculateGeoMean(getLimit()); 
      answer = geoMean; 
     case CALCULATE_HARMMEAN: 
      printf("Harmonic Mean"); 
      break; 
     default: 
      printf("Incorrect Character!\n"); 
      printf("Try again"); 
      break; 
    } 

    printf("Your answer is %5p", &answer); 

    return 0; 
} 

int getMenuOption (void) 
{ 
    char option; 

    printf("Please enter choice: "); 

    scanf("%c", &option); 

    return option; 
} 

int getLimit() 
{ 
    int limit; 

    scanf("%d", &limit); 

    return limit; 
} 

int calculatePi (void) 
{ 
    int limit, 
    count = 0, 
    Pi = 0; 

    printf("Please enter the PI limit: "); 

    limit = getLimit(); 

    for (count = 1; count <= limit; count++) 
    { 
     Pi += 1/count; 
    } 

    return sqrt(Pi * 6); 
} 

int calculateGeoMean() 
{ 
    int limit, 
     userValue = 0, 
     count = 0; 
    double geoMean = 0; 

    limit = getLimit(); 

    while(count <= limit) 
    { 
     if (userValue <= 0) 
      printf("Incorrect. Try again"); 
     else 
     { 
      count++; 
      userValue *= userValue; 
     } 

    } 
    geoMean = userValue; 

    return sqrt(userValue); 
} 

int calculateHarmonicMean() 
{ 
    int limit, 
     userValue = 0, 
     count = 0; 
    double harmMean = 0; 

    limit = getLimit(); 

    while(count <= limit) 
    { 
     if (userValue <= 0) 
      printf("Incorrect. Try again"); 
     else 
     { 
      count++; 
      userValue *= 1/userValue; 
     } 

    } 
    harmMean = userValue; 

    return limit/userValue; 
} 

回答

6

這個函數定義是完全錯誤的。

int runMenuOption (int getMenuOption()) 

要麼你可以傳遞的getMenuOption返回值這樣

int runMenuOption (int option) 

你不應該任意值傳遞給該函數並調用getMenuOptionrunMenuOption。你正在做這兩個,這是不正確的。

+0

@ComInfoSystems - 你的問題解決嗎? – neham 2013-03-24 02:25:43

2
int runMenuOption (int getMenuOption()) 

這是你的問題。

這應該是:

int runMenuOption (int opt) 

而且,你不應該叫內runMenuOptiongetMenuOption()因爲你打電話getMenuOption(),你把它傳遞給runMenuOption作爲參數。 runMenuOption應該只有一個switch聲明。

0

您需要修改功能的定義,從int runMenuOption (int getMenuOption())int runMenuOption (int option)。在調用中,將調用getMenuOption()並將輸出放入被調用函數的stack frame中。

0

根據您的runMenuOption函數的聲明,它需要一個指向它返回一個整數作爲其第一個參數的函數:

int runMenuOption (int getMenuOption()) 

然後調用該函數在這一行:

option = getMenuOption(); 

這很好。然而,問題就出在這行:

runMenuOption(getMenuOption()); 

在這裏,您呼叫的getMenuOption函數並傳遞返回值到runMenuOption功能。但是,你應該做的是傳遞函數本身作爲參數:

runMenuOption(getMenuOption); 

你得到一個分段錯誤的原因是因爲從getMenuOption函數的返回值被視爲一個函數指針,你的程序正試圖在該地址調用一個函數,這當然是無效的。

+0

@Armin:我剛剛測試了我的解決方案,它在GCC v4.5.3上正常工作。在做:runMenuOption(&getMenuOption)也將工作,但絕對不會運行MenuOption(getMenuOption())。你能否詳細說明爲什麼你認爲這是錯誤的?編輯:另請注意,通過:「runMenuOption(getMenuOption());」我指的是他在main函數中調用runMenuOption的行,而不是runMenuOption函數原型。 – Isuru 2013-03-24 02:13:20

+0

我腦子裏有不同的東西,你的建議雖然不尋常,但它的作用。除非你編輯,否則我不能再取消選舉。 – 2013-03-24 02:17:35

+0

我只是想通知作者分段錯誤的確切原因。該解決方案還具有對作者的原始程序進行微小更改的優點。 – Isuru 2013-03-24 02:21:41