1.使用字符串常量

位于双引号内,编译器自动提供结束标记字符。属于静态存储类,该字符串在运行时只存储一份,整个引号的内容作为指向该字符串存储位置的指针。与数组名类似。

 

  1. #include<stdio.h> 
  2.  
  3. int main(void){ 
  4.     printf("%s,%p,%c\n","We","are",*"world!");//最后一个输出字符串第一个字符‘w’! 
  5.     return 0; 

2.char数组

指定大小时一定要比字符串长度多1来容纳空字符。未被使用的自动初始化为0,这里的0是char形式的空字符,不是数字字符0。也可以让编译器计算数组大小。

3.char指针

几乎完全相同,几乎!

  1. #include<stdio.h> 
  2.  
  3. int main(void){ 
  4.     const char *m3[] = "Hello";//几乎完全相同于下面的  
  5.     char m3[] = "Hello"
  6.      
  7.     return 0; 

它们的差别是什么呢?

在数组形式中m3是个地址常量,不能更改m3,这相当于一个常量指针,不能改变指向。可以使用运算符m3+1来标识数组里的下一个元素,但是不能使用++m3,因为增量运算符只能使用在变量前不能用在常量前!数组形式需要复制静态存储区中的"Hello",生成它的一个副本!指向这个副本的唯一指针就是数组名,所以必须是常量指针,否则改变指向后就再也找不到这个副本了!

在指针形式中,m3是个变量指针,可以改变指向,可以使用增量运算符++m3。不会赋值静态存储区中双引号里面的内容,只是生成一个指针指向这个内容!如果我们改变这个指针的指向,静态存储区中的字符串内容还是可以被找到的,因为别的指针可能在引用它,所以这个指针不是常量指针,可以改变指向!

总之,数组初始化是从静态存储区把一个字符串赋值给数组,而指针初始化只是复制字符串的地址。

 

  1. #include<stdio.h> 
  2.  
  3. int main(void){ 
  4.     char heart[] = "I love Tillie"
  5.     char *head = "I love Millie"
  6.     int i; 
  7.      
  8.     for(i=0;i<6;i++)//都可以使用数组符号  
  9.         putchar(heart[i]); 
  10.     putchar('\n'); 
  11.     for(i=0;i<6;i++) 
  12.         putchar(head[i]); 
  13.     putchar('\n'); 
  14.      
  15.     for(i=0;i<6;i++)//都可以执行指针加法  
  16.         putchar(*(heart+i)); 
  17.     putchar('\n'); 
  18.     for(i=0;i<6;i++) 
  19.         putchar(*(head+i)); 
  20.     putchar('\n'); 
  21.      
  22.     //++heart;只有指针才能使用增量运算符  
  23.     //++head; 
  24.      
  25.     //head = heart;//可以让head改变指向指向heart  
  26.     //heart = head; 不能改变heart的指向 
  27.      
  28.     heart[0] = 'S'//可以改变数组形式的元素,因为不能改变指向,但是可以指向的地址的内容 
  29.     *(heart + 7) = 'K'
  30.      
  31.     //head[0] = 'F';//可以改变数组形式的元素,但是尽量不要去改变指针形式的元素,因为指针形式的元素没有存在副本,修改会引起很多问题 
  32.                  //所以建议的做法是使用const修饰符 const char * p1 = "Hello"; 
  33.                  //数组形式不存在这个问题,因为它复制了一个副本  
  34.      
  35.     getchar(); 
  36.     return 0; 

 

 

4.字符串数组

 

  1. #include<stdio.h> 
  2. #define LIM 5 
  3.  
  4. int main(void){ 
  5.     const char *mytal[LIM] = {"Apple","Pear","Orange"}; 
  6.     //这里LIM是行号,而不是列号,这与我们平时的二维数组是不一样的,平时我们提供列号但是不提供行号 
  7.     //mytal 是一个一维数组,实际上并不存放字符串,只是存放字符串的地址 
  8.     //尽管mytal没有被定义为二维数组,但是我们还是可以使用mytal[0][0]来引用第一个字串的第一个字符 
  9.      
  10.     char mytal2[5][7] = {"Apple","Pear","Orange"}; 
  11.     //字符串本身被存放在数组里,这是一个二维数组  
  12.          
  13.     getchar(); 
  14.     return 0; 

 

5.指针与字符串

绝大多数C字符串操作使用的都是指针。因为指针复制就是产生一个指向同一个字符串的多个指针!这样会有很高的效率,如果确实需要复制字符串,可以使用函数strcpy和strncpy!

 

  1. #include<stdio.h> 
  2.  
  3. int main(void){ 
  4.     char * mesg = "Don't be a fool"
  5.     char * copy; 
  6.      
  7.     copy = mesg; 
  8.     printf("mesg=%s;&mesg=%p;value=%p\n",mesg,&mesg,mesg);//最后一项value的值是相等的,说明是引用的同一个字符串! 
  9.                                                           //字符串本身并没有发生复制  
  10.     printf("copy=%s;&copy=%p;value=%p\n",copy,&copy,copy); 
  11.      
  12.     getchar(); 
  13.     return 0; 
  14. }