kendoziyu

1、定义字符串

C语言本身没有string类型,通常使用char数组来表示字符串。常用的定义字符串的方式有:

char str1[] = {\'C\', \'h\', \'i\', \'n\', \'a\'};
char str2[] = "China";
char* str3 = "China";
  1. 与Java语言不同,C语言中数组的括号是在变量名的后面。第一条定义字符串的语句等价于Java语言中:char[] str1 = {\'C\', \'h\', \'i\', \'n\', \'a\'};

  2. [] 中可以填入数字,表示char数组的长度。但是,中括号中的数字必须大于等于右边字符串数组的长度。

    • char str1[5] = {\'C\', \'h\', \'i\', \'n\', \'a\'}char str1[6] = {\'C\', \'h\', \'i\', \'n\', \'a\'}, ... , char str1[100] = {\'C\', \'h\', \'i\', \'n\', \'a\'} 都是合法的。
    • char str2[6] = "China";char str2[7] = "China";, ... ,char str2[100] = "China"; 都是合法的。
    • char str2[5] = "China";,如果 str2 括号内填写的数字小于 6 就会编译出错,出现数组界限溢出错误。

2、计算char数组的长度

在Java中,数组是看作对象类型的,数组有通用的属性 length,比如 str1.length 可以获取数组的长度。但是 C 语言可没有这么“友善”,想获取char数组的长度:

char str1[] = {\'C\', \'h\', \'i\', \'n\', \'a\'};
int len = sizeof(str1) / sizeof(char);  // 这句话计算字符串数组的长度
printf("%d", len);
  1. sizeof 是C语言中保留关键字,用来计算数据类型的“宽度”。用 sizeof 可以获得数据类型变量在内存中所占的字节数。同样,用 sizeof 也可以获得整个数组在内存中所占的字节数。

  2. 因为数组中每个元素的类型都是一样的,在内存中所占的字节数都是相同的,所以 总的字节数 除以 一个元素所占的字节数 就是数组的长度。

  3. sizeof(char) 表示数据类型 char 在内存中所占的字节数,在C语言中,char占一个字节,所以 sizeof(char) == 1

  4. 我这里说的字符串数组的长度,说到底还是数组的长度。

3、字符串必须以\0结尾。如果不是,就会出现乱码

char str1[] = { \'C\', \'h\', \'i\', \'n\', \'a\' };
printf("%s\n", str1);
  1. 上面这段代码在 Windows 上,用 Microsoft Visual Studio 运行时,会输出乱码。如图所示:

  2. C语言是一直读取到字节0作为字符串的结尾。Java则可以根据数组长度属性length,来读取指定长度的字符串。

  3. 所以,正确的定义方式应该是 char str1[] = { \'C\', \'h\', \'i\', \'n\', \'a\', \'\0\'};,此时字符串数组的长度是 6。 char str1[] = { \'C\', \'h\', \'i\', \'n\', \'a\', 0 }; 这样定义也是可以的,但是更推荐前一种。

4、定义一个空的字符串数组

char str0[100] = {0}; // 用这条语句定义一个空的字符串数组
int len0 = sizeof(str0) / sizeof(char); 
printf("%d", len0); // 数组长度为100
  1. 第一条语句就等同于Java中的char[] str0 = new char[100];

  2. 第一句语句也可以写成 char str0[100] = {};,这样写也是正确的。但是,char str0[] = {} 这样写不行,空初始值设定项对于未指定绑定的数组无效!

5、计算字符串的长度 strlen

与字符串数组的长度不同,字符串的长度是不把字节0算进去的。strlen 函数可以返回字符串的长度:

size_t strlen(const char* str);

然后来看几个实验:

char str1[] = {\'C\', \'h\', \'i\', \'n\', \'a\'};
char str2[] = "China";
char* str3 = "China";
char str4[] = {\'C\', \'h\', \'i\', \'n\', \'a\', \'\0\'};
printf("%d\n", strlen(str1)); // 输出结果为19
printf("%d\n", strlen(str2)); // 输出结果为5
printf("%d\n", strlen(str3)); // 输出结果为5
printf("%d\n", strlen(str4)); // 输出结果为5
  1. 其中,str1 所表示的字符串因为没有以 \'\0\' 结尾,所以,strlen 把内存中一直到 \0 结尾的字节都看作字符串的内容,所以长度为 19。

6、字符串常量不可修改

我们先来看一段程序:

char str0[] = {\'c\', \'h\', \'i\', \'n\', \'a\', \'\0\'};
char str1[] = "china"; // 在栈上,因为重载了=操作符
char* str2 = "china"; // china\0在常量区,str1在栈上

str0[0] = \'C\';
str1[0] = \'C\';
//str2[0] = \'C\';
//*str2 = \'C\';

printf("%s\n", str0);
printf("%s\n", str1);
printf("%s\n", str2);
  1. 运行结果是,str0[0] = \'C\'str1[0] = \'C\' 这两句可以正常运行。但是 str2[0] = \'C\'*str2 = \'C\' 会报错。

  2. char str1[] = "china"char* str2 = "china" 字符串存放的内存区域不同:前者存放在栈中,可以修改;后者存放在常量区,不可修改。

  3. 0xC0000005:安全点就是通过这个技术暂停所有线程的。

7、拷贝字符串strcpy

C语言 strcpy() 函数用于对字符串进行复制(拷贝)。

头文件:string.h

语法/原型:

char* strcpy(char* strDestination, const char* strSource);

参数说明:

  • strDestination:目的字符串。
  • strSource:源字符串。

strcpy() 会把 strSource 指向的字符串复制到 strDestination。

必须保证 strDestination 足够大,能够容纳下 strSource,否则会导致溢出错误。

返回值:目的字符串,也即 strDestination。

示例:

#include <string.h>

int main() {
  char dest[] = {0};
  char src[] = "Hello, Han Meimei!";

  strcpy(dest, src);

  printf("%s", dest);
  return 0;
}

8、连接字符串strcat

头文件:string.h
语法:

char* strcat(char* strDestination, const char* strSource);

参数说明:

  • strDestination:目的字符串;
  • strSource:源字符串。

strcat() 函数把 strSource 所指向的字符串追加到 strDestination 所指向的字符串的结尾,所以必须要保证 strDestination 有足够的内存空间来容纳两个字符串,否则会导致溢出错误。

注意:strDestination 末尾的\0会被覆盖,strSource 末尾的\0会一起被复制过去,最终的字符串只有一个\0。

返回值:指向 strDestination 的指针。

#include <string.h>

int main() {
  char dest[] = "Hello";
  char src[] = " World!";

  strcat(dest, src);

  printf("%s", dest);
  return 0;
}

8、比较字符串strcmp

C语言 strcmp() 函数用于对两个字符串的内容进行比较(区分大小写)。

头文件:string.h

语法/原型:

int strcmp(const char* stri1,const char* str2);
  • 参数 str1 和 str2 是参与比较的两个字符串。

strcmp() 会根据 ASCII 编码依次比较 str1 和 str2 的每一个字符,直到出现不到的字符,或者到达字符串末尾(遇见\0)。

返回值:

  • 如果返回值 < 0,则表示 str1 小于 str2。
  • 如果返回值 > 0,则表示 str2 小于 str1。
  • 如果返回值 = 0,则表示 str1 等于 str2。

示例:

#include <string.h>

int main() {
  char str1[] = {\'C\', \'h\', \'i\', \'n\', \'a\', \'\0\'};
  char* str2 = "China";

  int result = strcmp(str1, str2);
  printf("%d", result); // 输出结果为0
  return 0;
}

9、字符查找函数strchr

C语言 strchr() 函数用于查找给定字符串中某一个特定字符。

头文件:string.h

语法/原型:

char* strchr(const char* str, int c);

参数说明:

  • str:被查找的字符串。
  • c:要查找的字符。

strchr() 函数会依次检索字符串 str 中的每一个字符,直到遇见字符 c,或者到达字符串末尾(遇见\0)。

返回值:返回在字符串 str 中第一次出现字符 c 的位置,如果未找到该字符 c 则返回 NULL。

示例:

#include <string.h>

int main() {
  char str1[] = {\'C\', \'h\', \'i\', \'n\', \'a\', \'\0\'};
  printf("%p\n", str1);

  char* p1 = strchr(str1, \'b\');
  printf("%p\n", p1); // 输出结果为0,str1中不包含字符b

  char* p2 = strchr(str1, \'h\');
  printf("%p\n", p2); // 输出结果比 str1 的内存地址多一个字节
  return 0;
}

运行结果如下图所示:

10、查找子字符串strstr

C语言 strstr() 函数在字符串中查找子字符串。

语法/原型

char *strstr(const char *haystack, const char *needle)

参数说明:

  • haystack -- 要被检索的 C 字符串。
  • needle -- 在 haystack 字符串内要搜索的小字符串。

返回值
该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。

示例:

char haystack[20] = "RUNOOB";
char needle[10] = "NOOB";
 
char *ret = strstr(haystack, needle);
 
printf("子字符串是: %s\n", ret);
   
return 0;

运行结果:

参考文档

  1. Go to 《数组的长度,C语言获取数组长度详解》

分类:

技术点:

相关文章:

  • 2021-05-18
  • 2021-04-26
  • 2021-11-01
  • 2021-11-14
  • 2021-10-17
  • 2021-10-17
  • 2021-10-30
  • 2021-05-18
猜你喜欢
  • 2021-12-09
  • 2021-10-17
  • 2021-11-14
  • 2021-05-03
  • 2021-11-14
  • 2021-10-17
  • 2021-11-04
相关资源
相似解决方案