C语言学习笔记之字符串


字符串在C语言中实际是字符数组,因为C比其他大多数语言更底层,他并没有提供字符串这个数据类型,而是采用相似的东西代替,这就是以字符为元素的数组。

char *s="PPYY";

上面这个字符串(我们也把它称为字符串字面值),C会把它作为数组进行操作,

char s[]={'P','P','Y','Y'};

所以采用s[0],s[1]访问这个字符串是被允许的,但是需要非常清醒的是,字符串字面值是不能被修改的,因为字符串字面值和字符数组在内存当中的工作方式是不一致的。

将C语言梳理一下,分布在以下10个章节中:

  1. Linux-C成长之路(一):Linux下C编程概要
  2. Linux-C成长之路(二):基本数据类型
  3. Linux-C成长之路(三):基本IO函数操作
  4. Linux-C成长之路(四):运算符
  5. Linux-C成长之路(五):控制流
  6. Linux-C成长之路(六):函数要义
  7. Linux-C成长之路(七):数组与指针
  8. Linux-C成长之路(八):存储类,动态内存
  9. Linux-C成长之路(九):复合数据类型
  10. Linux-C成长之路(十):其他高级议题

C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码

我们以Linux系统为例,粗略说说为什么他们的工作方式不一致,下图是简略的内存结构图:

局部变量区域
无序组合
  全局区
只读存储区 常量区
  代码区

/*字符串字面值的工作工作方式*/

1、字符串字面值 "PPYY"先是存放在常量区,存放的样子如下:

 

P P Y Y \0

 

 (尾部有个\0 ,是字符串的在内存中的结束符,因为C语言并不知道字符串什么时候结束。)

2、然后在栈上创建s这个指针变量,用以存放指向常量区"PPYY"字面值的地址。

这就解释了为什么我们尝试修改字符串字面值的时候,程序会报错,因为字符串字面值是存放在常量区的。

/*字符数组的工作方式*/

1、"PPYY"这个字符串字面值仍然先是存放在常量区。

2、在栈上创建一个字符数组,数组的长度和数组元素都和先前的字符数组一致。

这个时候我们在程序中操作这个字符数组的时候,其实是操作的这个字符串字面值在栈空间中的字符数组副本。

这里我们顺着这个思路理清楚 char *s这个指针变量和char s[]这个数组变量的不同之处在什么地方。

char *s这个s是存放的常量区"PPYY"字面值的地址;而char s[]这个s表示栈空间中数组第一个元素的内存地址。上面两个描述,一个是存放,一个表示,因为char *s在初始化的时候,是在内存中分配了char类型的地址变量空间的。而char s[]在初始化的时候,是没有分配内存空间的,只是程序在编译的时候,会把这个s替换成数组第一个元素的内存地址。

char s[]和char *s在作为函数形参时效果是一样的,即void func_name(char s[])和void func_name(char *s)是等价的,但是此时的数组变量会退化成指针变量,作为数组变量,我们可以通过sizeof()运算符判断数组的长度,但是指针变量我们只能得到这个指针变量本身的长度。

本文永久更新链接地址:

相关内容