一.概念
字符串在C语言中是由一系列连续的字符组成,以空字符'\0'作为结束标志的字符序列。C语言本身并不直接支持字符串类型,而是通过字符数组或字符指针来处理字符串。
二.区别字符数组与字符指针
1.字符数组:
字符数组是一个固定的内存区域,用来存储一组连续的字符,数组的名字实际上就是这个内存区域的首地址。
2.字符指针:
1)字符指针变量存储的是一个内存地址,这个地址指向的是一个字符或字符串的首字符。
2)字符指针可以指向 1> 字符串常量、 2>字符数组、 3> 动态分配的内存块 等。
-
1>局部静态分配的字符数组: 当字符数组是在函数内部声明且没有使用
static
关键字时,它存储在栈(stack)上,这是种自动存储区域,生命周期随着函数调用的结束而结束。1 void foo() 2{ 3 char str[100] = "Hello, World!"; 4}
在这个例子中,
str
数组存储在栈上,不是静态存储区。 -
2>全局或静态局部字符数组: 当字符数组是在文件作用域(全局作用域)声明,或者在函数内部声明时使用了
static
关键字,那么数组存储在静态存储区。1 // 全局字符数组 2 char globalStr[100] = "Hello, World!"; 3 4 void bar() { 5 static char localStr[100] = "Hello, World!"; 6 }
在这两个例子中,
globalStr
和localStr
都在静态存储区,它们的生命周期从程序开始执行持续到程序结束。 -
3>动态分配的字符数组: 当使用
malloc
、calloc
或realloc
等函数动态分配字符数组时,数组存储在堆(heap)上,这也是动态存储区域,其生命周期由程序员管理,必须通过free
函数手动释放。1 char* dynStr = (char*)malloc(100 * sizeof(char)); 2 strcpy(dynStr, "Hello, World!"); 3 free(dynStr);
三.赋值
1.字符数组存储字符串:
char str1[10] = "Hello"; // C语言会自动在字符串末尾添加'\0'
(自定义字符数组(例如局部变量或全局变量)存储在栈区或静态存储区,取决于数组是否是静 态声明的。)
2.字符指针指向字符串:
char *str2 = "World"; // 字符串常量存储在静态存储区,str2指向该区域
(静态存储区:对于字符串常量,存储空间是只读的,旨在保护程序中的文本数据不被意外修改,确保程序的稳定性和安全性。)
3.动态分配内存存储字符串:
可以通过标准输入(如scanf
)或字符串拷贝函数(如strcpy
、strncpy
等)来输入赋值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// 动态分配内存
char *str = (char*)malloc(BUFFER_SIZE * sizeof(char)); // 假设BUFFER_SIZE是一个足够大的常数
if (str == NULL) {
printf("Memory allocation failed.\n");
return 1;
}
// 从标准输入读取字符串并赋值
printf("Enter a string: ");
fgets(str, BUFFER_SIZE, stdin); // 使用fgets读取一行,包括换行符
// 或者使用scanf读取字符串,但不安全,不处理长字符串或包含空格的情况
// scanf("%s", str);
// 去掉fgets带来的换行符(如果不需要保留换行符的话)
str[strlen(str) - 1] = '\0'; // 如果最后一个字符是换行符,替换成结束符'\0'
// 打印输入的字符串
printf("The entered string is: %s\n", str);
// 使用完毕后释放内存
free(str);
str = NULL;
return 0;
}
4.字符串常量(PRAISE)
使用#define定义字符串常量。
例如:
#define PRAISE "You are excellent."