11.1表示字符串和字符串I/O
11.1表示字符串和字符串I/O
第4章介绍过,字符串是以空字符(\0)结尾的char类型数组。因此,可以把上一章学到的数组和指针的知识应用于字符串。不过,由于字符串十分常用,所以C提供了许多专门用于处理字符串的函数。本章将讨论字符串的性质、如何声明并初始化字符串、如何在程序中输入和输出字符串,以及如何操控字符串。程序清单11.1演示了在程序中表示字符串的几种方式。
程序清单11.1strings1.c程序
strings1.c
#include<studio.h>
#define MSG"I am a symbolic string constant."
#define MAXLENGTH 81
int main(void)
char words(MAXLENGTH]="I am a string in an array.";
const char*pt1="Something is pointing at me.";
puts("Here are some strings:");
puts(MSG);
puts(words);
puts(pt1);
words[8]=-p';
puts(words);
return 0;
}
和printf()函数一样,puts()函数也属于stdio.h系列的输入/输出函数。但是,与printf()不同的是,puts()函数只显示字符串,而且自动在显示的字符串末尾加上换行符。下面是该程序的输出:
Here are some strings:
I am a symbolic string constant.
I am a string in an array. Something is pointing at me.
I am a spring in an array.
1. 字符串常量
C语言没有字符串类型,但是存在字符串这个概念,也就是字符串常量.
Q1:字符串常量是什么?
A1:跟整型常量其实是一回事,如果我们定义一个整型常量,那么在程序运行过程中,这个整型常量是不能再修改的.
示例:
#include <stdio.h> int main(void) { const int i = 3; i = 6; // error, 常量i不能修改,只能读取 return 0; }
字符串常量亦是如此,一旦定义并且赋值就不能再更改.
Q2:字符串常量怎么来表示呢?
A2:用双引号括""起来的字符,比如:
"H"
"Hello World!"
""
在C语言中,字符串比较特殊,都是以'\0'进行结尾.
"H",实际是“H\0”
"Hello World!",实际是"Hello World!\0"
空字符串"",在C语言里,实际是"\0"
至于在C语言中,字符串为什么以'\0'结尾?
因为C语言中,没有专门用来表示字符串的变量,'\0'作为字符串结束的标志,我们就可以知道字符串在哪里结束.
2. 指针
我们在定义字符串常量时,实际上返回的是这个字符串常量的地址,而指针变量就是存储地址的变量,所以我们可以通过指针来表示字符串常量.
2.1 指针表示字符串常量
/* 功能: 指针表示字符串 */ #include <stdio.h>
int main(void) {
const char * str = "I love China!"; // 等号右边"I love China!"实际上是字符串第一个字符的地址,将这个地址赋给了指针变量str // *str = 'w'; // error, 字符串常量不可修改
printf("%c\n", *str);
printf("%s\n", str);
while (*str != '\0') {
printf("%c", *str); str++; }
return 0; } /* 在DEV C++输出结果是: -------------------- I I love China! I love China! -------------------- */
注1:字符串常量出现在表达式中,代表的值为该字符串常量的第一个字符的地址
注2:字符串"I love China!"是存储在常量内存区域,不能进行修改,由指针变量指向,可以读取.
2.2 字符数组
我们知道,数组是一种复合类型,为解决大量同类型数据而存在,字符串由单个字符构成,所以也可以用字符数组来表示字符串.
与指针不同,字符数组表示字符串时,可以对字符串进行修改,因为用字符数组表示字符串时,字符串是保存在栈空间中,数组名指向这段栈空间的首地址.
示例1:字符串的表示、长度、输出
/* 功能: 字符数组表示字符串 */ #include <stdio.h>
int main(void) {
char s[] = "Hello World!";
int i = 0;
printf("%d\n", sizeof(s)); // 输出13,字符串结尾标识符'\0'也算字符串长度 // 字符串第一种输出方式
while (*(s+i) != '\0') {
printf("%c", *(s+i)); i++; }
printf("\n");
// 字符串第二种输出方式 printf("%s\n", s); // 字符串第三种输出方式,puts函数包含在stdio.h头文件里 puts(s); // while (*s != '\0') // {
// printf("%c", *s); // s++; // error, s是字符数组的第一个元素的首地址(常量),不能修改 // } return 0; } /*
在DEV C++ 输出结果: ------------------ 13 Hello World! Hello World! Hello World! ------------------ */
示例2:修改字符数组
修改字符数组 */ #include <stdio.h> int main(void) { char s[] = "hello world"; int i = 0; while (*(s+i) != '\0') { if (*(s+i) >= 'a' && *(s+i) <= 'z') { *(s+i) = *(s+i) - 32; // 小写变大写 } i++; } puts(s); return 0; }
注:用指针变量表示的字符串之所以不可修改,因为指针变量所指向的字符串存储在内存常量区,而分配给数组的内存为栈空间,对这段栈空间里的内容可以进行修改.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通