C语言——字符串指针和字符串数组

目录

前言

一、定义区别

1、数组表示

2、指针表示

二、内存管理区别

1.字符数组

2.字符指针

三、操作区别

1、访问与修改

2、遍历

3......

总结



前言

在C语言中,字符串随处可见,字符串是由字符组成的一串数据,字符串以null字符('\0')结尾,表示字符串的结束。字符串可以通过字符数组或指针来表示和操作。使用指针可以更灵活地处理字符串,因为指针可以指向字符串的起始位置,并通过指针运算来访问字符串中的字符。虽然指针和数组都可以用来表示和操作字符串,但它们在内存管理和使用方式上有一些关键的区别,下面就来简单的理一下吧。


一、定义区别

1、数组表示

字符串数组是在编译时确定大小的一个字符数组。例如:

cpp 复制代码
char str[10] = "Hello";

这里str是一个包含10个字符的数组,其中前5个字符是'H', 'e', 'l', 'l', 'o',剩下的字符自动初始化为'\0'(字符串结束符)。

2、指针表示

字符串指针是通过字符指针来指向一个字符串常量(只读,不能修改)或动态分配的字符数组。例如:

cpp 复制代码
char *ptr = "Hello";

char *Str = (char *)malloc(50 * sizeof(char));  // 动态分配内存  
if (Str != NULL) 
{  
    strcpy(Str, "Hello");                       // 复制字符串到动态内存  
}

这里ptr是一个指向字符的指针,它指向一个字符串常量"Hello"。注意,字符串常量通常存储在只读的数据段中。

二、内存管理区别

1.字符数组

如果是局部变量:字符串的内存是在栈上分配的;

如果是全局变量或静态变量:字符串的内存是在数据段上分配的;

但无论是局部变量还是全局变量(静态变量),数组的大小在编译时就已经确定了,而且在数组的生命周期内大小固定,不可以改变。

2.字符指针

当字符指针指向一个字符串常量时,内存是由编译器管理的,不能修改这个字符串的内容(只读,存储在只读区)尝试修改会导致段错误,通常使程序崩溃。如果指针指向的是通过malloc、calloc或realloc动态分配的内存,此时可以修改这块内存的内容,并且需要在适当的时候释放它。

三、操作区别

由于数组的大小是固定的,不能改变数组大小(即不能通过数组重新分配内存来存储更长的字符串),但是,可以修改数组中的字符,只要不超过数组的边界。

而指针提供了更大的灵活性,可以让它指向不同的字符串(通过改变指针的值)。如果指针指向的是动态分配的内存,可以根据需要调整内存的大小。但不能修改指针指向的字符串内容

1、访问与修改

可以通过数组索引来访问和修改数组字符串中的字符。

cpp 复制代码
str[0] = 'h';  // 修改第一个字符为小写'h'  
char ch = str[7];  // 获取第八个字符,即将其赋给ch变量

指针指向字符串常量,则不能修改其内容。如果指向动态分配的内存,则可以修改。

cpp 复制代码
ptr[0] = 'h';    // 该操作是错误的,因为ptr指向的是只读内存

if (Str != NULL)
{  
    Str[0] = 'h';  // 修改动态字符串的第一个字符为小写'h'  
}

2、遍历

可以使用循环来遍历数组字符串中的每个字符。

cpp 复制代码
for (int i = 0; str[i] != '\0'; i++) 
{  
    printf("%c", str[i]);  
}

可以使用指针来遍历字符串。

cpp 复制代码
while (*ptr != '\0') 
{  
    printf("%c", *ptr);  
    ptr++;  
}  

if (Str != NULL) 
{  
    char *temp = Str;  
    while (*temp != '\0') 
    {  
        printf("%c", *temp);  
        temp++;  
    }  
}

3......


总结

1、当使用指针指向字符串常量时,不要尝试修改这个字符串的内容,因为字符串字面量通常存储在只读内存段中。

2、当使用动态内存分配时,确保在使用完毕后释放内存,以避免内存泄漏。

3、在修改指针指向的字符串之前,始终检查指针是否为NULL,以避免空指针解引用错误。

4、字符串数组的大小在编译时就确定了,因此不能改变数组大小。如果需要动态大小的字符串,应使用指针和动态内存分配。

相关推荐
li星野20 小时前
打工人日报#20251011
笔记·程序人生·fpga开发·学习方法
摇滚侠20 小时前
Spring Boot 3零基础教程,yml配置文件,笔记13
spring boot·redis·笔记
QT 小鲜肉20 小时前
【个人成长笔记】在Ubuntu中的Linux系统安装 anaconda 及其相关终端命令行
linux·笔记·深度学习·学习·ubuntu·学习方法
QT 小鲜肉20 小时前
【个人成长笔记】在Ubuntu中的Linux系统安装实验室WIFI驱动安装(Driver for Linux RTL8188GU)
linux·笔记·学习·ubuntu·学习方法
急急黄豆20 小时前
MADDPG学习笔记
笔记·学习
Chloeis Syntax21 小时前
栈和队列笔记2025-10-12
java·数据结构·笔记·
Vanranrr1 天前
nullptr vs NULL:C/C++ 空指针的演变史
c语言·c++
Sunsets_Red1 天前
差分操作正确性证明
java·c语言·c++·python·算法·c#
QZ_orz_freedom1 天前
学习笔记--文件上传
java·笔记·学习
摇滚侠1 天前
Spring Boot 3零基础教程,整合Redis,笔记12
spring boot·redis·笔记