c程序的意外行为?

时间:2017-07-30 13:38:08

标签: c arrays function pointers undefined-behavior

此代码未按预期提供输出,显然我无法理解程序行为.Plz帮助我理解这一点。任何帮助将不胜感激。 您可以在此处查看程序https://code.hackerearth.com/31d954z?key=fce7bc8e07fc10a3d7a693e45a5af94a的输出。

  

1.在最后一条评论中,我找不到为什么数组的元素没有更新。

     

2.在打印'a'的函数体中,它会产生一些意想不到的输出。

     

例如,如果我通过j = 2和a [0] = 1

       After j = j+1 , which results in j = 3;

       a=a+j should result in a = 4

       but instead it result in a = 13.
#include <stdio.h>

void func(int j,int *a)
{
 j=j+1;
 printf("%d\t%d\n",a,j);     //prints j updated value and a
 a=a+j;
 printf("a = %d\n ",a);      //prints value of a
}


void main()
{
 int a[5] ={1,2,3,4,5},i,j=2;
 for (i =0;i<5;i++ )
 func(j, a[i]);
 for (i =0;i<5;i++ )   
 printf("%d\t",a[i]);    //Prints the array as 1 2 3 4 5
}

运行此代码时,输​​出为:

  

1 3 // Here a = 1 and j = 3 a = 13 //but after addition a = 13 2 3 a = 14 3 3 a = 15 4 3 a = 16 5 3 a = 17 1 2 3 4 5 //array elements not updated

2 个答案:

答案 0 :(得分:3)

  

我想了解代码行为。

您的代码会生成未定义的行为,因此您应该停止正在执行的操作并 debug

如果你想索引数组,你可以这样做:

a[i]

其中i是索引,a是您的数组。因此,如果要访问第一个元素,则需要执行a[0],当您要为第3个元素编制索引时,执行a[2]等等。

但是,您可能想要做的就是传递第i个元素,添加并打印它。

因此,您应该启用编译器警告:

prog.c: In function 'func':
prog.c:6:11: warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat=]
  printf("%d\t%d\n",a,j);     //prints j updated value and a
          ~^
          %ls
prog.c:8:15: warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat=]
  printf("a = %d\n ",a);      //prints value of a
              ~^
              %ls
prog.c: At top level:
prog.c:12:6: warning: return type of 'main' is not 'int' [-Wmain]
 void main()
      ^~~~
prog.c: In function 'main':
prog.c:16:10: warning: passing argument 2 of 'func' makes pointer from integer without a cast [-Wint-conversion]
  func(j, a[i]);
          ^
prog.c:3:6: note: expected 'int *' but argument is of type 'int'
 void func(int j,int *a)
      ^~~~

然后相应地修改您的代码,例如:

#include <stdio.h>

void func(int j,int a)
{
 j=j+1;
 printf("%d\t%d\n",a,j);   
 a=a+j;
 printf("a = %d\n ",a);
}


int main(void)
{
 int a[5] ={1,2,3,4,5},i,j=2;
 for (i =0;i<5;i++ )
 func(j, a[i]);
 for (i =0;i<5;i++ )   
 printf("%d\t",a[i]);
}

输出:

1   3
a = 4
 2  3
a = 5
 3  3
a = 6
 4  3
a = 7
 5  3
a = 8
 1  2   3   4   5

答案 1 :(得分:0)

那是因为你为需要指针的函数赋予了价值。

void func(int j,int *a) // a is a pointer

这就是你传递的内容:

func(j, a[i]); // a[i] is a value

您应该传递要更改的值的地址。这样,如果在func上更改了值,则main也将具有更改的值。如果你传递值,func将在堆栈上更改该值(因为函数参数转到堆栈),而main将具有旧的未更改的值。要传递对要更改的值的引用,请使用以下命令:

func(j, a + i); //a is address to start of array

当然,在函数中,你应该增加值,而不是地址:

*a += j; // Instead of a = a + j where 'a' is pointer according your function