表示字符串和字符串I/O
字符串是以空字符(\0)结尾的char类型数组。因此,可以将数组与指针的知识应用于字符串。不过,字符串非常常用,所以有提前写好的处理字符串的函数。本章将讨论字符串的性质、如何声明字符串、如何输入输出字符串、如何操控。
可能注意到,上图中代码,用的puts()函数来输出字符串:puts函数只能显示字符串,并在末尾加上换行符
一、在程序中定义字符串
1、字符串字面量(字符串常量)
用双括号括起来的内容称为字符串字面量(string literal),也叫做字符串常量(string constant)。双引号中的字符和编译器自动加入的\0字符,都作为字符串存储在内存中,从ANSI C标准起,如果字符串字面量之间没有间隔,或者空白字符分隔,C会将其视为串联起来的字符串字面量。列如:
如果在字符串内使用双引号,要在双引号前加上反斜杠(\):
字符串常量属于静态存储类别(static storage class),说明如果在函数中使用字符串常量,该字符串只会被存储一次,在整个程序的生命周期内存在。用双引号括起来的内容被视为指向该字符串存储位置的指针,这类似于把数组名作为指向该数组位置的指针。如果确实如此,下面代码会输出什么呢?
printf()根据%s打印字符串,根据%p打印地址。因此,如果“are”代表一个地址,printf()将打印该字符串的首地址,最后*"space farers"表示该字符串所指向地址的值,应该是该字符串的首字符。输出如下
显然之前的思路是对的
2、字符串数组和初始化
定义字符串数组时,必须让编译器知道需要多少空间。一种是用足够空间数组去存储:
const表示该字符串不可变,编译器会自动在末尾加上“\0”空字符。
在指定数组大小时,要确保数组的元素个数至少比字符串长度多1,所有未被使用的元素都被自动初始化为空字符,也可以让编译器自己计算数组大小:通过查找字符串末尾的空字符确定字符串在何时结束。让编译器计算数组大小只能用在初始化数组时 ,如果创建一个稍后再填充的数组,就必须在声明时指定大小。数组大小必须是整数。在变长数组前,数组的大小必须是整型常量,包括由整型常量组成的表达式。
字符数组名和其他数组名一样,是该数组首元素的地址:
还可以使用指针表示法创建字符串。
3、数组和指针
数组和指针有何不同?以上面为列子,数组形式(char ar1[])在计算机的内存中分配为一个内含20个元素的数组。通常字符串都作为可执行文件的一部分存储在数据段中。当程序载入内存时也载入看字符串。字符串存储在静态存储区中。但是程序运行时才会为该数组分配内存,此时才将字符串拷贝到数组中(之后详讲),这时候一个字符串有两个副本,一个在静态存储区中,一个在数组中。此后,编译器便把数组名ar1识别为该数组首元素地址(&ar1[0]的别名),在数组形式中,ar1不能被修改,因为它代表数组的在内存中的位置,改变它就等于修改了数组的地址,允许内存ar1+1的操作:标识数组的下一位元素;++ar1则不允许,递增运算符只能用于可修改的左值(即变量),不能用于常量。
指针形式(*pt1)也使得编译器为字符串在静态存储区中预留20个元素的空间。程序开始执行时,也会为指针变量pt1留下一个存储位置,并把字符串的地址赋值给指针变量,该变量最初指向该字符串的首地址,但是它的值可以改变,可以使用递增运算符。列如++pt1将指向第二个字符
字符串被视为const类型,不可修改,所以指针不能修改他所指向的字符串。但如果把字符串赋值给一般类型数组,则可以通过数组修改字符串,除非数组也为const类型。
数组形式将静态存储区中的数据赋值进数组中;指针形式将字符串的地址拷贝给指针变量。
4、数组和指针的区别
数组名是常量,指针名是变量,首先,它们都可以使用数组表示法:
其次,两者都能进行指针加法操作:
但是只有指针可以进行递增操作:
可以让指针指向数组,但不能用数组存储指针(非法构造),类似于x = 3, 3 = x;的情况。赋值运算法的左侧必须是变量。
如果打算修改字符串,就不要用指针指向字符串字面量。
5、字符串数组
看上去,指针数组mytakents和字符串数组yourtalents非常相似,两者都代表5个字符串。使用下标时都分别表示一个字符串,而且初始化方式也相同。
但是,也有区别。mytakents是一个包含5个指针的数组,在我们的系统中共计占用40个字节;yourtalents是一个包含5个数组的数组,每个数组内含40个char类型值,共占用200个字节。表示两者类型不同。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具