【C语言】字符与字符串

news2025/6/6 12:04:15

在 C 语言中,字符(Character) 和 字符串(String) 是两个不同但相关的概念。下面详细介绍它们的定义、存储方式和使用方法:

一、字符(Character)

1. 定义与存储
  • 基本类型char(1 字节,范围 - 128~127 或 0~255,取决于编译器)
  • 存储形式:单个字符用单引号 ' ' 包裹,实际存储为对应的 ASCII 码值
2. 示例代码
#include <stdio.h>

int main() {
    // 直接赋值(字符常量)
    char c1 = 'A';         // 存储ASCII码值65
    char c2 = 66;          // 等价于 char c2 = 'B';
    char newline = '\n';   // 转义字符:换行符
    
    // 输出字符和对应的ASCII值
    printf("c1: %c (ASCII %d)\n", c1, c1);  // 输出: A (ASCII 65)
    printf("c2: %c (ASCII %d)\n", c2, c2);  // 输出: B (ASCII 66)
    
    // 特殊字符(转义序列)
    char tab = '\t';       // 制表符
    char quote = '\"';     // 双引号字符
    
    return 0;
}
3. 关键注意点
  • 转义字符:使用反斜杠 \ 表示特殊字符,例如:
    '\n'  // 换行符
    '\t'  // 制表符
    '\0'  // 空字符(ASCII 0,字符串终止符)
    '\\'  // 反斜杠本身
    '\''  // 单引号
    '\"'  // 双引号
    
  • 字符与整数的关系char 本质是小整数,可参与算术运算:
    char c = 'A';
    printf("%d\n", c + 1);  // 输出66('A'的ASCII码是65)
    

二、字符串(String)

1. 定义与存储
  • 本质:由多个字符组成的数组,以空字符 '\0' 结尾
  • 两种定义方式
    • 字符数组char str[] = "Hello";
    • 字符指针char *str = "Hello";
2. 字符数组 vs 字符指针
字符数组字符指针
char str[] = "Hello";char *str = "Hello";
数据存储在栈内存数据存储在只读内存区
可修改内容(如 str[0]='J';不可修改内容(修改会导致运行时错误)
数组大小自动计算(含 '\0'指针指向常量字符串的首地址
3. 示例代码
#include <stdio.h>
#include <string.h>  // 字符串处理函数库

int main() {
    // 1. 字符数组方式(可修改)
    char str1[] = "Hello";  // 等价于 char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    printf("str1长度: %zu\n", strlen(str1));  // 输出5(不包含'\0')
    printf("str1大小: %zu\n", sizeof(str1));  // 输出6(包含'\0')
    
    // 修改字符数组内容
    str1[0] = 'J';
    printf("修改后: %s\n", str1);  // 输出 "Jello"
    
    // 2. 字符指针方式(指向常量字符串,不可修改)
    char *str2 = "World";
    // str2[0] = 'X';  // 错误!修改常量字符串会导致运行时错误
    
    // 3. 动态输入字符串(需确保缓冲区足够大)
    char input[100];
    printf("请输入字符串: ");
    scanf("%s", input);  // 注意:scanf遇到空格会截断
    printf("你输入的是: %s\n", input);
    
    // 4. 字符串处理函数示例
    char src[] = "Copy this";
    char dest[20];
    strcpy(dest, src);  // 复制字符串
    printf("复制结果: %s\n", dest);
    
    return 0;
}
误区 1:“指针指向的字符串不能修改,所以指针本身不能修改”
  • 错误:指针变量本身的值(即所指向的地址)可以修改,例如:
    char *str = "Hello";
    str = "World";  // 合法!指针重新指向另一个常量字符串
    

    但 不能通过指针修改其所指向的内存内容
误区 2:“用 char * 定义的字符串都不能修改”
  • 错误:如果 char* 指向的是 可写内存(如动态分配的内存或字符数组),则可以修改。例如:
    char arr[10] = "abc";
    char *ptr = arr;  // ptr指向栈上的数组(可写)
    ptr[0] = 'x';     // 合法,修改数组内容为 "xbc"
4. 字符串处理函数

常用的字符串操作函数(需包含 <string.h>):

函数名功能描述示例
strlen(s)返回字符串长度(不含 '\0'strlen("Hello") → 5
strcpy(dst, src)复制字符串 src 到 dststrcpy(dest, "Hi");
strcat(dst, src)将 src 追加到 dst 末尾strcat(dest, " World");
strcmp(s1, s2)比较 s1 和 s2(按字典序)strcmp("A", "B") → 负数
strchr(s, c)在 s 中查找字符 c 第一次出现的位置strchr("test", 'e') → 指向 e 的指针

三、字符与字符串的区别

特性字符 (char)字符串 (char[] 或 char*)
定义符号单引号 'A'双引号 "Hello"
存储内容单个字符的 ASCII 码值多个字符 + 终止符 '\0'
占用空间1 字节字符串长度 + 1 字节
示例char c = 'A';char s[] = "ABC"; 或 char *s = "ABC";

四、常见错误与注意事项

  1. 未初始化字符串

    未初始化指针直接使用

    char *ptr;
    strcpy(ptr, "test"); // 错误!ptr未指向有效内存
    // 修正:ptr = (char*)malloc(5); strcpy(ptr, "test");
  2. 字符串越界

    char str[3];
    strcpy(str, "ABCD");  // 错误!超出数组大小,导致缓冲区溢出
    
  3. 忘记字符串终止符

    char str[3] = {'A', 'B', 'C'};  // 错误!缺少'\0',不是有效字符串
    printf("%s", str);  // 可能输出乱码,直到遇到内存中的某个'\0'
    
  4. 混淆字符和字符串

    char c = "A";  // 错误!"A"是字符串(含'A'和'\0'),无法赋值给char
    char c = 'A';  // 正确
    

    补充:预分配内存的常用方法

    方法适用场景函数 / 语法示例
    栈内存数组长度固定、编译时已知char arr[size];char name[20];
    堆内存动态分配长度动态变化、运行时确定malloc()/calloc()int *ptr = (int*)malloc(n*sizeof(int));
    常量字符串只读场景,无需修改"Hello"char *str = "World";
    柔性数组结构体末尾的动态数组struct { int len; char data[]; }// C99特性,需动态分配结构体+数组

总结

  • 字符:单个字符用 char 类型表示,存储为 ASCII 码值,用单引号包裹。
  • 字符串:由字符数组组成,以 '\0' 结尾,用双引号定义。
  • 操作字符串:使用标准库函数(如 strlenstrcpy)处理字符串,避免手动操作终止符。
  • 安全性:确保缓冲区足够大,避免越界和未初始化内存的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2401626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

经典算法:回文链表

题目&#xff1a;234. 回文链表 给你一个单链表的头节点 head&#xff0c;请你判断该链表是否为 回文链表。如果是&#xff0c;返回 true&#xff1b;否则&#xff0c;返回 false。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#x…

uboot移植之GPIO上电初始状态的调整

开发板在上电之后&#xff0c;GPIO都有一个默认初始状态&#xff0c;这个状态可能是高电平也可能是低电平。而我们的应用程序在正式接管控制这些GPIO&#xff0c;是在内核起来并成功加载根文件系统之后。所以在内核启动的这段时间内&#xff0c;这些GPIO保持在一种不受控的状态…

本地id_rsa.pub输入到服务器~/.ssh/authorized_keys后,依然需要输入密码的解决办法

首先检查服务器&#xff1a; sudo vim /etc/ssh/sshd_config 然后把这两个修改为&#xff1a; 如果依然需要输入密码&#xff0c;在本地终端&#xff1a; ssh -v userserver 查看认证过程&#xff0c;例如我这里提示说明客户端已成功尝试使用密钥认证&#xff1a; 进一步…

【设计模式-3.7】结构型——组合模式

说明&#xff1a;本文介绍结构型设计模式之一的组合模式 定义 组合模式&#xff08;Composite Pattern&#xff09;又叫作整体-部分&#xff08;Part-Whole&#xff09;模式&#xff0c;它的宗旨是通过将单个对象&#xff08;叶子节点&#xff09;和组合对象&#xff08;树枝…

Unity Mac 笔记本操作入门

在 macOS 笔记本电脑上使用 Unity Editor 的场景视图 (Scene View) 旋转视角&#xff0c;主要依赖于触摸板手势和键盘修饰键的组合。由于没有物理中键&#xff0c;操作方式会与 Windows 鼠标略有不同。 以下是具体的旋转视角操作&#xff1a; 1. 基本旋转视角 (Orbit) 这是最…

实时数据仓库是什么?数据仓库设计怎么做?

目录 一、实时数据仓库是什么 &#xff08;一&#xff09;实时数据仓库的定义 &#xff08;二&#xff09;实时数据仓库的特点 二、实时数据仓库的应用场景 &#xff08;一&#xff09;金融行业 &#xff08;二&#xff09;电商行业 &#xff08;三&#xff09;物联网行…

Linux(12)——基础IO(下)

目录 六、重定向 &#x1f4c4;输出重定向 &#x1f4c4;输入重定向 &#x1f4c4;追加重定向 &#x1f4c4;dup2 七、理解一切皆文件 八、缓冲区 &#x1f9e0;什么是缓冲区 &#x1f9e0;为什么要引入缓冲区 &#x1f4c4;缓冲区类型 九、FILE 六、重定向 我们这…

WPF可拖拽ListView

1.控件描述 WPF实现一个ListView控件Item子项可删除也可拖拽排序&#xff0c;效果如下图所示 2.实现代码 配合 WrapPanel 实现水平自动换行&#xff0c;并开启拖拽 <ListViewx:Name"listView"Grid.Row"1"Width"300"AllowDrop"True&…

[蓝桥杯]倍数问题

倍数问题 题目描述 众所周知&#xff0c;小葱同学擅长计算&#xff0c;尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况&#xff0c;当有很多个数之后就会比较苦恼。现在小葱给了你 nn 个数&#xff0c;希望你从这 nn 个数中找到三个数&#xff0c;使得…

【MySQL】 约束

一、约束的定义 MySQL 约束是用于限制表中数据的规则&#xff0c;确保数据的 准确性 和 一致性 。约束可以在创建表时定义&#xff0c;也可以在表创建后通过修改表结构添加。 二、常见的约束类型 2.1 NOT NULL 非空约束 加了非空约束的列不能为 NULL 值&#xff0c;如果可以…

前端vue打开多个窗口,关闭窗口后才继续执行后续逻辑

1.打开第一个弹窗 弹窗的按钮代码 2.点击窗口1中按钮&#xff0c;打开新的窗口 // 请领单按钮点击 async cb_6_delClick() {let ls_yfbm this.st_3Value.BMBMlet pstring {}pstring.a ls_yfbmpstring.b this.queryFormDialog.outDepotDeptCodeawait this.openwithparm_w_md…

「深度拆解」Spring Boot如何用DeepSeek重构MCP通信层?从线程模型到分布式推理的架构进化

什么是MCP&#xff1f; MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是由Anthropic公司于2024年11月推出的开放标准协议&#xff0c;旨在为大型语言模型&#xff08;LLM&#xff09;与外部数据源、工具及系统提供统一的交互接口&#xff0c;被…

【西门子杯工业嵌入式-2-点亮一颗LED】

西门子杯工业嵌入式-2-点亮一颗LED 一、课程回顾与目标1.上节课内容回顾2.本节课目标 二、硬件连接与原理1. 硬件连接方式2. 连接实例 三、GPIO原理知识1. GPIO结构2. 推挽输出模式原理 四、软件实现步骤1. 项目结构设置2. 函数定义3. led.c 文件编写初始化函数 led_init交替闪…

代码随想录算法训练营第60期第五十五天打卡

大家好&#xff0c;我们今天继续我们图论的部分&#xff0c;其实我们昨天是主要讲解了深搜与广搜的理论基础&#xff0c;我们大体上了解了两种算法的差异与适用情景&#xff0c;今天我们就继续我们的图论的章节&#xff0c;以后几天的题目是图论中比较有名的问题叫做岛屿问题&a…

重磅更新! 基于Gemini 2.5 Pro打造的AI智能体PlantUML-X上线!

目录 图表绘制AI智能体PlantUML-X上线通过简单的提示词创建各种UML图&#xff1a;轻松搞定其它类型的技术图表&#xff1a; AI智能体PlantUML-X功能实测画一个在Java中的一个简单的用户登录功能的时序图效果展示&#xff1a;根据详细内容生成系统架构图效果展示&#xff1a;效果…

[5-02-04].第01节:Jmeter环境搭建:

JMeter笔记大纲 Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量 一、JMeter概述&#xff1a; 1.1.JMeter是什么&#xff1a; JMeter是Appache组织使用java开发的一款测试工具 可以用于对服务器、网络或对象模拟巨大的负载…

AI智能推荐实战之RunnableParallel并行链

导读&#xff1a;在现代AI应用开发中&#xff0c;如何高效处理多维度数据分析始终是开发者面临的核心挑战。当您需要同时进行情感分析、关键词提取和实体识别&#xff0c;或者要对比多个AI模型的输出结果时&#xff0c;传统的串行处理方式往往效率低下。 本文将深入解析LangCha…

Gemini开源项目DeepResearch:基于LangGraph的智能研究代理技术原理与实现

引言 在人工智能快速发展的今天&#xff0c;如何构建一个能够进行深度研究、自主学习和迭代优化的AI系统成为了技术前沿的重要课题。Gemini开源的DeepResearch一周收获7.9k Star&#xff0c;Google的开源项目Gemini DeepResearch技术通过结合LangGraph框架和Gemini大语言模型&…

Doris Catalog 联邦分析查询性能优化:从排查到优化的完整指南

在大数据分析中&#xff0c;Doris 的 Catalog 联邦分析功能为整合多源数据提供了有力支持。然而&#xff0c;在实际应用中&#xff0c;可能会遇到各种问题影响其正常运行。本文将详细剖析这些问题并提供解决方案。 一、联邦分析查询慢&#xff1a;内外表通用排查逻辑 当遇到 …

01 Deep learning神经网络的编程基础 二分类--吴恩达

二分类 1. 核心定义 二分类任务是监督学习中最基础的问题类型&#xff0c;其目标是将样本划分为两个互斥类别。设样本特征空间为 X ⊆ R n \mathcal{X} \subseteq \mathbb{R}^n X⊆Rn&#xff0c;输出空间为 Y { 0 , 1 } \mathcal{Y} \{0,1\} Y{0,1}&#xff0c;学习目标为…