字符串
字符串是以字符数组的方式存在的
不能对其用运算符做运算
通过数组的方式可以遍历字符串
可以通过字符串常量去初始化字符数组
字符数组
以0结尾的一串字符
0标志字符串的结束,但它不是字符串的一部分,计算字符串长度的时候不包含这个0
字符串以数组的形式存在,以数组或指针的形式访问
格式: char hello[] = {'H','e','l','l','o','!','\0'};
每个字符使用单引号
结尾的'\0'
可以写成0,但是不能写成’0’
对应的分别是
元素 | 值 |
---|---|
hello[0] | H |
hello[1] | e |
hello[2] | l |
hello[3] | l |
hello[4] | o |
hello[5] | ! |
hello[6] | \0 |
字符串变量
指针变量 char *string = "Hello";
字符数组 char word[] = "Hello";
字符数组char line[6] = "Hello"
会占据6个字节的空间
字符数组在本地存放,本地变量的空间会自动回收
指针用来处理参数和不可修改的值,以及动态分配空间
当需要构建一个字符串时使用数组的方式,当处理字符串时用指针
char *
字符串可以表达成char*
的形式,但char*
不一定是字符串,只有当它所指的字符数组的结尾处是0才能确定它指向的是字符串
字符串常量
“Hello”就是字面量/常量,它会被编译器变成一个字符数组放在某处,这个数组的长度是字符+1,在结尾处还有个表示结束的0
两个相邻的字符串常量会被自动连接起来
当使用指针去定义字符串的时候,字符串常量是只读的,无法被修改 const char *s = "Hello,World";
当有第二个指针变量指向了已有的常量时,它们的地址是一模一样的
1 |
|
如果需要修改字符串中的常量,需要使用字符数组去定义字符串char word = "Hello,Wolrd";
输入输出
将指针变量a字符串赋值给另一个指针b的时候,是将a地址指向了b,将它们两个链接起来了,对b做的任何操作都会映射到a
1 |
|
scanf作为字符串输入时,会读入一个单词(一串字符以空格和tab作为结束)
限制scanf的长度为12scanf ("%12s, a");
当超过12个字符后,越界的部分会被裁掉,当有连续的字符串时,会被挤到下个scanf
定义指针类型的字符串时,需要对变量进行初始化为0
空字符串
char a[10] = ""
意味着这是一个空的字符串,a[0] == ‘\0’
char a[] = ""
意味着这个字符串的长度只有1,而a[0]就是’\0’,所以你放不下任何东西
程序参数
main函数的参数有两个参数,前者a是告诉后者b数组中有多少个元素
后者b是在执行时可以带上的任何字符
1 |
|
输入输出
putchar
int putchar(int x)
把一个字符输出在标准输出上
当输出EOF( -1 )代表输出失败
参数是int类型,但只能接收一个字符,返回类型也是in
getchar
不需要参数int getchar(void)
返回从标准输入读取到的字符
返回类型是int,目的是为了返回EOF( -1 )表示标准输入结束
当程序获取到EOF状态,即当用户使用Ctrl + D
中断运行,就会在标准输出得到EOF结束程序运行
字符串函数
在头文件string.h中有很多函数可以调用
strlen (string length)
返回字符串的长度(不包含结尾的\0)size_t strlen(const char *s);
不会修改参数表中的参数
1 |
|
仿照strlen函数写一个自己的函数
1 |
|
strcmp (string compare)
对比两个字符串的大小,同样不会修改字符串int strcmp(const char *s1,const char *s2)
前者比较后者,前者与后者相同则返回0,前者小于后者则结果小于0,前者大于后者则结果大于0
不相等的结果取决于等于两者之间的差值,按照ASCII表
中字符的顺序计算
1 |
|
仿照strcmp函数写一个自己的函数
1 |
|
strcpy (string copy)
char *strcpy(char *restrict s1,const char *restrict s2)
将后者的内容拷贝到前者
restrict表示这两个字符串在地址中没有重叠部分
strcpy具有返回值,能够继续参与代码的其他运算,返回值是前者
1 |
|
strcat (concatenate string)
char *strcat(char *restrict s1,const char *restrict s2)
把后者连接到前者的后面,拼凑成一个字符串
restrict表示这两个字符串在地址中没有重叠部分
返回值是s1,在完成拼凑的这个操作时,得确保s1的空间是足够容纳s2的内容
1 |
|
strchr (locate character in string)
char *strchr(const char *s, int c);
返回一个指针,指向变量c第一次出现的位置,自左向右寻找
char *strrchr(const char *s, int c);
返回一个指针,指向变量c第一次出现的位置,自右向左寻找
当返回Null时表示没有找到,非0的值表示寻找到了,并返回指针
1 |
|
定位第二个相同字符
1 |
|
反向定位
第一个2开始算作p[0]以此类推
首先将p[0]的值备份一下,然后让它变成\0代表结束
动态分配一个临时的变量t去保存字符串s的值,也就是11
t = | 1 | 1 | \0 | 2 | 3 | 3 | 4 | 4 | \0 |
再恢复*p的值
s = | 1 | 1 | 2 | 2 | 3 | 3 | 4 | 4 | \0 |
1 |
|
strstr (locate a substring in a string)
char *strstr(const char *s1, const char *s2);
从字符串s2中定位s1的内容,并返回一个指针
1 |
|
char *strcasestr(const char *s1, const char *s2);
从字符串s2中定位s1的内容忽略大小写,并返回一个指针
1 |
|
char *strnstr(const char *s1, const char *s2, size_t 3);
仅从3个长度的字符串s2中定位s1的内容,并返回一个指针,当超过3个长度会返回null
1 |
|
限制字符串数量
strncpy
限制拷贝的最大字符数为12
char *strncpy(char *restrict s1,const char *restrict s2,size_t n);
– > strncpy(s1,s2,12);
strncat
限制能将后者连接到前者的最大字符数为12
char *strncat(char *restrict s1,const char *restrict s2,size_t n);
–> strncat (s1,s2,12);
strncmp
限制仅对比开头的三个字符
int strncmp(const char *s1,const char *s2,size_t n);
–> strncmp(s1,s2,3)