寻找生命的意义  
早日脱贫

0 前言

C语言中由于指针的灵活性,导致指针能代替数组使用,或者混合使用,这些导致了许多指针和数组的迷惑。本文深入探究了指针和数组,主要是容易混淆的字符数组和字符指针。

1 数组的本质

数组是多个元素的集合,在内存中分布在地址相连的单元中,所以可以通过其下标访问不同单元的元素。

2 指针的本质

指针也是一种变量,只不过它的内存单元中保存的是一个标识其他位置的地址。由于地址也是整数,在32位平台下,指针默认为32位。
指针变量永远是整型,因为它保存的是地址。

3 指针的指向

指向的直接意思就是指针变量所保存的地址指向的内存单元所保存的数据类型。

int* p;  //p变量保存的地址所指向的内存单元中的数据类型为整型

4 字符数组

本质意义:数组中的元素是字符。

char str[10]={"hello world"};
  1. 当编译器遇到这句时,会把str数组中从第一个元素把hello world\0 逐个填入。
  2. 由于C语言中没有真正的字符串类型,可以通过字符数组表示字符串,因为它的元素地址是连续的,这就足够了。
  3. C语言中规定数组代表数组所在内存位置的首地址,也是 str[0]的地址,即str = &str[0]。
  4. C语言中字符串常量的本质表示其实是一个地址。(难点)

针对难点4

char* s;
s="China";

C语言中编译器会给字符串常量分配地址,如果 "China", 存储在内存中的 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005。s="China";的真正意义是地址,即s ="China" = 0x3000;。你把"China"看作是字符串,但是编译器把它看作是地址0x3000,即字符串常量的本质表现是代表它的第一个字符的地址。

%s的原理其实也是通过字符串首地址输出字符串,printf("%s ", s); 传给它的其实是s所保存的字符串的地址。
对于char str[10] = "hello";``printf("%s",str);本质也是 printf("%s", "hello"的首地址); C语言中操作字符串是通过它在内存中的存储单元的首地址进行的,这是字符串终极本质

5 char* 与char a[]

char  *s;
char  a[ ];

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++);

字符指针可以用 间接操作符 *取其内容,也可以用数组的下标形式 [ ],数组名也可以用 *操作,因为它本身表示一个地址。

char* 与char a[]的本质区别

当定义 char a[10]时,编译器会给数组分配十个单元,每个单元的数据类型为字符;而定义char *s时,这是个指针变量,只占四个字节,32位,用来保存一个地址。

sizeof(a) = 10;
sizeof(s) = 4;  //编译器分配4个字节32位的空间,这个空间中将要保存地址。

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个字节了。

char **s;

char **为二级指针,s保存一级指针char *的地址。

二级指针

posted on 2022-12-11 16:21  田园脆鸡堡  阅读(275)  评论(0编辑  收藏  举报