?
目录
字符串和指针有着紧密·的联系,下面我们就来学习字符串和指针的相似点和不同点。
下面我们来看用数组和指针实现的字符串
#include<stdio.h>
int main()
{
char str[] = "ABC";
char *ptr = "123";
printf("str=\"%s\"\n", str);
printf("ptr=\"%s\"\n", ptr);
return 0;
}
让我们来结合两图来分析它们的异同:
str是char[4]类型的数组,各元素从开头开始依次用‘A’ 'B' 'C' '\0'进行初始化,char数组占据的内存空间和数组元素个数一致,可以通过sizeof(str)求得
ptr是指向char型变量的指针变量,它的初始值为字符串字面量“123”,对字符串字面量进行判定,可以得到指向该字符串字面量第一个字符的指针,所以ptr被初始化为指向保存在内存中的字符串字面量“123”的第一个字符‘1’的指针
另外一般情况下,我们把指针p指向字符串字面量“string”的首个字符‘s’,称为“指针p指向string”
需要注意的是指针ptr不可进行如下声明:
char *ptr = {'1', '2', '3', '\0'};
数组用的{ }形式的初始值,不可以用于单一的变量
从上面的图可以看出,指针ptr和字符串字面量“123”都占用了空间,指针ptr占用的空间为sizeof(ptr),即sizeof(char*)字节,其长度因编译器而异。
请注意,用指针实现的字符串相比于数组需要更多的内存空间。
指针p是指向字符串首个字符的指针,数组str也是指向首个字符的指针(因为数组名会被解释为指向起始元素的指针)
综上,使用下标运算符[ ],可以访问字符串中的各个字符,这是二者的共同点
先让我们来看下面两段代码:
/*这是一段错误的代码*/
#include<stdio.h>
int main()
{
char s[] = "ABC";
printf("s= \"%s\"\n", s);
s = DEF;
printf("s= \"%s\"\n", s);
return 0;
}
/*这是一段正确的代码*/
#include<stdio.h>
int main()
{
char *p = "123";
printf("p= \"%s\"\n", p);
p = "456";
printf("p= \"%s\"\n", p);
return 0;
}
?在第一段代码中,目的是将“DEF”赋值给“ABC”的数组,并显示前后赋值的字符串,在进行DEF的赋值过程中会发生错误,所以程序无法执行,因为对数组不能进行赋值,虽然左边的数组名可以被解释为数组起始元素的地址,但依然不能改写其值,否则就会改变数组的地址。
我们用图来解释第二段代码的赋值的原理:
第一个图对应:
char *p = "123";
指针p的初始值为字符串字面量“123”,所以指针p指向字符串字面量“123”的第一个字符‘1’
第二个图对应:
p = "456";
与上面的解释一样,不过是对其地址上保存的值进行更改而异,指针p指向的字符变为了‘4’
不要误以为是进行了赋值,其实不过是指针的指向发生了变化,因为不再有指针指向123,所以该字符串也不能被访问,也就是说成为了无法清除的垃圾。
在前面我们学习了用数组和指针两种形式来表示字符串,而字符串数组就是将字符串“数组化”来实现的
#include<stdio.h>
int main()
{
int i = 0;
char a[][5] = {"MAX", "MIN"};
char *p[] = {"MAX", "MIN"};
for(;i < 2; i++)
printf("a[%d] = \"%s\"\n", i, a[i]);
for(;i < 2; i++)
printf("p[%d] = \"%s\"\n", i, p[i];
return 0;
}
数组a是2行5列的二维数组,占用的内存空间是10个字节(行数乘列数),并非所有的字符串长度是一样的,所以数组会产生未被使用的部分。
a[0][0] | a[0][1] | …… | …… | a[2][4] | a[2][5] |
0 | 1 | 2 | 3 | 4 | |
0 | M | A | X | \0 | \0 |
1 | M | I | N | \0 | \0 |
指针p是元素类型为char*型,元素个数为2的数组,数组p[0] p[1] 分别指向各字符串字面量的首字符‘M’的指针,因此除了数组p占用的2个sizeof(char*)长度之的空间之外,还占用2个字符串字面量的空间。
字符串字面量中的MAX中的字符,可以从头开始按顺序通过p[0][0] p[0][1]……等来访问,通过连续使用下标运算符[ ],可以像二维数组一样处理指针数组。
因为无法保证初始值的字符串字面量在内存单元时连续保存的,所以在上图中字符串字面量并不是相邻的,并不能想当然的认为“MAX”后面就保存着“M”,否则在有些编译器和运行环境中不能运行。
我也是终于放寒假了,希望在座的各位都能不挂科取得好成绩!!!