【问题标题】:Global variable in C changes in spite of not making any changes to it尽管没有对其进行任何更改,但 C 中的全局变量会发生变化
【发布时间】:2015-06-06 17:59:36
【问题描述】:

请在下面查看我的代码。我很困惑为什么我的全局变量“magicnunmber”的值在第一次“迭代”之后会发生变化,尽管我没有在代码中的任何地方更改它的值。

#include <stdio.h>

float m[4][4] = { {0,0.5,1,0},{0.33,0,0,0.5},{0.33,0,0,0.5},{0.33,0.5,0,0} };
float v[4][1] = {{0.25},{0.25},{0.25},{0.25}};
float vdash[4][1];
int i =0, j=0;
int r1,c1,r2,c2,k;
float magicnumber = 0.01;
int iteration = 0;

int main(void)
{
 r1 = c1 = r2 = 4;
 c2 = 1;

 //while(1)
 while(iteration < 5)
 {
  printf("magicnumber==[%f]\n",magicnumber);
  //magicnumber = 0.01;
  iteration++;
  printf("\n---------------------------------------------------------------------------------------------------------------------\n");

  for(i=0;i<r1;i++)
  { 
   for(j=0;j<c2;j++)
   {
    vdash[i][j] = 0;
    for(k=0;k<c1;k++)
    {
     vdash[i][j] = vdash[i][j] + (m[i][k] * v[k][j]);
    }
   }
  }

  if(myfun(vdash,v)==0)
  {
   break;
  }
  else
  {
   printf("\n");
   for(i=0;i<r1;i++)
   {
    v[i][1] = vdash[i][1];
   }
  }
 }

 return 0;
}

int myfun(float* vdash, float* v)
{ 
 float delta = 0;

 for(i=0;i<r1;i++)
 {
  delta = (*(vdash+i) - *(v+i));
  (delta < 0)?(delta = delta*-1):delta;

  if( delta > magicnumber)
  {
   return 1;
  }
 }
 return 0;
}

我的输出

magicnumber==[0.010000]

---------------------------------------------------------------------------------------------------------------------

magicnumber==[0.000000]

---------------------------------------------------------------------------------------------------------------------

magicnumber==[0.000000]

---------------------------------------------------------------------------------------------------------------------

magicnumber==[0.000000]

---------------------------------------------------------------------------------------------------------------------

magicnumber==[0.000000]

---------------------------------------------------------------------------------------------------------------------

我已经在gdb上试过了,但是我只能看到进入新的迭代时这个值变成了一个很小的数字。

1: magicnumber = 0.00999999978
1: magicnumber = 0.00999999978
1: magicnumber = 5.60519386e-45

如果我从不给它分配任何东西,magicnumber 怎么会改变?

【问题讨论】:

  • 当转换为float* 并传递给函数myfun 时,编译器不知道数组vdash 和数组v 的维度。由于这些数组是全局的,因此您最好不要将它们传递给函数。也就是说,您应该尽可能避免使用全局变量(在您给定的代码中几乎是everywhere)。顺便说一句,我希望编译器会在包含myfun(vdash,v) 的行上警告您有关尺寸问题。不是吗???
  • 因为你在 myfun() 中破坏了你的内存,由于函数参数不匹配,这不应该在没有警告/错误的情况下编译。

标签: c pointers floating-point stack global-variables


【解决方案1】:

实际发生的错误在v[i][1] = vdash[i][1]; 行中。在这里,您的数组由 1 列组成,并且您指的是数组的第二列,因此您正在写入超出数组的内容,这会导致未定义的行为,从而导致此问题。

所以将v[i][1] = vdash[i][1];这一行改为v[i][0] = vdash[i][0];

您的代码也写得非常糟糕。如果您想使用一维数组,那么当您可以使用arr[length] 时,为什么要像arr[length][1] 一样定义它。这可以防止你犯下你刚刚犯下的错误。你的 myfun 功能也很糟糕。看看下面的代码。

#include <stdio.h>
//Try not to use global variable. Global variables are bad :D.
int main(void)
{
 float m[4][4] = { {0,0.5,1,0},{0.33,0,0,0.5},{0.33,0,0,0.5},{0.33,0.5,0,0} };
 float v[4] = {0.25,0.25,0.25,0.25};
 float vdash[4];
 int i =0, j=0;
 int r1,c1,r2,c2,k;
 float magicnumber = 0.01;
 int iteration = 0;
 r1 = c1 = r2 = 4;
 c2 = 1;

 //while(1)
 while(iteration < 5)
 {
  printf("magicnumber==[%f]\n",magicnumber);
  //magicnumber = 0.01;
  iteration++;
  printf("\n---------------------------------------------------------------------------------------------------------------------\n");

  for(i=0;i<r1;i++)
  { 
//   for(j=0;j<c2;j++) --since you are only going through j once. also it is not required in this code
//   {
    vdash[i] = 0;
    for(k=0;k<c1;k++)
    {
     vdash[i] = vdash[i] + (m[i][k] * v[k]);
    }
//   }
  }

  if(myfun(vdash,v,magicnumber,r1)==0)
  {
   break;
  }
  else
  {
   printf("\n");
   for(i=0;i<r1;i++)
   {
    v[i] = vdash[i];
   }
  }
 }

 return 0;
}

int myfun(float vdash[], float v[], int magicnumber, int r1)
{ 
 float delta = 0;
 int i;
 for(i=0;i<r1;i++)
 {
  delta = (vdash[i] - v[i]);
  (delta < 0)?(delta = delta*-1):delta;

  if( delta > magicnumber)
  {
   return 1;
  }
 }
 return 0;
}

【讨论】:

  • 问题是超出数组末尾的写入会导致未定义的行为。将其注入程序后,没有任何值得到保证。您的程序可能会继续运行、运行时使用损坏的值或段错误。结果只是未定义
猜你喜欢
  • 2012-09-28
  • 1970-01-01
  • 2012-03-02
  • 2021-02-05
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
相关资源
最近更新 更多