1.使用字符串常量
位于双引号内,编译器自动提供结束标记字符。属于静态存储类,该字符串在运行时只存储一份,整个引号的内容作为指向该字符串存储位置的指针。与数组名类似。
- #include<stdio.h>
- int main(void){
- printf("%s,%p,%c\n","We","are",*"world!");//最后一个输出字符串第一个字符‘w’!
- return 0;
- }
2.char数组
指定大小时一定要比字符串长度多1来容纳空字符。未被使用的自动初始化为0,这里的0是char形式的空字符,不是数字字符0。也可以让编译器计算数组大小。
3.char指针
几乎完全相同,几乎!
- #include<stdio.h>
- int main(void){
- const char *m3[] = "Hello";//几乎完全相同于下面的
- char m3[] = "Hello";
- return 0;
- }
它们的差别是什么呢?
在数组形式中m3是个地址常量,不能更改m3,这相当于一个常量指针,不能改变指向。可以使用运算符m3+1来标识数组里的下一个元素,但是不能使用++m3,因为增量运算符只能使用在变量前不能用在常量前!数组形式需要复制静态存储区中的"Hello",生成它的一个副本!指向这个副本的唯一指针就是数组名,所以必须是常量指针,否则改变指向后就再也找不到这个副本了!
在指针形式中,m3是个变量指针,可以改变指向,可以使用增量运算符++m3。不会赋值静态存储区中双引号里面的内容,只是生成一个指针指向这个内容!如果我们改变这个指针的指向,静态存储区中的字符串内容还是可以被找到的,因为别的指针可能在引用它,所以这个指针不是常量指针,可以改变指向!
总之,数组初始化是从静态存储区把一个字符串赋值给数组,而指针初始化只是复制字符串的地址。
- #include<stdio.h>
- int main(void){
- char heart[] = "I love Tillie";
- char *head = "I love Millie";
- int i;
- for(i=0;i<6;i++)//都可以使用数组符号
- putchar(heart[i]);
- putchar('\n');
- for(i=0;i<6;i++)
- putchar(head[i]);
- putchar('\n');
- for(i=0;i<6;i++)//都可以执行指针加法
- putchar(*(heart+i));
- putchar('\n');
- for(i=0;i<6;i++)
- putchar(*(head+i));
- putchar('\n');
- //++heart;只有指针才能使用增量运算符
- //++head;
- //head = heart;//可以让head改变指向指向heart
- //heart = head; 不能改变heart的指向
- heart[0] = 'S'; //可以改变数组形式的元素,因为不能改变指向,但是可以指向的地址的内容
- *(heart + 7) = 'K';
- //head[0] = 'F';//可以改变数组形式的元素,但是尽量不要去改变指针形式的元素,因为指针形式的元素没有存在副本,修改会引起很多问题
- //所以建议的做法是使用const修饰符 const char * p1 = "Hello";
- //数组形式不存在这个问题,因为它复制了一个副本
- getchar();
- return 0;
- }
4.字符串数组
- #include<stdio.h>
- #define LIM 5
- int main(void){
- const char *mytal[LIM] = {"Apple","Pear","Orange"};
- //这里LIM是行号,而不是列号,这与我们平时的二维数组是不一样的,平时我们提供列号但是不提供行号
- //mytal 是一个一维数组,实际上并不存放字符串,只是存放字符串的地址
- //尽管mytal没有被定义为二维数组,但是我们还是可以使用mytal[0][0]来引用第一个字串的第一个字符
- char mytal2[5][7] = {"Apple","Pear","Orange"};
- //字符串本身被存放在数组里,这是一个二维数组
- getchar();
- return 0;
- }
5.指针与字符串
绝大多数C字符串操作使用的都是指针。因为指针复制就是产生一个指向同一个字符串的多个指针!这样会有很高的效率,如果确实需要复制字符串,可以使用函数strcpy和strncpy!
- #include<stdio.h>
- int main(void){
- char * mesg = "Don't be a fool";
- char * copy;
- copy = mesg;
- printf("mesg=%s;&mesg=%p;value=%p\n",mesg,&mesg,mesg);//最后一项value的值是相等的,说明是引用的同一个字符串!
- //字符串本身并没有发生复制
- printf("copy=%s;©=%p;value=%p\n",copy,©,copy);
- getchar();
- return 0;
- }