您的位置:首页 > 编程语言 > C语言/C++

C++数组名的思考

2015-09-11 11:14 543 查看

C++数组名、指针和编译器

目录

C数组名指针和编译器

目录
第一种思考

第二种思考

目前关于这个思考的解答

为什么关于错误的文章阅读量更高呢

注意不要盲目相信以下内容! 不要盲目相信以下内容! 不要盲目相信以下内容! (重要的事情说三遍),虽然以下内容也经过了我的验证,但是我的验证可能有错误的地方,欢迎大家留言告知。希望这篇文章成为你深入探索相关领域的引子启发,而不是标准答案

第一种思考

数组是十分常用的数据结构,而对经常使用C++的同学来说指针也是逃不开的拦路虎。相信在很多课程或书本上大家都看过说指针在内存中存储的是一个地址,而数组名也是一个地址。

如果按照这种方法理解数组名和指针的话,当我们遇上下面这种情况就不好解释了。

int a[5]={1,2,3,4,5};
int *p=a;
//这时可以使用p++来遍历数组,而不能使用a++来遍历数组,这是为什么呢?


上面这段代码,当我们把a的地址赋给指针p后,我们可以使用指针p来遍历数组,只是需要注意防止 指针在遍历过程中修改了数组值,还有越界时操作了其他内存地址 。

而a如果是一个地址的话,按道理a++会使a跨过一个基类型长度的字节数,指向下一个变量,然而如果你使用a++遍历数组的话,编译器会报错,显示内容是“表达式必须是可修改的左值”,这是什么意思呢?

所以我们不能简单的把数组名当作地址来使用,而一些情况也印证了这一点。当我们把数组作为形参的时候,我们在函数中是可以使用数组名++来遍历这个形式参数的数组的,如下面的例子。

int sum(int a[],int n)
{
a++;
return a
;
//这里没有考虑函数的健壮性和可行性,只是对a++这个特殊情况做思考
}


第二种思考

而通过查阅C11规范,我得到了下面的思考和结论。

c语言规范,说的是“如果数组名不是sizeof、alignof、&的操作数,不是用来初始化char数组的string,这时数组类型转化为指向数组第一个元素的指针”。

数组名做函数形参时,C++编译器把它作为指针来处理

这时这里的数组名是++的操作数,按理说a应该转化为指向数组第一个元素的指针,也就是int*类型(在编译器中我也确认了a是int 类型),这时如果a是int 类型的话为什么不能对a进行++运算呢?

此文章中代码均未考虑健壮性,只是为了某个单一的思考做的验证。下图为验证数组名a的类型的方法。



关于这点我的考虑是a在这里是int const类型的,所以a不能做++运算,然而为什么编译器不显示a是int const类型,而显示a是int *类型呢?

目前关于这个思考的解答

首先分配内存的含义,就是分配一个指针指向分配的内存的首地址。

int a[3]相当于在内存中用a来标识这段长度为3的连续内存,

而当我们进行++操作时,相当于你挪动了这个地址的指针,当然也就等于释放了内存。

所以a++相当于释放数组的内存,编译器会报错。

为什么关于错误的文章阅读量更高呢?

这里有篇关于“野生程序猿”的文章写得很好,可以略窥一二。

野生程序员

之前我也作为一名野生程序猿,遇到错误的时候十分反感,害怕,第一反应就是上网找相关错误有没有人遇到过,是否有完美的解决方案?

当然一般情况下是查不到或者答非所问的,这时候作为“野生程序猿”的我就可能会放弃这个解决方案,寻找另一个完成算法的途径,把问题放过去。

现在稍微长进了一点,变成受过训练的“马戏团程序猿”了,遇到错误提示我会觉得十分感恩,感觉“哎呦,不错呦,我代码里的Bug又可以少了一个,居然还有提示告诉我哪里出了错,真好”。

其实写代码也相当于一次艺术创作,只有认真对待思考,才能获得进步。哎,又灌鸡汤又说多了,就这样吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++