2012-04-04 12 views
-4

ちょっと私はnewtonsメソッドを実行し、式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

+0

どのように動作しませんか? – JeremyP

+0

私の問題はポインタで配列にインデックスを付けることに関連している – Leavenotrace

答えて

1

ない犯罪が、あなたの質問はdownvotingに非常に魅惑的です。無関係な質問タイトル、ばかげたコーディングスタイル(私は表を意味する)。

また、newton関数の中には、実際に中間結果をすべて格納する必要はありません.Newton-Raphsonは余分なメモリ(O(1))を使用すべきではありません。

printfを反復ループ内のnewtonに追加するだけです。これは問題ですか?

+0

申し訳ありませんが、私はその質問を偽って宣伝しているわけではありません。私は2ヶ月間だけコーディングしているので、私のスタイルはあまり良くありません。 – Leavenotrace

1

newtonには、関数が返された後でもう存在しないローカル変数のアドレスが返されます。後でそれにアクセスすることは、未定義の動作です。あなたは

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

dataを持ってmain

double*なので、最初からdata + iアドレスi番目のdouble。配列にsizeof(double)を掛けると、配列の末尾を越えてアクセスします。i > number_of_elements/sizeof(double)の場合、未定義の動作です。

そして、それを見つけるためのJeremyPのおかげで、mainにあなたはnewton

newtonによって返されたポインタ参照解除
*data= *newton(root,accuracy,data); 

(未定義の動作を、しかし、あなたがやりたいと思わその時点で)呼び出して保存すること値に割り当てられたdataの最初のスロットの値。それはおそらくnewtonroot配列の最初の要素を返しますが、に割り当てられたメモリブロックの他の部分はmainに変更されません。

+0

+1私はあなたが最悪のエラーをカバーしたと思います。 – JeremyP

+0

また、data + i * sizeof(double)はdata [i]でなければなりません。addとptrの逆参照はdata + i * sizeof(double)の不要な合併症です。 –

+0

この行はメインの '* data = * newton(root、accuracy、data);'であり、newtonがデータの最初の要素に返すものであれば最初のdoubleを代入します。 – JeremyP

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(something);ちょうどreturn something;が行います。
  • ローカルアレイルートへのポインタを返します。これは、呼び出し側が参照すると範囲外です。考え直し上で、私は内側のループのような何かを意図OPで考える:
  • 空白が

がUPDATE読書体験で違いが一体この質問はに関連してどのように

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

関連する問題