C语言字符及字符串讲解

简介: C语言字符及字符串讲解

前言

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语言中是非常重要的,需要大家细心的去学习,并且多加练习。


相关文章
|
25天前
|
存储 算法 C语言
【C语言】字符常量详解
字符常量是C语言中处理字符数据的重要工具。通过单引号括起一个字符,我们可以方便地使用字符常量进行字符判断、字符运算和字符串处理等操作。理解字符常量的表示方法、使用场景和ASCII码对应关系,对于编写高效的C语言程序至关重要。
110 11
|
25天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
49 10
|
25天前
|
存储 C语言 开发者
【C语言】格式化输出占位符及其标志字符详解(基于ISO/IEC 9899:2024)
在C语言中,格式化输出通过 `printf` 函数等格式化输出函数来实现。格式说明符(占位符)定义了数据的输出方式,标准ISO/IEC 9899:2024(C23)对这些格式说明符进行了详细规定。本文将详细讲解格式说明符的组成部分,包括标志字符、宽度、精度、长度修饰符和类型字符,并适当增加表格说明。
41 6
|
28天前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
88 4
|
2月前
|
C语言
C语言字符(串)函数
C语言字符(串)函数
|
2月前
|
C语言 C++
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
|
2月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
3月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
113 8
|
3月前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
235 7
|
2月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲