首先,我们得明确,在C语言中,没有真正的字符串类型。

所以,就诞生了 字符串数组 这么个类型。

于是,当我们想申明一个字符串变量时,大体上有下面两种方法:

char str[] = "hello";
char *p = "hello";

str[]:它定义的是一个字符串数组变量。可以通过 str[0] = "w" 修改值。

*p:它定义的是一个指针变量。不能通过 *(p+0) = "w" 修改值。

为什么这两种写法都可以呢?这就和C语言中字符串本质有关了。

C语言中字符串本质 是返回一个首个字符地址

也就是说 str 代表 "h" 的地址,p 也存储着 “h" 的地址。

sizeof()打印的区别

下面,我们再来看看对 str 和 p 取 sizeof() 会有什么惊喜:

C语言中 char str[] 与 char *str 的关系_c语言

很明显,可以看到两个打印值不一样,我们来分析一下为什么是这个值。

sizeof(str) -> 6:char 类型是 1 个字节 ==》存在 "hello" 5个字符 + “\0" 1个结束符 = 6个字符 ==》所以 sizeof(str) 为 6。也就是说字符串数组变量所占内存的大小 与存储值的类型和存储数量有关

sizeof(p) -> 8:p 是一个存储地址的变量,前面的 char 是说明存储的这个地址对应的值的类型,和 p 的类型没关系。而 存储地址的大小和平台位数有关,我是64位电脑,所以打出来的是 8。

strlen()

C语言中 char str[] 与 char *str 的关系_c语言_02

可以看到都是5,因为 strlen() 的判断标准是 结束符 ‘\0',结束符是一样的,strlen()结果当然是一样的。

关于是否预留 结束符位 的总结:当你的 char 是用来装数据(如sm2密钥)时,数据是多长你就分配多长即可。当你的 char 是用来装字符串时,得多预留一个位置装结束符。