46 字符数组和字符串

1,用来存放字符的数组称为字符数组

2,字符数组实际上是一系列字符的集合,也就是字符串(String),在C语言中,没有专门的字符串变量,没有 string 类型,通常就用一个字符数组来存放一个字符串

3,C语言中,字符串实际上是使用  null 字符 ( ' ' ) 终止的一维字符数组,因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

4,' ' 是 ASCII 码表中的第0个字符,用NULL表示,称为空字符,该字符既不能显示,也不是控制字符,输出该字符不会有任何效果,它在C中仅作为字符串的结束标志。

5,字符数组(字符串)在内存中的布局分析

  

   ① 字符数组 c 分配了7个字节,但是它的字符串长度只有3占3个字节,所以系统会自动在 'm' 的后面再添加一个 '' 作为字符串的结束标志

  ②字符数组 str 只分配了3个字节,它本身的字符串长度也是3个字节,没有多余的空间让系统添加一个 'o' ,会异常输出

1 void main() {
2     char str1[7] = { 't','o','m' };
3     char str2[3] = { 'a','b','c' };
4     printf("str1=%s
", str1);
5     printf("str2=%s
", str2);
6 }

 str1 正常输出,str2输出 abc 后,没有找到字符串的结束标志 '' ,会继续输出,直到输出 m 时在后面遇到了 '' 为止。

若将第2行改为 char str2[4] = { 'a','b','c',''};  ,手动添加一个 '' ,就能正常输出 tom

⑥如果在给某个字符数组赋值时,赋给的元素的个数小于该数组的长度,则会自动在后面加 '' ,表示字符串结束。赋给的元素的个数等于该数组的长度时,则不会自动添加 '',

  char str[] = { 'a','b','c' };  没有定义字符数组的长度时,系统也不会自动添加 '',abc后面输出仍是乱码

  

6,字符串的访问和遍历

  ①因为字符串的本质就是字符数组,因此可以按照数组的方式遍历和访问某个元素,

 1 #include<stdio.h>
 2 #include<string.h>
 3 void main() {
 4     char greeting[] = "hello";
 5 
 6     //1,字符串长度
 7     int len = strlen(greeting);
 8     printf("字符串的长度为:%d
", len);
 9 
10     //2,字符串的访问
11     printf("字符串第2个字符是%c
", greeting[1]);
12 
13     //3,遍历字符串
14     for (int i = 0;i < len;i++) {
15         printf("%c ", greeting[i]);
16     }
17 }

        

   ②对应的内存分析图

    

 7,字符串的表示形式

  ①用字符数组存放一个字符串

    如:char str[ ] =" hello tom " ;

      char str2[ ] = { 'h' , 'e' } ;

  ②用字符指针指向一个字符串

    如:char* pstr=" hello tom " ;

    C 语言中对字符串常量“ hello tom " 是按字符数组处理的,在内存中开辟了一个字符数组用来存放字符串常量,程序在定义字符串指针变量 str 时只是把字符串首地址(即存放字符串的字符数组的首地址)赋给 pstr 

    printf(" %s " ,pstr) ;  可以输出 str 指向的字符串

    

    对应的内存布局:

    

    pstr 是一个字符指针,存储的是字符串常量”hello " 的地址(字符数组的首地址),指向的是 “ hello"

8,①字符数组由若干个元素组成,每个元素放一个字符,而字符指针变量中存放的是地址(字符串/字符数组的首地址),绝不是将字符串放到字符指针变量中

  ②对字符数组只能对各个元素赋值,不能用以下方式对字符数组赋值

    

     这里的 str 实际上是一个常量,在内存中开辟了14个字节存储这个常量,不能修改str这个值,不能再给它赋值” hello tom " 

  ③对字符指针变量,采用下面的方法赋值,是可以的   

    void main() {
      char* a = "yes";
      a = "hello tom";
    }

    

     a 是一个字符指针,存储的是 yes 的地址,指向的 yes 这个字符串常量,执行 a = "hello tom " 时,a 这个字符指针存储的是 "hello tom"的地址,指向的是” hello tom “ 

     如果定义了一个字符数组,那么它有确定的内存地址(即字符数组名是一个常量),而定义一个字符指针变量时,它并未指向某个确定的字符数组,并且可以多次赋值。

9,字符串相关函数

  常用字符串函数

    

10,字符串(字符数组)使用细节:

  ①程序中往往靠检测 ' ' 的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度,因此,字符串长度不会统计 ' ' ,字符数组长度会统计

  ②在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度,否则,在输出字符数组时可能出现未知字符。

  ③系统对字符串常量也自动加一个 '' 作为结束符,录入“ C progrom” 共有9个字符,但在内存中占用10个字节,最后一个字节 ' ' 是系统自动加上的。(通过 sizeof()可以验证)

  ④定义字符数组时,如果给的字符个数比数组的长度小,则系统会默认将剩余的元素空间,全部设置为 ' ' ,比如 char str[6] = "ab" ,str 内存布局就是: [a][b][][][][]

  ⑤字符数组定义和初始化的方式比较多

 1 void main() {
 2     char str1[] = { "I am happy" }; //默认后面加 ''
 3     char str2[] = "I am happy";  //省略{},默认后面加''
 4     char str3[] = { 'I',' ','a','m',' ','h','a','p','p','y' };//字符数组后面不会加'',可能有乱码
 5     char str4[5] = { 'C','h','i','n','a' };//字符数组后面不会加'',可能有乱码
 6     char* pstr = "hello";
 7 
 8     printf("str1=%s
", str1);
 9     printf("str2=%s
", str2);
10     printf("str3=%s
", str3);
11     printf("str4=%s
", str4);
12     printf("pstr=%s
", pstr);
13 }

  

原文地址:https://www.cnblogs.com/shanlu0000/p/12355283.html