Struct有两个字段,每个字段都是一个1d数组。将struct对象传递给没有指针的函数会改变struct对象吗?

时间:2015-02-11 15:53:50

标签: c arrays pointers struct

这是我昨天的测试中的一个问题 考虑这段代码:

#include <stdio.h>
#define ARR_SIZE 5

typedef struct _A {
   int _arr1[ARR_SIZE];
   int* _arr2; } A;

void foo(A a) {
   int i;
   for (i=0;i< ARR_SIZE;++i)
      a._arr1[i] = 5*i;
}

void bar(A a) {
   int i;
   for (i=0;i< ARR_SIZE;++i)
   a._arr2[i] = 10*i;
}

void printA(A* a,char* str)
{
   int i;
   printf("%s:\n_arr1:\t",str);
   for (i=0;i< ARR_SIZE;++i)
       printf("%d\t",a->_arr1[i]);
       printf("\n_arr2:\t");
   for (i=0;i< ARR_SIZE;++i)
       printf("%d\t",a->_arr2[i]);
       printf("\n");
}

int main() {
    A a1 = {{1,2,3,4,5},0};
    A a2 = a1;
    a1._arr2 = a1._arr1;
    a2._arr2 = a2._arr1;
    foo(a1);
    bar(a2);
    printA(&a1,"a1");
    printA(&a2,"a2");
    return 0;
}

现在,打印出来: a1:
_arr1: 1 2 3 4 5
_arr2: 1 2 3 4 5
a2:
_arr1: 0 10 20 30 40
_arr2: 0 10 20 30 40

我不懂印刷品。如果我逐步配置代码,我发现将a1传递给foo将不会产生任何结果,因为我没有发送指针到a1。但我不明白的是,如果我在没有指针的情况下将a2发送到bar,则会更改a2。 我想过是因为_arr2是一个指针,因此bar会更改它,所以a2会发生变化。但是,我们知道每个数组都是指向第一个元素的指针。所以_arr1是一个数组,所以它是一个指针,但不会改变!

有人能解释我为什么会这样吗? tnx提前很多!

2 个答案:

答案 0 :(得分:2)

原始bar中显示struct所做更改的原因是因为_arr2副本中的struct仍指向_arr1您已通过的原始struct。基本上,你传递一个指针,除了它现在隐藏在通过值传递的struct中。

Illustration

这是一种了解正在发生的事情的方法:

void bar(A a) {
    printf("%p %p", (void*)a._arr2, (void*)&a._arr1);
    for (int i=0;i< ARR_SIZE;++i) {
       a._arr2[i] = 10*i;
    }
}

这将打印存储在_arr2struct中的_arr1的不同指针。

答案 1 :(得分:1)

struct A里面有一个数组和一个指针。

typedef struct _A {
   int _arr1[ARR_SIZE];     // _arr1 is an array
   int* _arr2; } A;         // _arr2 is a pointer

如果您传递指针的副本,则副本仍指向同一位置。

更改复制指向要在调用函数中反映的内容。

您可能希望了解数组和指针之间的差异 我建议c-faq的第6部分。