文章目录
1.数组的本质
数组是多个元素的集合,在内存中分布在地址相连的单元中,所以可以通过其下标访问不同单元的元素。
2.指针
指针一种变量,只不过它的内存单元中保存的是一个标识其他位置的地址。由于地址也是整数,在32位平台下,指针默认为32位。
3.指针的指向
指向的直接意思就是指针变量所保存的其他的地址单元中所存放的数据类型。
int *p; //p变量保存的地址所在内存单元中的数据类型为整型
float *q; // .............浮点型
不论指向的数据类型为哪种,指针变量其本身永远为整型,因为它保存的地址。
4.字符数组
字面意思是数组,**数组中的元素是字符。**确实,这就是它的本质意义。
char str[10]; //定义了一个有十个元素的数组,元素类型为字符。
C语言中定义一个变量时可以初始化。
char str[10] = {
"hello"};
当编译器遇到这句时,会把str数组中从第一个元素把hello\0 逐个填入。
C语言中规定数组代表数组所在内存位置的首地址,也是 str[0]的地址,即str = &str[0];
!!!
printf("%s",str);
为什么用首地址就可以输出字符串。
因为还有一个关键,在C语言中字符串常量的本质表示其实是一个地址
举例:
char *s ;
s = "China";
为什么可以把一个字符串赋给一个指针变量?
C语言中编译器会给字符串常量分配地址,如果 “China”, 存储在内存中的 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005 .
s = “China” ,意识是什么,对了,地址。
其实真正的意义是 s ="China" = 0x3000;
那么 %s ,它的原理其实也是通过字符串首地址输出字符串,printf("%s ", s); 传给它的其实是s所保存的字符串的地址。
#include <stdio.h>
int main()
{
char *s;
s = "hello";
printf("%p\n",s);
return 0;
}
结果:
00422020
可以看到 s = 0x00422020 ,这也是"hello"的首地址
所以,printf("%s",0x00422020);也是等效的。
字符数组:
char str[10] = "hello";
前面已经说了,str = &str[0] ,也等于 "hello"的首地址。
所以printf("%s",str); 本质也是 printf("%s", 地址);
C语言中操作字符串是通过它在内存中的存储单元的首地址进行的,这是字符串的终极本质。
4.char * 与 char a[]
char *s;
char a[] ;
前面说到 a代表字符串的首地址,而s 这个指针也保存字符串的地址(其实首地址),即第一个字符的地址,这个地址单元中的数据是一个字符,
这也与 s 所指向的 char 一致。
因此可以 s = a;
但是不能 a = s;
C语言中数组名可以复制给指针表示地址, 但是却不能赋给给数组名,它是一个常量类型,所以不能修改。
当然也可以这样:
char a [ ] = "hello";
char *s =a;
for(int i= 0; i < strlen(a) ; i++){
printf("%c", s[i]); //或 printf("%c",*s++);
}
字符指针可以用 间接操作符 *取其内容,也可以用数组的下标形式 [ ],数组名也可以用 *操作,因为它本身表示一个地址 。
比如
printf("%c",*a);
将会打印出 'h'
5.char * 与 char a[] 的本质区别:
当定义 char a[10] 时,编译器会给数组分配十个单元,每个单元的数据类型为字符。
定义 char *s 时, 这是个指针变量,只占四个字节,32位,用来保存一个地址。
sizeof(a) = 10 ;
sizeof(s) = ?
当然是4了,编译器分配4个字节32位的空间,这个空间中将要保存地址。
printf("%p",s);
这个表示 s 的单元中所保存的地址。
printf("%p",&s);
这个表示变量本身所在内存单元地址,不要搞混了。
6.char ** 与char *a[]
char *a[] ;
由于[] 的优先级高于 * 所以a先和 []结合,他还是一个数组,数组中的元素才是char * ,前面讲到char *是一个变量,保存的地址。
char *a[] = {“China”,“French”,“America”,“German”};
通过这句可以看到, 数组中的元素是字符串,那么sizeof(a) 是多少呢,有人会想到是五个单词的占内存中的全部字节数 6+7+8+7 = 28;
但是其实sizeof(a) = 16;
为什么,前面已经说到, 字符串常量的本质是地址,a 数组中的元素为char * 指针,指针变量占四个字节,那么四个元素就是16个字节了
看一下实例:
#include <stdio.h>
int main()
{
char *a [ ] = {
"China","French","America","German"};
printf("%p %p %p %p\n",a[0],a[1],a[2],a[3]); //数组元素中保存的地址
printf("%p %p %p %p\n",&a[0],&a[1],&a[2],&a[3]);//数组元素单元本身的地址
return 0;
}
可以看到 0012FF38 0012FF3C 0012FF40 0012FF44,这四个是元素单元所在的地址,每个地址相差四个字节,这是由于每个元素是一个指针变量占四个字节。