C数组声明和赋值?

时间:2009-04-13 16:45:20

标签: c arrays variable-assignment

我在结构here上问了一个类似的问题,但是我试图弄清楚C如何处理分配变量的事情,以及如果它们在功能上是相同的,不允许将它们分配给彼此的原因

假设我有两个阵列:

int x[10];  
int y[10];  

为什么x = y不能编译?如果它们都是相同的“签名”,那么你不应该来回分配它们吗?

我可以用允许我在C中执行此操作的方式声明这些吗?你能够做到这一点对我有意义,但也许有办法可以做到这一点?结构的Typedef似乎是解决方案,对于数组声明和赋值是否相同?

感谢你们的帮助,我是Stackoverflow的新手,但到目前为止它对我来说是一个非常好的资源!

7 个答案:

答案 0 :(得分:24)

简单地说,数组不可分配。它们是“不可修改的左值”。这当然引出了一个问题:为什么?有关更多信息,请参阅此问题:

Why does C++ support memberwise assignment of arrays within structs, but not generally?

数组不是指针。 x这里 引用数组,但在很多情况下这会“衰减”(被隐式转换)为指针到它的第一个元素。同样,y也是数组的名称,而不是指针。

你可以在结构中进行数组赋值:

struct data {
    int arr[10];
};

struct data x = {/* blah */};
struct data y;
y = x;

但你无法直接使用数组。使用memcpy

答案 1 :(得分:4)

int x [sz];
int *y = x;

此编译和y将与x相同。

答案 2 :(得分:2)

这里的一些消息说数组的名称产生了第一个元素的地址。并非总是如此:

#include <stdio.h>

int
main(void)
{
  int array[10];

  /*
   * Print the size of the whole array then the size of a pointer to the
   * first element.
   */
  printf("%u %u\n", (unsigned int)sizeof array, (unsigned int)sizeof &array[0]);

  /*
   * You can take the address of array, which gives you a pointer to the whole
   * array. The difference between ``pointer to array'' and ``pointer to the
   * first element of the array'' matters when you're doing pointer arithmetic.
   */
  printf("%p %p\n", (void*)(&array + 1), (void*)(array + 1));

  return 0;
}

输出:

40 4
0xbfbf2ca4 0xbfbf2c80

答案 3 :(得分:1)

为了分配数组,你必须在数组中分配值。

即。 x = y等于

for(int i = 0; i < 10 < ++i)
{
x[i] = y[i];
}

答案 4 :(得分:1)

为了补充Blank的答案,我设计了以下程序:

localhost:~ david$ cat test.c
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char * argv [])
{
  struct data {
    int c [2];
  } x, y;
  x.c[0] = x.c[1] = 0;
  y.c[0] = y.c[1] = 1;
  printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]);
  printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]);
  x = y;
  printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]);
  printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]);

  return 0;
}

执行时,输出以下内容:

x.c 0x7fff5fbff870 0 0
y.c 0x7fff5fbff860 1 1
x.c 0x7fff5fbff870 1 1
y.c 0x7fff5fbff860 1 1

重点是说明结构值的副本是如何发生的。

答案 5 :(得分:0)

当说“int x [10]”说,“为10个整数保留一些空间并向我传递指向该位置的指针”。因此,要使副本有意义,您需要对指向的内存进行操作,而不是“内存位置的名称”。

因此,对于复制,您可以使用for循环或memcpy()。

答案 6 :(得分:0)

我使用的C编译器可以很好地编译......运行时代码会使x指向y的数组。

你会看到,在C中,数组的名称是指向数组开头的指针。实际上,数组和指针基本上是可互换的。您可以使用任何指针并将其索引为数组。

早在70年代早期开发C时,它就意味着相对较小的程序在抽象中几乎不会超过汇编语言。在那种环境中,能够轻松地在数组索引和指针数学之间来回切换是非常方便的。另一方面,复制整个数据阵列是一件非常昂贵的事情,而且很难被用户鼓励或抽象出来。

是的,在这些现代时代,将数组的名称简化为“整个数组”,而不是“对数组前面的一个深度”更为有意义。然而,C并不是在这些现代时期设计的。如果你想要一种语言,试试Ada。 x:= y确实有你所期望的;它将一个数组的内容复制到另一个数组中。