这篇文章主要是字符串和字符数组的一个学习笔记。
1、字符串
(1)概念
什么叫字符串?一个或多个字符的序列就叫做“字符串”。
C语言里形如“Hope is a good thing.”
双引号并不属于字符串的一部分,仅仅是用来告诉编译器括起来的是字符串。
(2)C语言里的字符串
C语言中的字符串使用字符数组存储(请注意:空字符不要跟NULL弄混了,空字符是字符串的终止符,而NULL是一个符号,表示不引用任何内容的内存地址)
2、字符串与字符数组
声明存储字符串的数组时,数组大小至少要比所存储的字符数多1,这是因为编译器会自动地在字符串常量的末尾添加空字符\0。
#include <stdio.h> #include <stdlib.h> int main(){ //定义字符串的几种方式 //字符串和字符数组的区别:最后一位是不是空字符 char names1[] = {'j','a','c','k','\0'}; char names2[] = "jack"; // char *name3 = "jack"; printf("数组所占空间大小:%d\n",sizeof(names1)); printf("数组所占空间大小:%d\n",sizeof(names2)); //printf("数组所占空间大小:%d\n",sizeof(names3)); return 0; }
3、gets/puts函数补充
gets函数不对接受字符串的buffer进行边界检测,会造成越界,从而产生bug。
可以使用fgets(words1,20.stdin);来代替gets,20表示最多读入20-1个字符。
#include <stdio.h> #include <stdlib.h> int main(){ //定义字符串的几种方式 //字符串和字符数组的区别:最后一位是不是空字符 char names1[] = {'j','a','c','k','\0'}; char names2[50] = "jack"; //char *name3 = "jack"; int i = 1; printf("数组所占空间大小:%d\n",sizeof(names1)); printf("数组所占空间大小:%d\n",sizeof(names2)); //printf("数组所占空间大小:%d\n",sizeof(name3)); printf("请输入新名称:"); //gets(names2); //scanf("%s",name2); fgets(names2,10,stdin);//从标准输入流中读取10-1个字符到数组names2中 //在满足能够打印所有元素的前提下,fgets会默认给最后一个元素设置\n printf("数组names2中的内容:%s\n",names2); printf("**********************\n"); for(i=0;i<11;i++){ printf("%d\n",names2[i]); } //puts(names2); //printf("%s\n",names2); return 0; }
4、计算字符串长度
(1)不带转义字符的字符串
“abc!x = /“,长度是7。
(2)带转义字符的字符串
字符串"abc\n":里面的'\n'是转义字符(即换行符),计算字符串长度时只能计作一个字符,所以这个字符串的长度是4(而非5)。
字符串"abc\n\\\'\"":这里面有4个转义字符,分别是'\n'(换行符),'\\'(反斜杠),'\''(单引号),'\"'(双引号),所以这个字符串的长度是7(而不是11哦)。
字符串"abc\0xyz":其中有一个转义字符'\0',它是字符串结束符,所以当用函数strlen来测试该字符长度时,结果应为3,而不应该是7。
字符串"abc\\0xy":其中有一个转义字符'\\'(反斜杠),这样的话后面的字符串"0xy"照样得算,所以该字符串的长度是7。
字符串"abc\\\0xy":这里面有两个转义字符,'\\'(反斜杠)和'\0'(字符串结束符),当用函数strlen来测试这个字符串的长度的时候,结果应该是4了而不是7。
字符串"abc\\\061xy":其中有两个转义字符'\\'(反斜杠)和'\061'(ASCII码值是061的字符,也就是数字字符'1'),这时当用函数strlen来测试该字符串的长度时,结果应为7而不是4或者9。咱们可以试一下printf("abc\\\061xy");输出,输出结果是abc\1xy。
所以应该有这样的意识,当遇到转义字符'\0'的时候要看一看它后面是不是还有数字。若有,就应该将后面的数字(一至二位)与前面的'\0'相结合作为一个字符计入整个字符串的长度。
5、字符串操作
(1)strlen函数
用来计算字符串的实际长度,不包含字符串结束标志\0哦。。。
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char word1[] = "HelloWorld"; char word2[] = {'H','e','l','l','o','W','o','r','l','d','\0'}; char word3[] = "你好,大鹏学长!"; printf("word1的长度是:%d\n",strlen(word1)); printf("word2的长度是:%d\n",strlen(word2)); printf("word3的长度是:%d\n",strlen(word3)); return 0; }
(2)字符串复制:strcpy函数
把源字符数组中的字符串复制到目的字符数组中,连同结束标志\0一同复制。
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char word1[50] = "HelloWorld"; char word2[20]; printf("请输入字符串:"); gets(word2); strcpy(word1,word2); printf("%s\t%s\n",word1,word2); return 0; }
(3)字符串比较:strcmp函数
将两个字符串从首字母开始按照ASCII码的顺序进行逐个比较。
字符串1 == 字符串2,返回0。
字符串1 < 字符串2,返回正数。
字符串1 > 字符串2,返回负数。
(4)字符串连接:strcat函数
将一个字符串连接到另一个字符串的末尾,组合成一个新的字符串。
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char str1[100] = "我爱科比!"; char str2[20] = "我爱詹姆斯!"; strcat(str1,str2); printf("str1:%s\tstr2:%s",str1,str2); return 0; }
6、数组与指针
(1)指向字符串的指针
可以指向常量字符串
可以指向存储字符串的字符数组
(2)数组形式和执行形式的不同
初始化字符数组会把静态存储区的字符串拷贝到数组中
初始化指针时只把字符串的地址拷贝给指针
#include <stdio.h> #include <stdlib.h> int main(){ char str1[] = "I Love You"; char *str2 = "I Love You"; printf("字符串常量的地址:%p\n","I Love You"); printf("字符数组的首地址:%p\n",str1); printf("字符指针的取值:%p\n",str2); //str1++;不能执行! //str2++;可以执行! return 0; }