char*、char[]傻傻分不清?一文详解C++字符串指针与数组的区别
char*、char[]傻傻分不清?一文详解C++字符串指针与数组的区别
在C++编程中,char*和char[]是表示字符串的两种常见方式,但它们之间存在一些重要的区别。本文将详细讲解这两种类型的特点、使用场景以及如何安全地操作字符串,帮助读者更好地理解它们之间的差异。
在C++中,C风格的字符串通常使用
char*
或
char[]
来表示。头文件:#include
一、char*
1、定义与初始化
①指向字符串字面量:
字符串字面量是只读的,通常用const char*来指向它。
注意:const char是常量指针(指针指向可以改,指针指向的值不可以更改),str[0]='h';//error字符串字面量存储在程序的*只读内存区域(通常是
.rodata
段)的常量,只读性是由编译器和操作系统共同保证的,而不是由
const char*
决定的。
使用
const char*
可以明确语义,并让编译器帮助检查潜在的错误。
②动态分配内存:
可以使用new或malloc动态分配内存,然后用char*指向这块内存。记得释放!!!
char*
指向动态分配的内存或可修改的数组,则可以修改字符串内容。例如:
char* str = new char[10]; strcpy(str, "Hello"); str[0] = 'h';
是合法的。
③指向字符数组:
char*
可以指向一个已有的字符数组。
2、常用操作
①字符串复制:
如果源字符串
src
的长度(包括
\0
)超过了目标字符串
dest
的大小,
strcpy
会导致缓冲区溢出,从而可能破坏内存或引发安全漏洞。如果你坚持使用
strcpy
,可以在代码的最开头(
#include
之前)添加宏定义#define _CRT_SECURE_NO_WARNINGS 来禁用这个警告。
解决方法1:使用
strcpy_s
(推荐)
strcpy_s
是 C11 标准中引入的安全版本,它在复制字符串时会检查目标缓冲区的大小,避免缓冲区溢出。
方法 2**:使用
strncpy
**
strncpy
可以指定最大复制的字符数,避免缓冲区溢出。
sizeof(dest) - 1
:最大复制的字符数(保留一个位置给
\0
)。
②字符串连接:
使用
strcat
或
strncat
连接字符串。类似,解决缓冲区溢出问题还有:**strcat_s、
strncat(
**
sizeof(dest) - strlen(dest) - 1
:最大连接的字符数(保留一个位置给
\0
))、宏定义。
③字符串比较:
使用
strcmp(
比较整个字符串,直到遇到
'\0'
) 或
strncmp(
只比较前
n
个字符) 比较字符串,都区分大小写,且比较是基于字符的ASCII值。
④获取字符串长度:
使用
strlen
获取字符串长度(不包括
\0)
。sizeof(char*)返回指针的大小,通常是4或8字节,取决于系统。
注意:未初始化的
char*
指针是空指针,直接使用会导致程序崩溃。
二、char[]
1、定义与初始化
①直接初始化:
可以直接用字符串字面量初始化字符数组。
②指定大小初始化:
可以指定字符数组的大小,但需要确保足够大以容纳字符串和
\0
。
③逐个字符初始化:
可以逐个字符初始化数组,并手动添加
\0
。
2、常用操作与char*一样
④获取字符串长度:
**
sizeof
**:返回数组的总大小(以字节为单位),包括
\0
。 **
strlen
**:返回字符串的实际长度(不包括
\0
)。
3、遍历字符数组
可以使用循环逐个访问字符数组中的字符。
4、修改字符数组
字符数组的内容可以修改。
三、char* 和 char[]区别
**
char*
**:
通常用于指向字符串常量或动态分配的字符串。
需要手动管理内存(如果指向动态内存)。
可修改性取决于指向的内存区域。
不包含大小信息,需通过
strlen
获取长度。作为函数参数时传递指针(即字符串的首地址)。
char[]:
用于存储字符串的数组,内存由编译器管理。
可修改,存储的是字符串的副本。
大小在编译时确定,可通过
sizeof
获取。作为函数参数时退化为
char*。
根据具体需求选择合适的类型:如果需要动态管理内存或指向常量字符串,使用
char*
;如果需要固定大小的字符串且可修改,使用
char[]
。