字符串是有限个字符的有序集合,前面讲的char类型用于表示和存储单个字符,字符串相当于几个或多个char类型的有序集合,用于表示和存储多个有序的字符序列。字符串必须包含在一对“”(双引号)之内。例如:“I want to learn Java programming”、“我要学C编程”、“3+5=8”、“abc”等等。
字符串的定义和初始化
C语言没有给字符串类型定义一个关键字,用于声明字符串类型,而是通过字符数组的方式提供对字符串的操作和存储。字符数组也是数组,其声明方式与数值型数组相同。例如:下面声明一个包含10个字符元素的str。
char str[10];
声明字符数组后,字符数组str就可以像其它数组一样使用。C语言为字符数组提供了特殊的初始化方式,方便对字符串的操作。
char str[] = “Hello World”;
对数组每个元素赋值的的初始化方式也可以使用,需要注意的是字符数组的最后一个元素是转义符'\0',表示一个字符串的结束。
char str[]={'H','e','l','l','o','\0'};
字符数组的最后一个元素必须是转义符'\0',该转义符为字符串的结束符号。
printf()函数提供格式化符“%s”可以输出一个字符串,和“%s”匹配的是字符数组变量,并且字符数组的最后一个元素必须是转义符'\0'。
使用scanf()函数可以从终端接收用户输入的字符串,格式化输入符为“%s”,接收的数据类型为字符数组,声明的字符数组长度必须且至少要比用户输入的字符个数多1,因为字符数组还需要容纳字符串的结束符。
char str[20];
scanf("%s",str);
在上述代码中,用户输入的字符串长度(即用户输入的字符个数)不能大于19,否则程序会报错。
例1 字符串输入与输出练习
程序清单 sample.c
#include <stdio.h>
void main()
{
/*
声明字符数组str,用于接收用户输入的字符串
用户输入的字符个数不能大于str的长度
*/
char str[30];
// str接收用户输入的字符串
scanf("%s",str);
// 输出字符串
printf("%s",str);
}
字符串指针
在C语言中,存储字符串的方式有两种:字符数组和字符指针。前面已经掌握了使用字符数组来存储字符串,下面学习如何使用字符指针来存储字符串。
用字符指针指向一个字符串,可以不用声明一个字符数组,而是声明一个字符指针,用字符指针指向字符串中的字符。例如:
void main()
{
char* pstr = "Hello World";
printf("%s",pstr);
}
在上面的代码中,没有声明一个字符数组,而是在程序中声明了一个字符指针变量pstr,用字符串常量"Hello World",对它进行初始化。C语言对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组用来存放该字符串常量。对字符指针变量初始化,实际上是把字符串第1个元素的地址(即存放字符串的字符数组的首元素地址)赋给pstr。
字符指针指向字符串后,字符串的值不能被修改,但可以通过索引访问字符串的单个字符,也可以访问整个字符串,并适用于所有的字符串处理函数。
字符串指针应用案例
字符串复制
使用字符串指针可以实现字符串的复制。下面是一段字符串复制案例代码:
#include <stdio.h>
void string_copy(char *dest, const char *src) {
while (*src != '\0') {
*dest = *src;
dest++;
src++;
}
*dest = '\0'; // 添加字符串结束符
}
int main() {
char src[] = "Hello, World!";
char dest[20];
string_copy(dest, src);
printf("Copied string: %s\n", dest);
return 0;
}
字符串拼接
字符串指针也可以用于字符串的拼接。下面是一段字符串拼接案例代码:
#include <stdio.h>
void string_concatenate(char *dest, const char *src) {
while (*dest != '\0') {
dest++;
}
while (*src != '\0') {
*dest = *src;
dest++;
src++;
}
*dest = '\0'; // 添加字符串结束符
}
int main() {
char str1[] = "Hello, ";
char str2[] = "World!";
char result[50];
strcpy(result, str1);
string_concatenate(result, str2);
printf("Concatenated string: %s\n", result);
return 0;
}
字符串查找
字符串指针可以用于实现字符串的查找功能。下面是一个简单的函数,用于查找一个子字符串在另一个字符串中的位置:
#include <stdio.h>
int string_search(const char *str, const char *substr) {
while (*str != '\0') {
const char *p = str;
const char *q = substr;
while (*p != '\0' && *q != '\0' && (*p == *q)) {
p++;
q++;
}
if (*q == '\0') {
return str - str; // 返回子字符串在原始字符串中的位置
}
str++;
}
return -1; // 未找到子字符串
}
int main() {
char str[] = "Hello, World!";
char substr[] = "World";
int position = string_search(str, substr);
if (position != -1) {
printf("Substring found at position: %d\n", position);
} else {
printf("Substring not found\n");
}
return 0;
}
字符串指针使用小结
字符串指针是进行字符串操作的重要工具,字符串指针就是指向字符串首字符的指针。在使用字符串指针时,需要注意以下几个方面:
字符串的存储方式
在C语言中,字符串通常以字符数组的形式存储。字符数组中的每个元素都是一个字符,字符串的结束由空字符('\0')标识。字符串指针就是指向这个字符数组首元素的指针。
初始化字符串指针
在声明字符串指针后,需要将其初始化为指向某个字符串的首字符。例如:
char *str = "Hello, world!";
这里,str 是一个指向字符串 "Hello, world!" 的指针。注意,这个字符串是存储在程序的只读内存段中的,因此不应该尝试修改它的内容。
字符串指针的赋值
可以将一个字符串指针赋值为另一个字符串指针的值,或者指向另一个字符串的首字符。例如:
char *str1 = "Hello";
char *str2 = str1; // str2 现在也指向 "Hello"
或者
char *str1 = "Hello";
char str2[] = "World";
str1 = str2; // 现在 str1 指向 "World"
字符串指针的运算
可以对字符串指针进行加减运算,以移动指针到字符串中的其他位置。需要注意的是,加减运算的结果应该是有效的内存地址。例如:
char *str = "Hello";
str++; // 现在 str 指向 "ello"
字符串指针与字符串数组
字符串指针和字符串数组在用法上有很多相似之处,但也有一些重要的区别。例如,字符串数组的名字就是一个指向其首元素的指针,但它不能被修改以指向其他字符串。而字符串指针则可以被修改以指向不同的字符串。
字符串指针的结束
C语言中的字符串是以空字符('\0')结尾的。因此,在遍历或处理字符串时,需要注意检查空字符以确定字符串的结束位置。
内存分配
当使用字符串指针指向动态分配的内存时,需要特别注意内存的管理。使用 malloc 或 calloc 等函数分配内存后,需要在使用完字符串后使用 free 函数释放内存,以避免内存泄漏。
例如:
char *str = malloc(100); // 分配 100 个字符的内存
if (str == NULL) {
// 处理内存分配失败的情况
}
strcpy(str, "Hello, world!"); // 将字符串复制到分配的内存中
// ... 使用字符串 ...
free(str); // 释放内存
使用C语言中的字符串指针时,需要注意字符串的存储方式、指针的初始化和赋值、指针的运算、与字符串数组的区别、字符串的结束、以及内存管理等方面的问题。