C语言中的指针-字符串指针变量和字符数组的比较-学习笔记-34

引入

上面我们引入了很多例子,发现字符指针和字符数组仿佛使用起来差不多,真的是这样嘛?其实并不是,我们来细数字符指针和字符数组之间的区别吧!

组成

字符指针和字符数组的组成上,有很大的不同。
字符指针:存放的是地址,是字符串首元素的地址。
字符数组:存储的是数组中的所有元素。

赋值方式

字符指针:我们可以对指针赋值,赋值一个新的地址给指针。
字符数组:我们不能给一个数组名赋值,职能给某一个数组元素赋值。

1
2
3
4
5
6
7
8
9
10
11
//对字符指针变量赋值;
char *a="Hello!";
a="Hello"; //注意,这里不是*a,因为要把这个字符串的首地址给 a,a 是指针,只能接收地址。

//对字符数组赋值
char str[20]="Hello!";
str[2]="C";

//下面的方式就是错误的
str="I am Chinese!"
我们无法对数组名直接赋值。

初始化

对于字符指针变量初始化:

1
2
3
4
char *a="I love you !";
//上面等价于下面
char *a;
a="I love you !";

对于字符数组的初始化:

1
2
3
4
char str[14]="I am China !";
// 下面这种初始化是不对的, 等同于给数组名赋值
char str[15];
str[]="I am China !" // 这事不对的!

存储单元

字符指针和字符数组在程序编译时,编译器为其创造的存储单元是不同的。
字符数组:
因为字符数组是一种特殊的数组,既然是数组,编译器就会为数组中的每一个元素创建存储单元。
字符指针:
字符指针存储的是地址,是字符串的首元素地址,所以编译器只为其创造4个字节的存储单元,用于存放地址。

在创建完字符指针后,要及时的把指针指向数组或者变量,否则指针指向的内容不可预测,可能会指向系统重要文件,一单修改,可能会导致系统崩溃!

修改

字符指针变量,其存储的是一组内存地址,我们可以再次给指针赋值一个新的地址,或者通过加减移动指针。
字符数组,表示的也是一组内存地址,是该数组的首元素地址,但该地址是一个常量,我们无法修改该地址。

1
2
3
4
5
6
7
#include <stdio.h>
int main(){
char *a="I am Chinese!";
a=a+2;
printf("%s\n",a);
return 0;
}

如果是字符数组,我们就无法通过加减移动他的当前地址。

重新赋值

如果我们想对字符串的某个字符修改:
字符数组就可以很简单的完成:

1
2
3
4
char str[]="Chinese",*a="Boy";
str[0]='B';
//我们得到的就是「Bhinese」
a[0]='A'; //这样是不合法的,因为这是一个字符串常量,无法赋值

注意
虽然指着存储的是地址,我们也可以通过下标法找到指向的字符串中的某个元素,但我们无法修改,因为这是一个字符串常量。

引用方式

字符数组:
可以是下标法 或者 地址法,如果字符指针变量指向了该数组,则同样可以使用下标法或者地址法。

字符指针变量:
如果没有指向数组,则无法使用下标法或地址法。

因为字符指针变量也是按照数组的方式存储的,所以我们可以在不定义数组的时候,依旧使用下标法来移动指针。

可变格式输出函数

我们经常使用 printf 关键字来输出字符
printf(”格式化文本”,变量)
前面的格式化文本包括双引号,都可以用地址来代替。
例如:

1
2
3
4
5
6
#include <stdio.h>
int main(){
char str[]="你好 %s ,早上好!\n",name[]="Bliner";
printf(str,name);
//str 等同于 "你好 %s ,早上好!"
}

使用指针同样可以:

1
2
3
4
5
6
#include <stdio.h>
int main(){
char *str="你好 %s ,早上好!\n",*name="Bliner";
printf(str,name);
//str 等同于 "你好 %s ,早上好!"
}

但是下面的这种方式就是错误的了:

1
2
char str[20];
str="你好 %s ,早上好!\n";

所以我们尽量在初始化的时候就赋值。

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!