Код C не работает, когда переменная int обновляется внутри цикла

#c #loops #variables

#c #циклы #переменные

Вопрос:

Я новичок в программировании на C и давно ничего не делал. Я пытаюсь выполнить простое численное интегрирование функции. Вот упрощенная версия моего кода:

 int main()
{

/*Constants----*/
double e0=8.85E-12;          //C^2/Nm^2
double e_charge=1.6E-19;     //C
double e_mass=1E-31;         //kg
double N=1E22;               //m^-3
double w0=1E10;              //rad/seg
double gam=5;
double f=(N*pow(e_charge,2))/(e_mass*e0);
/*--------------*/

double delta=50;
double step=0.1;
int array_size=2*delta/step;
double Re_X[array_size];
double Im_X[array_size];
double Re_X_KK[array_size];
double Im_X_KK[array_size];
double i,k;
int j,z;


for(i=w0-delta ; i<=w0 delta ; i=i step ){
    Re_X[j]=f*(pow(w0,2)-pow(i,2))/(pow(pow(w0,2)-pow(i,2),2) 4*pow(i,2)*pow(gam,2));
    Im_X[j]=f*(2*i*gam)/(pow(pow(w0,2)-pow(i,2),2) 4*pow(i,2)*pow(gam,2)); 
    j  ;
}

/*This is just a test*/
z=0;
for(j=0 ; j<=10 ; j  ){
z  ;
printf("%dn",z);
}

return(0);
}
  

Когда я запускаю этот код, ничего не работает, z не печатается внутри цикла, и первый цикл также не выполняется (я печатаю результаты в .txt и ничего не получаю).

Если я прокомментирую второй цикл, первый будет работать просто отлично. Если я прокомментирую первый цикл, второй выполняется нормально. Если я не добавляю единицу к z на каждой итерации, все работает.

Я действительно не понимаю, что происходит, это происходит только с целочисленными переменными. Если я изменю z на double, все будет в порядке (но мне нужно, чтобы это было int).

Любая помощь действительно ценится. Спасибо!

Комментарии:

1. вероятно, вам не следует смешивать математику с плавающей запятой и целочисленную математику. Отладьте каждую строку и выведите значения всех переменных, чтобы увидеть, что происходит

2. Определите все double массивы как глобальные переменные или лучше используйте malloc() как double Re_X = malloc( array_size * sizeof (double) );

3. Не имеет отношения к вашей проблеме, но я предлагаю вам квалифицировать все переменные, значения которых вы не будете изменять, как const .

4. вы никогда не инициализируете j . Это случайный мусор, и его использование в качестве индекса массива приводит к неопределенному поведению

5. Спасибо вам всем! Также учтет ваши предложения.

Ответ №1:

Используйте отладчик:

 Program received signal SIGSEGV, Segmentation fault.
0x0000555555555808 in main () at demo.c:29
29      Im_X[j]=f*(2*i*gam)/(pow(pow(w0,2)-pow(i,2),2) 4*pow(i,2)*pow(gam,2)); 
(gdb) 
  

Вы используете неинициализированную переменную ( j ) в Re_X[j] = ...; и Im_X[j] = ...;

Комментарии:

1. Это было оно! Спасибо!

Ответ №2:

Эта программа имеет неопределенное поведение, поскольку j используется неинициализированная как нижний индекс для записи в Re_X и Im_X , что затем повреждает память в стеке. Это объясняет ваши наблюдения о том, как программа произвольно работает или не работает, когда части кода прокомментированы. Комментируемый код не связан, но случайно повреждение памяти воспроизводится по-разному между различными запусками программы.

Полезным инструментом для устранения неполадок такого рода является AddressSanitizer, который включается в clang или gcc путем компиляции с помощью -fsanitize=address , или, если вы используете Xcode, для этого есть опция. Другим отличным инструментом является valgrind.