前言
C 语言中的字符和字符串是常用的数据类型。字符是一个单个的字母、数字、标点符号或者其他可打印的符号,使用单引号 ’ ’ 表示,例如:‘A’、‘0’、‘+’ 等。C 语言使用 ASCII 码表示字符,每个字符都有一个整数值和一个字符表示。
字符串是字符数组或指针,表示一个或多个字符的序列。字符串使用双引号 " " 表示,例如:“hello”、“world” 等。字符串的最后一个字符是 ‘\0’,表示字符串的结尾。
一、字符介绍和使用
在计算机编程语言中,字符表示单个字符,如字母、数字或标点符号等,用于表示文本信息和各种类型的数据。在C语言中,字符使用单引号(’ ')表示。例如,单引号中的字符‘a’、‘A’、‘0’都是字符。
字符变量和字符常量是计算机程序中常用的C字符处理机制。变量通常存储一个或多个字符的系列。常量是字符的固定值,不能被修改。字符常量可以存在程序中或通过用户输入设置,然后被分配给字符变量。字符数组也是一种常见的字符处理机制,由多个字符变量组成。
以下是一些C语言中字符的示例代码:
#include <stdio.h> int main() { char c = 'A'; // 定义一个字符变量 printf("The character is %c\n", c); // 输出字符 char ch = getchar(); // 获取从键盘输入的字符 printf("The character entered is %c\n", ch); return 0; }
运行结果:
以上代码演示了如何定义一个字符变量和如何使用 getchar() 函数从用户输入中获取字符。 getchar() 函数从键盘读取一个字符,用户需要输入字母或其他可显示字符,然后按下回车键。在以上示例中,用户输入的字符将存储在变量 ch 中,并打印出来。
二、字符串介绍和使用
字符串是字符序列,是C语言中非常重要的一种数据类型。字符串中的字符使用空字符(‘\0’)作为结尾。与字符不同,字符串是必须使用双引号(" ")来表示。在C语言中,我们通常用字符指针或字符数组来表示字符串。
在C语言中没有提供内置的字符串类型,但提供了一些便于处理字符串的函数(如strlen()、strcpy()等),此外我们一般使用字符数组或字符指针来模拟字符串。
下面是一个C语言中使用字符数组或字符指针来模拟字符串的示例代码:
#include <stdio.h> #include <string.h> int main(){ char str1[] = {'h', 'e', 'l', 'l', 'o', '\0'}; // 声明字符数组 char str2[] = "world"; // 另一种声明字符数组的方法 printf("The strings are %s and %s\n", str1, str2); char* ptr = "hello world"; // 声明字符指针 printf("The string is %s\n", ptr); char str3[20] = "hello"; char str4[20]; strcpy(str4, str3); // 将 str3 的内容复制到 str4 printf("The new string is %s\n", str4); char str5[20] = "hello"; char str6[20] = "world"; strcat(str5, str6); // 将 str6 的内容附加到 str5 后面 printf("The result string is %s\n", str5); char str7[20] = "hello"; printf("The length of string is %d\n", strlen(str7)); // 获取字符串长度 return 0; }
以上代码演示了如何声明字符数组和字符指针来表示字符串,以及如何使用字符数组和指针来实现字符串操作,包括将两个字符串合并、复制、获取字符串长度等等。
指针在字符串中的使用十分广泛,在字符串操作中,常需要指向字符串常量或字符串数组的指针,可以通过字符指针和字符数组的相互转换来方便地完成操作。
以下是一个使用字符指针和字符数组指向字符串的示例代码:
#include <stdio.h> #include <string.h> int main(){ char* ptr = "hello world"; // 声明字符指针 char arr[] = "world"; printf("%s\n", ptr); printf("%s\n", arr); int len1 = strlen(ptr); // 获取 ptr 指向的字符串的长度 int len2 = strlen(arr); // 获取 arr 指向的字符串的长度 printf("The length of string is %d\n", len1); printf("The length of string is %d\n", len2); char* p = arr; // 声明字符指针p,指针指向到字符数组arr printf("%c\n", *(p + 1)); // 输出字符数组第二个字符 return 0; }
以上代码演示了如何使用字符指针和字符数组指向字符串,包括获取字符指针所指向的字符串的长度、输出字符数组中的单个字符。
总而言之,字符串是C语言中非常重要的数据类型,C语言没有内置的字符串类型,但是提供了许多字符串处理函数(如strlen()、strcpy()、strcat()等),简化了操作。C语言中常使用字符数组或字符指针来表示字符串,并通过指针的运用来完成对字符串的操作。
三、字符串操作函数
在C语言中,许多字符串操作函数都有_s版本和普通版本的实现。_s版本在一些函数中出现是为了解决常见的缓冲区溢出漏洞,比如strcpy()和sprintf()等函数,这些函数在处理字符串时没有检查缓冲区的边界,导致可能会发生缓冲区溢出漏洞,从而造成安全漏洞。
_s版本的函数增加了一个额外参数(通常称为边界参数),用于指定目标缓冲区的长度,从而避免了缓冲区溢出的问题。例如,strcpy_s()函数的原型如下:
errno_t strcpy_s(char *dest, rsize_t destsz, const char *src);
在此原型中,dest参数是目标字符数组的首地址,destsz参数是dest数组的大小,src参数是要复制的源字符串的首地址。因此,当复制源字符串时,该函数将检查目标缓冲区是否可以容纳整个源字符串,如果destsz小于源字符串的长度,strcpy_s()将返回一个错误码,并且不会将源字符串复制到目标缓冲区中。
下面是一个演示S函数和普通函数使用的示例代码:
#include <stdio.h> #include <string.h> int main(){ char dest[10]; char* src = "Hello, World!"; strcpy(dest, src); printf("%s\n", dest); // 输出 Hello, Worl char dest_s[10]; char* src_s = "Hello, World!"; strcpy_s(dest_s, 10, src_s); printf("%s\n", dest_s); // 输出 Hello, Wo return 0; }
以上代码演示了strcpy()和strcpy_s()两个函数的使用。在第一个strcpy()中,源字符串的长度大于dest数组的大小,这将导致缓冲区溢出,并且复制的字符串被截断。在第二个strcpy_s()中,由于指定了destsz,因此在字符串复制之前,将检查dest数组的大小是否足以容纳整个源字符串。在执行复制操作之前,由于目标数组太小,strcpy_s()返回了一个错误码。
总而言之,S版本字符串操作函数在一些操作中提高了安全性,通过传递边界参数来检查缓冲区大小,从而避免缓冲区溢出和其他安全漏洞。但使用_s版本的函数需要仔细检查其特定用途,并确保正确使用参数以避免缓冲区溢出和其他安全漏洞的问题。
四、字符串的长度和字符串所占内存空间的大小
字符串是一个以null字符(‘\0’)结尾的字符数组。由于字符串以null字符结尾,因此可以通过null字符来确定字符串的长度。可以使用标准库函数strlen()来计算字符串的长度,该函数返回从字符串的起始位置开始到null字符之前的字符数。例如,下面的代码计算字符串"Hello, World!"的长度并输出:
#include <stdio.h> #include <string.h> int main() { char str[] = "Hello, World!"; printf("Length of the string is: %zu\n", strlen(str)); //输出长度为13 return 0; }
另一方面,字符串所占的内存空间的大小取决于该字符串的长度。当一个字符串被存储在内存中时,它实际上是被存储为一个char类型的数组。由于每个char类型在内存中占用1个字节的空间,因此一个包含n个字符的字符串在内存中占用的空间大小为n+1个字节,其中一个字节用于储存null字符的终止符。
例如,下面的代码演示了一个用字符串字面量创建的字符串所占用的内存空间大小:
#include <stdio.h> int main() { char str[] = "Hello, World!"; printf("Memory space used by the string: %zu bytes\n", sizeof(str)); // 输出内存占用14 bytes return 0; }
由于这个字符串包含的字符数是13个,再加上一个null字符结尾,因此其占用的内存大小为14个字节。
需要注意的是,当C语言编译器处理字符串字面量时,它会自动向字符串的末尾添加一个null字符,以确保该字符串是以null字符结尾的。因此,在使用字符串字面量初始化一个字符串时,不需要显式地添加null字符。
总结
本篇文章就讲解到这里字符串在C语言中是非常重要的,需要大家细心的去学习,并且多加练习。