2012-04-04 85 views
-4

嘿,我試圖編寫一個程序來執行牛頓方法,並找到方程exp(-x) - (x^2)+3的根。它的工作原理是找到根,但我也希望它在每次迭代後都打印出根,但是我無法使它工作,任何人都可以指出我的錯誤,我認爲它與我的索引有關?用指針索引C/C++

太感謝了:)

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

//Define Functions: 
double evalf(double x) 
{ 
     double answer=exp(-x)-(x*x)+3; 
     return(answer); 
} 
double evalfprime(double x) 
{ 
     double answer=-exp(-x)-2*x; 
     return(answer); 
} 
double *newton(double initialrt,double accuracy,double *data) 
{ 
     double root[102]; 
     data=root; 
     int maxit = 0; 
     root[0] = initialrt; 
     for (int i=1;i<102;i++) 
     { 
       *(data+i)=*(data+i-1)-evalf(*(data+i-1))/evalfprime(*(data+i-1)); 
       if(fabs(*(data+i)-*(data+i-1))<accuracy) 
       { 
         maxit=i; 
         break; 
       } 
       maxit=i; 
     } 

     if((maxit+1==102)&&(fabs(*(data+maxit)-*(data+maxit-1))>accuracy)) 
     { 
       printf("\nMax iteration reached, method terminated"); 
     }  
     else 
     { 
       printf("\nMethod successful"); 
       printf("\nNumber of iterations: %d\nRoot Estimate: %lf\n",maxit+1,*(data+maxit)); 
     } 

     return(data); 
} 




int main() 
{ 
    double root,accuracy; 
    double *data=(double*)malloc(sizeof(double)*102); 

    printf("NEWTONS METHOD PROGRAMME:\nEquation: f(x)=exp(-x)-x^2+3=0\nMax No iterations=100\n\nEnter initial root estimate\n>> "); 
    scanf("%lf",&root); 
    _flushall(); 
    printf("\nEnter accuracy required:\n>>"); 
    scanf("%lf",&accuracy); 
    *data= *newton(root,accuracy,data); 
    printf("Iteration  Root   Error\n "); 
    printf("%d   %lf    \n", 0,*(data)); 
    for(int i=1;i<102;i++) 
    { 
     printf("%d    %5.5lf   %5.5lf\n", i,*(data+i),*(data+i)-*(data+i-1)); 
     if(*(data+i*sizeof(double))-*(data+i*sizeof(double)-1)==0) 
     { 
      break; 
     } 
    } 
    getchar(); 
    getchar(); 
    free(data); 
    return(0); 
} 
+2

如何赫克這個問題是有關它的標題?! – valdo 2012-04-04 10:34:29

+0

它以什麼方式不起作用? – JeremyP 2012-04-04 10:39:38

+0

,因爲我確定我的問題是與指數編入我的數組 – Leavenotrace 2012-04-04 10:40:06

回答

1

沒有犯罪,但你的問題是非常養眼downvoting。無關的問題標題,荒謬的編碼風格(我的意思是製表)。

同樣在你的newton函數中,並不需要存儲所有的中間結果,Newton-Raphson不應該使用額外的內存(即它是O(1))。

只需在迭代循環內的newton內添加printf即可。這是一個問題嗎?

+0

對不起,我不是故意做廣告的問題。我只有2個月的編碼,所以我的風格並不好。 – Leavenotrace 2012-04-04 10:49:46

1

newton中,返回函數返回後不再存在的局部變量的地址。之後訪問它是未定義的行爲。

main你有

if(*(data+i*sizeof(double))-*(data+i*sizeof(double)-1)==0) 

datadouble*,所以data + i地址的第i個double從一開始。通過將偏移量乘以sizeof(double),您可以訪問超出數組末尾的數據,如果i > number_of_elements/sizeof(double)還有更多未定義的行爲。

而且,你打電話感謝JeremyP尋找它,在mainnewton

*data= *newton(root,accuracy,data); 

其解引用由newton返回的指針(未定義的行爲,但在這一點上可能會做你想要的)並存儲在main中分配的data的第一個插槽中的值。 Sot可能會給你陣列的初始元素newton,但不會改變main中分配給data的內存塊中的任何其他內容。

+0

+1我認爲你已經覆蓋了最糟糕的錯誤。 – JeremyP 2012-04-04 10:43:31

+0

另外data + i * sizeof(double)應該是data [i],使用add和ptr dereference是data + i * sizeof(double)不必要的複雜度。 – 2012-04-04 10:43:55

+0

只要注意,這行在主'* data = * newton(root,accuracy,data);'這將分配第一個double在任何newton返回數據的第一個元素。 – JeremyP 2012-04-04 10:45:01

0
void newton(double initialrt,double accuracy,double *data) 
{ 
    double root[102]; 
    data=root; 
    // at this moment the values in the original argument data[] 
    // are no longer accessible to this function. 
    int maxit = 0; 
    root[0] = initialrt; 
    for (int i=1; i < 102; i++) 
     { 
       data[i] = data[i-1] 
       - evalf(data[i-1])/evalfprime(data[i-1]); 
       if (fabs(data[i] - data[i-1]) < accuracy) 
       { 
         maxit=i; 
         break; 
       } 
       maxit=i; 
     } 

     if (maxit+1 == 102 && fabs(data[maxit] - data[maxit-1]) > accuracy) 
     { 
       printf("\nMax iteration reached, method terminated"); 
     }  
     else 
     { 
       printf("\nMethod successful"); 
       printf("\nNumber of iterations: %d\nRoot Estimate: %lf\n",maxit+1 
       ,data[maxit); 
     } 
    return; 
} 

(這僅僅是風格評論,因爲真正的問題已經解決)

  • 指針引用和數組索引是C.相當於你​​相當於data[i] = ...
  • 的返回值是無用的,函數可能會返回一些有用的東西(例如精度)
  • return不是函數。沒有必要return(something);只是return something;會做。
  • 您返回一個指向本地數組根的指針,當調用者看到它時超出了範圍。
  • 空白使得閱讀體驗的差異

UPDATE:在第二個想法,我想在內環類似的OP:

root[i] = root[i-1] 
     - evalf(data[i-1])/evalfprime(data[i-1]); 
if (fabs(data[i] - data[i-1]) < accuracy) 
    { 
    maxit=i; 
    break; 
    } 
maxit=i; 
+0

該死的標籤! void void。 – wildplasser 2012-04-04 11:24:21