`有必要学一学思维导图了,思维真的有些僵化`,自建的记忆思维导图:
数组和指针记忆导图.jpg
数组与指针:
· 数组变量可以被用着指针
· 数组变量指向数组中第一个元素
· 如果函数参数
声明为数组
,他会被当做指针
处理
·sizeof
不是一个函数,而是运算符
,编译器回把运算符编译为一串指令,所以程序实在编译期间计算出存储空间的大小的;而程序调用函数时,会调到另一段独立的代码中执行。
数组与指针又是完全不同的
char s[] = "How big is it";
char *t = s;
-
1 ==sizeof==(
数组
)是数组的大小而==sizeof==(指针
)返回是4或8。 -
2 数组的地址··· ···是数组的地址。
指针变量是一个用来存储存储器地址的变量,如果堆数组变量使用&运算符,结果是数组本身。
&s == s
&t != t
当程序员写下
&s
时, 表示“数组s的地址是”
,数组s的地址就是……s
; 但 如果他写的是&t
, 则 表示==变量t的地址是?==”。
&t表示指针变量t的存储地址,因为计算机回味指针变量分配存储空间.
t表示指针变量指向数据的存储地址。
所以 &t != t
而计算机不会为数组变量分配任何空间,仅在出现它的地方把它换成数组的起始地址。
所以 &s == s
- 3 数组变量不能指向其他地方
当创建
指针变量
是,计算机会为它分配4
或8
字节的存储空间
如果创建的是数组,计算机会为数组分配空间,但不会为数组变量
分配任何空间,编译器
仅在出现它的地方把它
替换成数组的起始地址
。
由于计算机没有为数组变量分配空间,也就不能把它指向其他地方。
s = t;
会编译报错
但是t = s
是可以的
指针退化
由于
数组变量
和指针变量
有一点小小的区别, 所以把数组
赋给
指针
时千万要小心。 假如把数组赋给指针变量
,指针变量只会包含数组的地址 信息
, 而对数组的长度
一无所知, 相当于指针丢失了一些信息
。 我们把这种信息的丢失称为去退化
。
只要把数组传递给函数,数组就免不了退化为指针,但要记清楚代码中有哪些地方发生过数组退哈,因为他们会会引发一些不易察觉的错误。
为什么数组从零开始
数组变量可以用作指针,这个指针指向数组的第一个元素,也就是说除了方括号表示法,还可以用*
运算符读取数组的第一个元素,如:
int drinks[] = {4,2,3};
printf("第一单:%i 杯\n",drinks[0]);
printf("第一单:%i 杯\n",*drinks);
两行代码是等价的,也就是说drinks[0]
=*drinks
地址只是一个数字,所以可以进行指针算术运算
,比如为了找到存储器的下一个地址,可以增加
指针的值,也可以增加方括号的索引值:
int drinks[] = {4,2,3};
printf("第一单:%i 杯\n",drinks[2]);
printf("第一单:%i 杯\n",*(drinks+2));
表达式drinks[i]
和*(drinks+i)
是等价的。
这也解释了为什么数组要从索引0开始
所谓索引,其实就是为了找到元素的地址,指针需要加上的那个数字。
为什么指针有类型
如果对
char
指针加1,指针会指向下一个地址,因为char
就占1个字节。
如果对int
指针加1,因为int通常占4
个字节,因此编译后的代码就会对存储器地址加4
。
所以,指针之所以有类型,是应为编译器在指针运算是需要知道加几。
网友评论