指针——C语言的灵魂 为什么说C指针是C语言的灵魂? 买前必读: 迷你书下载 精彩片段: 恶名昭著的指针究竟是什么:报错
int *p; p[3] = …… ←突然使用没有指向内存区域的指针 ——自动变量的指针在初期状态,值是不定的。 char str[10]; . . . str = “abc”; ←突然向数组赋值
——数组既不是标量,也不是结构体,不能临时使用。 int p[]; ←使用空的[]声明本地变量 ——只有在“函数的形参的声明”中,数组的声明才可以被解读成指针。 对于数组和指针,它们在哪些地方是相似的,又在哪些地方是不同的?不好意思,可能在下面会出现和前面重复的内容。 表达式之中 在表达式中,数组可以被解读成指向其初始元素的指针。所以,可以写成下面这样:
int array[10]; p = array; ←将指向array[0]的指针赋予p
可是,反过来写成下面这样,
array = p;
就是不可以的。确实,在表达式中array 可以被解读成指针,可是,本质上它其实是被解释成了&array[0],此时的指针是一个右值*。(此时的指针是右值这个理由之外,在标准中,数组也不是“可变更的左值”。) 比如,对于int类型的变量a,a = 10;这样的赋值是可以的,但肯定没有人想做a + 1 = 10;这样的赋值吧。尽管a 和a + 1 都是int,但是a + 1没有对应的内存区域,只是一个右值,所以不能被赋值。同样的道理,array也不能被赋值。此外,对于下面这个指针,
int *p;
如果p指向了某个数组,自然可以通过p[i]的方式进行访问,但这并不代表p就是指针。 p[i]只不过是*(p + i)的语法糖,只要p正确地指向一个数组,就可以通过p[i]对数组的内容进行访问,如图3-18所示。
如果是“指针的数组”和“数组的数组”,就会有很大的不同。
char *color_name[] = { ←指针的数组 “red”, “green”, “blue”, };
对以上的代码进行图解(参照图3-19),
![enter image description here][5] char color_name[][6] = { “red”, “green”, “blue”, }
对以上的代码进行图解(参照图3-20),
以上两种情况都可以用color_name[i][j]的方式对数组进行访问,但是内存中数据的布局是完全不同的。 声明 只有在声明函数的形参的时候,数组的声明才能解读成指针的声明(参照3.5.1节)。 以上的语法糖,与其说使C变得更加容易理解,倒不如说它使C语言的语法变得更加混乱。是不是有很多人这么想?我就是其中的一个(虽然使用这个语法糖可以让多维数组作为参数被传递时更容易理解……)。而且K&R的说明更是使这种混乱局面雪上加霜。 在不是声明函数的形参的时候,数组声明和指针的声明是不可能相等的。 使用extern 的时候是最容易出现问题的(参照3.5.2节)。另外,声明局部变量或者结构体的成员时,写成
int hoge[];
会引起语法错误(对于结构体的成员,在ISO C99 中是允许这种写法的)。 存在数组初始化表达式的情况下,可以使用空的[],但这是因为编译器能够计算出数组元素的个数,所以可以省略书写元素个数。仅此而已,这种特征和数组扯不上任何关系。
要 点 【非常重要!!】 •数组和指针是不同的事物。
以下文字摘自《C陷阱与缺陷》,写的非常好,很有必要摘录下来和大家一同分享。
C语言中的数组值得注意的地方有以下两点:
1.C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常熟确定下来。然而,C语言中数组的元素可以是任何类型的对象,当然也可以是另外一个数组。这样,要“仿真”出一个多维数组就不是一件难事。
2.对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其他有关数组的操作,哪怕它们乍看上去是以数组下标 进行运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算,因此我们完全可以依据指针行为定义数组下标的行为。 ######可不可以理解这是广告###### 难掌握的是计算机体系
搞不懂指针的都是体系没学好的 ######国内好多数组和指针搞不清楚的教材害人呀。######明显广告######受益匪浅,对指针的看法有了更具体的认识,没那么抽象了。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。