LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2949|回复: 17

关于在C/C++中数组不能直接赋值的问题

[复制链接]
发表于 2006-5-18 13:49:07 | 显示全部楼层 |阅读模式
大家都知道在C/C++中数组是不能直接赋值的,要赋值必须一个一个的赋值。现在我想知道C/C++的实现者为什么要这么做?按理说数组也是一个内置的数据类型,能够直接赋值是顺利成章的事情,为什么要搞得不能赋值,而且还有数组名代表的是数组的地址为什么不能象结构(struct)的变量名一样代表的是它的内存块的内容呢?
    还有我一直认为数组的定义int a[10]很别扭,没有int[20] a那么直观。定义一般就是
       类型  变量名;
这点在java中就做得很好。

    上面的所有问题我现在很糊涂,希望知道的兄弟姐妹帮帮我!不知道当初的c/c++的设计者和标准的制定者是出于什么方面的考虑才把它们设计成这个样子???
发表于 2006-5-18 14:11:21 | 显示全部楼层
在C/C++中,普通数组只是分配在连续地址上的一段相同类型的变量组成的,而不是一个变量。像a[n]并不是一个变量,而是通过指向第一个值的指针来操作的。数组和指针有着很密切的联系。可以认为数组操作是指针操作的另一种写法。因此像数组整体赋值这类操作是没有意义的,因为它们不是一个整体。

至于声明语法,这是一个很复杂的历史过程了,可以看看C Design Rationale之类的东西。
回复 支持 反对

使用道具 举报

发表于 2006-5-18 16:42:49 | 显示全部楼层
想实现这个也很容易,把数组放在结构里不就行了?
回复 支持 反对

使用道具 举报

发表于 2006-5-18 19:48:12 | 显示全部楼层
Post by cxh_nuaa_2001
大家都知道在C/C++中数组是不能直接赋值的,要赋值必须一个一个的赋值。现在我想知道C/C++的实现者为什么要这么做?按理说数组也是一个内置的数据类型,能够直接赋值是顺利成章的事情,为什么要搞得不能赋值,而且还有数组名代表的是数组的地址为什么不能象结构(struct)的变量名一样代表的是它的内存块的内容呢?
这样的设计应该自有它的道理。
假定把数组设计成struct一样,即使可以直接赋值,但同时也带来副作用,比如:
  1. int * ptr_arr1[10];
  2. // 假定上面数组里头存放的 int * 指针是动态的
  3. int * ptr_arr2[10];
  4. ptr_arr2=ptr_arr1; // 假定数组可以赋值。现在两个数组有同样的内容了。
复制代码
一个问题是,这个赋值到底是浅拷贝还是深拷贝? 显然两者都有副作用,搞的象 struct/class 的赋值/拷贝一样,数组的灵活性大大降低。显然,这个语义层面的东西应该交给程序员来处理,而不是由语言本身来内部规定。
回复 支持 反对

使用道具 举报

发表于 2006-5-18 20:06:20 | 显示全部楼层
像下面这样的两个变量用楼主建议的方法如何声明呢?

  1. int *(a[10]);
  2. int (*b)[10];
复制代码


C 中把对内存的直接访问更直接地摆在了程序员面前, 这是其它很多高级语言所不能比拟的.
如果楼主关心程序的效率, 那么就应该能够体会指针, 或者说内存的直接访问, 是一种多么伟大的东东. 如果楼主不喜欢这样, 完全可以不用 C, 用别的语言并没有什么不好.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-18 20:23:11 | 显示全部楼层
Post by manphiz
在C/C++中,普通数组只是分配在连续地址上的一段相同类型的变量组成的,而不是一个变量。像a[n]并不是一个变量,而是通过指向第一个值的指针来操作的。数组和指针有着很密切的联系。可以认为数组操作是指针操作的另一种写法。因此像数组整体赋值这类操作是没有意义的,因为它们不是一个整体。

至于声明语法,这是一个很复杂的历史过程了,可以看看C Design Rationale之类的东西。



如果象你所说的一样,那么在C中的sizeof()应该怎么理解,还有int (*p)[4];  p++步进的不是一个int单位,而是4个,应该怎么理解?谢谢!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-18 20:26:13 | 显示全部楼层
Post by muxingren
想实现这个也很容易,把数组放在结构里不就行了?



我现在问的不是这个问题,实际上你的这种做法我也知道。我想知道的是为什么C/C++的设计者要这么安排,是出于什么方面的考虑的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-18 20:53:00 | 显示全部楼层
Post by Lolita
这样的设计应该自有它的道理。
假定把数组设计成struct一样,即使可以直接赋值,但同时也带来副作用,比如:

  1. int * ptr_arr1[10];
  2. // 假定上面数组里头存放的 int * 指针是动态的
  3. int * ptr_arr2[10];
  4. ptr_arr2=ptr_arr1; // 假定数组可以赋值
复制代码

一个问题是,这个赋值到底是浅拷贝还是深拷贝? 显然两者都有副作用,搞的象 struct/class 的赋值/拷贝一样,数组的灵活性大大降低。显然,这个语义层面的东西应该交给程序员来处理,而不是由语言本身来内部规定。



我想我的意思你误会了,或者是我看不懂你的这段话,能不能请你说的清楚一点。浅拷贝和深拷贝跟直接赋值有什么直接的关系呢?我的意思是数组可以直接赋值的同时还可以象a=b;
*(p+i)=x;//p指向一个一维数组;那样赋值。哦,我想可能是考虑到下标运算的方便,就向2楼的那么兄弟说的那样,数组不是被看成一个整体,而是一系列的元素单元组成的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-18 20:59:22 | 显示全部楼层
Post by DoDo
像下面这样的两个变量用楼主建议的方法如何声明呢?

  1. int *(a[10]);
  2. int (*b)[10];
复制代码


C 中把对内存的直接访问更直接地摆在了程序员面前, 这是其它很多高级语言所不能比拟的.
如果楼主关心程序的效率, 那么就应该能够体会指针, 或者说内存的直接访问, 是一种多么伟大的东东. 如果楼主不喜欢这样, 完全可以不用 C, 用别的语言并没有什么不好.


如果按照我的设想,
int *(a[10]);  可以声明为  int*[10] a;
int (*b)[10];  可以声明为  int[10] *b;


如果你要强调效率,那么可以用指向数组(int (*a)[10];)的指针操作啊,直接赋值没有说不允许不使用指针啊。
回复 支持 反对

使用道具 举报

发表于 2006-5-19 00:01:46 | 显示全部楼层
Post by cxh_nuaa_2001
如果象你所说的一样,那么在C中的sizeof()应该怎么理解,还有int (*p)[4];  p++步进的不是一个int单位,而是4个,应该怎么理解?谢谢!!!

我所说的是C/C++语言的处理方式。对于

int p[10]

来说,p的类型是

int [10]

是个数组。对于

int* q = new int[10];

来说,q是个指向数组首地址的指针。两者类型不同,但操作方式相同,因为两者底层处理方式是一样的。

另一方面,你能new一个指向数组的指针吗?不能。因为数组本身并不是一个完整的类型。因此需要像上个例子那样做。而且在delete的时候需要指出你是在delete一个变量还是数组:

delete[] q;

数组归根结底是用来操作一组连续空间内相同类型变量的方式。如果需要数组赋值,可以使用C++中的容器来代替数组。当然这是类,而不再是简单的数组了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表