C语言字符及字符串讲解

news/2025/1/13 2:28:54/

文章目录

  • 前言
  • 一、字符介绍和使用
  • 二、字符串介绍和使用
  • 三、字符串操作函数
  • 四、字符串的长度和字符串所占内存空间的大小
  • 总结


前言

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 的内容复制到 str4printf("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,指针指向到字符数组arrprintf("%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, Worlchar dest_s[10];char* src_s = "Hello, World!";strcpy_s(dest_s, 10, src_s);printf("%s\n", dest_s); // 输出 Hello, Woreturn 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)); //输出长度为13return 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 bytesreturn 0;
}

由于这个字符串包含的字符数是13个,再加上一个null字符结尾,因此其占用的内存大小为14个字节。

需要注意的是,当C语言编译器处理字符串字面量时,它会自动向字符串的末尾添加一个null字符,以确保该字符串是以null字符结尾的。因此,在使用字符串字面量初始化一个字符串时,不需要显式地添加null字符。

总结

本篇文章就讲解到这里字符串在C语言中是非常重要的,需要大家细心的去学习,并且多加练习。


http://www.ppmy.cn/news/293642.html

相关文章

从零手写操作系统之RVOS系统调用实现-09

从零手写操作系统之RVOS系统调用实现-09 系统模式&#xff1a;用户态和内核态如何让任务运行在用户态下 系统模式的切换用户模式下访问特权指令测试系统调用系统调用执行流程系统调用传参规范系统调用封装 系统调用完整流程解析执行测试 本系列参考: 学习开发一个RISC-V上的操作…

Jetpack Compose:使用PagerIndicator和Infinity实现滚动的HorizontalPager

Jetpack Compose&#xff1a;使用PagerIndicator和Infinity实现滚动的HorizontalPager 可能你已经知道&#xff0c;Jetpack Compose 默认不包含内置的ViewPager组件。然而&#xff0c;我们可以通过在 build.gradle 文件中添加 accompanist 库依赖&#xff0c;将 ViewPager 功能…

【JavaEE】网络编程之TCP套接字

目录 1、TCP套接字 1.1、ServerSocket 常用API 1.2、Socket 常用API 2、基于TCP套接字实现一个TCP回显服务器 2.1、服务器端代码 2.2、客户端代码 2.3、解决服务器不能同时和多个客户端建立链接的问题 3、基于TCP socket 写一个简单的单词翻译服务器 1、TCP套接字 T…

浅谈 UUID 生成原理及优缺点

UUID 是一套用于生成全局唯一标识符的标准&#xff0c;也被称为 GUID &#xff08;Globally Unique Identifier&#xff09;&#xff0c;通过使用 UUID 可以在分布式系统中生成唯一的 ID。UUID 的生成方式有多种&#xff0c;本文将详细讲解 UUID 的生成原理、特性、实用场景以及…

Android壳程序实现方式对比

vs. 原生开发、纯H5&#xff08;依赖浏览器&#xff09;、浏览器壳程序&#xff08;混合应用的方式&#xff09; 本篇指的是最后一种 Android手机壳程序&#xff0c;用系统WebView 和 内嵌Chromium 实现方式的对比使用系统WebView内嵌ChromiumFirefox的引擎 - GeckoView 组件说…

联发科MT76x8使用1-芯片对比

上面是我创建的群聊&#xff0c;欢迎新朋友的加入。 最近新到手一个MT-76X8的板子&#xff0c;盖了个铁壳壳&#xff0c;丝印上写的是MT-7628. 学习一下。 特意对比了MT-7628和MT-7688 对比了一下&#xff0c;没什么太大区别 官方资源路径 https://docs.labs.mediatek.com…

MT7688详细芯片资料下载  MT7688规格说明简介

MT7688详细芯片资料下载 MT7688规格说明简介 今天给大家分享MT7688芯片资料的相关问题&#xff0c;具体资料到闯客网技术论坛下载&#xff0c;也可以加群解决&#xff1a;813238832 或者资料链接&#xff1a;https://bbs.usoftchina.com/ Q: 联发科 MT7688AN是什么? ? 联发…

MT7687芯片资料MT7687原理图资料

MT7687是一种高度集成的单片芯片&#xff0c;提供应用程序处理器、低功率1t1r 802.11b/g/n wi-fi、子系统和电源管理单元。应用程序处理器子系统包含一个带有浮点单元的臂Cortex-m4。它还支持一系列接口&#xff0c;包括uart&#xff0c;i2c&#xff0c;spi&#xff0c;i2s&…