C++ 字符串与字符数组 详解

C++ 字符串与字符数组 详解在 C 中 有两种类型的字符串表示形式 C 风格字符串 C 引入的 string 类 C 风格字符串 C 风格的字符串起源于 C 语言 并在 C 中继续得到支持 字符串实际上是使用 null 字符 0 终止的一维字符数组 因此 一个以 null 结尾的字符串 包含了组成字符串的字符 下面的声明和初始化创建了一个 Hello 字符串 由于在数组的末尾存储了空字符 所以

在C++中,有两种类型的字符串表示形式:

  • C-风格字符串
  • C++引入的string类

C-风格字符串

char greeting[6] = { 
  'H', 'e', 'l', 'l', 'o', '\0'};

其实,您不需要把 null 字符放在字符串常量的末尾。C++ 编译器会在初始化数组时,自动把 ‘\0’ 放在字符串的末尾。所以也可以利用下面的形式进行初始化

char greeting[] = "Hello";
序号 函数 功能
1 strcpy(s1,s2) 复制字符串 s2 到字符串 s1
2 strcat(s1,s2) 连接字符串 s2 到字符串 s1 的末尾
3 strlen(s1) 返回字符串 s1 的长度
4 strcmp(s1,s2) 返回s1与s2的比较结果
5 strchr(s1,ch) 返回一个指针,指向字符串s1中字符ch的第一次出现的位置
6 strstr(s1,s2) 返回一个指针,指向字符串s1中s2的第一次出现的位置

C++ 中的 String 类

C++ 标准库提供了 string 类类型,支持上述所有的操作,另外还增加了其他更多的功能。比如:

  • append() – 在字符串的末尾添加字符
  • find() – 在字符串中查找字符串
  • insert() – 插入字符
  • length() – 返回字符串的长度
  • replace() – 替换字符串
  • substr() – 返回某个子字符串

4种字符串类型

C++中的字符串一般有以下四种类型,

  • string
  • char*
  • const char*
  • char[]

下面分别做简单介绍,并说明其中的一些区别

string

string是一个C++类库中的一个类,它位于名称空间std中,因此必须使用using编译指令或者std::string来引用它。它包含了对字符串的各种常用操作,它较char*的优势是内容可以动态拓展,以及对字符串操作的方便快捷,用+号进行字符串的连接是最常用的操作

char*

char* 是指向字符串的指针(其实严格来说,它是指向字符串的首个字母),你可以让它指向一串常量字符串。

const char*

该声明指出,指针指向的是一个const char类型,即不能通过当前的指针对字符串的内容作出修改

注意这里有两个概念:

  • char * const [指向字符的静态指针]
  • const char * [指向静态字符的指针]

前者const修饰的是指针,代表不能改变指针
后者const修饰的是char,代表字符不能改变,但是指针可以变,也就是说该指针可以指针其他的const char。

char[]

与char*与许多相同点,代表字符数组,可以对应一个字符串,如

char * a="string1"; char b[]="string2";

二者的不同点

一,char*是变量,值可以改变, char[]是常量,值不能改变!
a是一个char型指针变量,其值(指向)可以改变;
b是一个char型数组的名字,也是该数组首元素的地址,是常量,其值不可以改变




二,char[]对应的内存区域总是可写,char*指向的区域有时可写,有时只读
比如:

char * a="string1"; char b[]="string2"; gets(a); //试图将读入的字符串保存到a指向的区域,运行崩溃!  gets(b) //OK

解释: a指向的是一个字符串常量,即指向的内存区域只读;
b始终指向他所代表的数组在内存中的位置,始终可写!

注意,若改成这样gets(a)就合法了:

char * a="string1"; char b[]="string2"; a=b; //a,b指向同一个区域 gets(a) //OK printf("%s",b) //会出现gets(a)时输入的结果

解释: a的值变成了是字符数组首地址,即&b[0],该地址指向的区域是char *或者说 char[8],习惯上称该类型为字符数组,其实也可以称之为“字符串变量”,区域可读可写。

总结:char *本身是一个字符指针变量,但是它既可以指向字符串常量,又可以指向字符串变量,指向的类型决定了对应的字符串能不能改变!

三,char * 和char[]的初始化操作有着根本区别:
测试代码:

char *a="Hello World"; char b[]="Hello World"; printf("%s, %d\n","Hello World", "Hello World"); printf("%s, %d %d\n", a, a, &a); printf("%s, %d %d\n", b, b, &b);

结果:

Hello World, Hello World,  Hello World, 
  1. 声明一个char*变量(也就是声明了一个指向char的指针变量);
  2. 在内存中的文字常量区中开辟了一个空间存储字符串常量”string1”
  3. 返回这个区域的地址,作为值,赋给这个字符指针变量a

char b[]=”string2”;则是实现了2个操作:

  1. 声明一个char 的数组,
  2. 为该数组“赋值”,即将”string2”的每一个字符分别赋值给数组的每一个元素

最终的结果:“数组的值”(注意不是b的值)等于”string2”,而不是b指向一个字符串常量

实际上, char * a=”string1”; 的写法是不规范的!
因为a指向了即字符常量,一旦strcpy(a,”string2”)就糟糕了,试图向只读的内存区域写入,程序会崩溃的!尽管VS下的编译器不会警告,但如果你使用了语法严谨的Linux下的C编译器GCC,或者在windows下使用MinGW编译器就会得到警告。
所以,我们还是应当按照”类型相同赋值”的原则来写代码:




const char * a="string1";

保证意外赋值语句不会通过编译

另外,关于char*和char[]在函数参数中还有一个特殊之处,运行下面的代码

void fun1 ( char *p1, char p2[] ) { printf("%s %d %d\n",p1,p1,&p1); printf("%s %d %d\n",p2,p2,&p2); p2="asdf"; //通过! 说明p2不是常量! printf("%s %d %d\n",p2,p2,&p2); } void main(){ char a[]="Hello"; fun1(a,a); }

运行结果:

Hello   Hello   asdf  

const char*与char[]的区别:
const char * a=”string1”
char b[]=”string2”;
二者的区别在于:






  1. a是const char 类型, b是char const类型
    ( 或者理解为 (const char)xx 和 char (const xx) )

  2. a是一个指针变量,a的值(指向)是可以改变的,但a只能指向(字符串)常量,指向的区域的内容不可改变;
  3. b是一个指针常量,b的值(指向)不能变;但b指向的目标(数组b在内存中的区域)的内容是可变的
  4. 作为函数的声明的参数的时候,char []是被当做char *来处理的!两种形参声明写法完全等效!

字符串类型之间的转换: string、const char*、 char* 、char[]相互转换

一、转换表格

源格式->目标格式 string char* const char* char[]
string NULL 直接赋值 直接赋值 直接赋值
char* strcpy NULL const_cast char*=char
const char* c_str() 直接赋值 NULL const char*=char;
char[] copy() strncpy_s() strncpy_s() NULL

二、总结方法:

  1. 变成string,直接赋值。
  2. char[]变成别的,直接赋值。
  3. char*变constchar*容易,const char*变char*麻烦。


    (constchar*);

  4. string变char*要通过const char*中转。
  5. 变成char[]。string逐个赋值,char* const char* strncpy_s()。

三,代码示例

1、string转为其他类型

①、string转const char*

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { std::string str = "HelloWorld!"; //初始化string类型,并具体赋值 const char* constc = nullptr; //初始化const char*类型,并赋值为空 constc= str.c_str(); //string类型转const char*类型 printf_s("%s\n", str.c_str()); //打印string类型数据 .c_str() printf_s("%s\n", constc); //打印const char*类型数据 return 0; }

②、string转char*

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { std::string str = "HelloWorld!"; //初始化string类型,并具体赋值 char* c = nullptr; //初始化char*类型,并赋值为空 const char* constc = nullptr; //初始化const char*类型,并赋值为空 constc= str.c_str(); //string类型转const char*类型 c= const_cast<char*>(constc); //const char*类型转char*类型 printf_s("%s\n", str.c_str()); //打印string类型数据 .c_str() printf_s("%s\n",c); //打印char*类型数据 return 0; }

③、string转char[]

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { std::string str = "HelloWorld!"; //初始化string类型,并具体赋值 char arrc[20] = { 
  0}; //初始化char[]类型,并赋值为空 for (int i = 0; i < str.length(); i++) //string类型转char[]类型 { arrc[i]=str[i]; } printf_s("%s\n", str.c_str()); //打印string类型数据 .c_str() printf_s("%s\n", arrc); //打印char[]类型数据 return 0; }

2、const char*转为其他类型

①const char*转string

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { const char* constc = "Hello World!"; //初始化const char* 类型,并具体赋值 std::string str; //初始化string类型 str= constc; //const char*类型转string类型 printf_s("%s\n", constc); //打印const char* 类型数据 printf_s("%s\n", str.c_str()); //打印string类型数据 return 0; }

②const char*转char*

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { const char* constc = "Hello World!"; //初始化const char* 类型,并具体赋值 char* c = nullptr; //初始化char*类型 c= const_cast<char*>(constc); //const char*类型转char*类型 printf_s("%s\n", constc); //打印const char* 类型数据 printf_s("%s\n", c); //打印char*类型数据 return 0; }

③const char*转char[]

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { const char* constc = "Hello World!"; //初始化const char* 类型,并具体赋值 char arrc[20] = { 0 }; //初始化char[]类型,并赋值为空 strncpy_s(arrc,constc,20); //const char*类型转char[]类型 printf_s("%s\n", constc); //打印const char* 类型数据 printf_s("%s\n", arrc); //打印char[]类型数据 return 0; }

3、char*转为其他类型

①char*转string

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { char* c = "HelloWorld!"; //初始化char* 类型,并具体赋值 std::string str; //初始化string类型 str= c; //char*类型转string类型 printf_s("%s\n", c); //打印char* 类型数据 printf_s("%s\n", str.c_str()); //打印string类型数据 return 0; }

②char*转const char*

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { char* c = "HelloWorld!"; //初始化char* 类型,并具体赋值 const char* constc = nullptr; //初始化const char* 类型,并具体赋值 constc= c; //char*类型转const char* 类型 printf_s("%s\n", c); //打印char* 类型数据 printf_s("%s\n", constc); //打印const char* 类型数据 return 0; }

③char*转char[]

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { char* c = "HelloWorld!"; //初始化char* 类型,并具体赋值 char arrc[20] = { 0 }; //初始化char[] 类型,并具体赋值 strncpy_s(arrc,c,20); //char*类型转char[] 类型 printf_s("%s\n", c); //打印char* 类型数据 printf_s("%s\n", arrc); //打印char[]类型数据 return 0; }

4、char[]转为其他类型

#include "stdafx.h" #include 
    int _tmain(intargc, _TCHAR* argv[]) { char arrc[20] = "HelloWorld!";//初始化char[] 类型并具体赋值 std::string str; //初始化string const char* constc = nullptr; //初始化const char* char*c = nullptr; //初始化char* str= arrc; //char[]类型转string类型 constc= arrc; //char[]类型转const char* 类型 c= arrc; //char[]类型转char*类型 printf_s("%s\n", arrc); //打印char[]类型数据 printf_s("%s\n", str.c_str()); //打印string类型数据 printf_s("%s\n", constc); //打印const char* 类型数据 printf_s("%s\n", c); //打印char*类型数据 return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/204902.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午7:16
下一篇 2026年3月19日 下午7:16


相关推荐

  • resnet18 pytorch_如何搭建服务器

    resnet18 pytorch_如何搭建服务器参照ResNet50的搭建,由于50层以上几乎相同,叠加卷积单元数即可,所以没有写注释。101和152的搭建注释可以参照我的ResNet50搭建中的注释:训练可以参照我的ResNet18搭建中的训练部分:ResNet101和152可以依旧参照ResNet50的网络图片:上代码:ResNet101的model.py模型:importtorchimporttorch.nnasnnfromtorch.nnimportfunctionalasFclassDownSampl

    2022年10月6日
    6
  • Faulty Odometer【水题】

    Faulty Odometer【水题】FaultyOdomet 2000 1000MS Java Others MemoryLimit 32768 32768K Java Others TotalSubmiss s 1218Accepted s 841ProblemDe Youaregiv

    2026年3月17日
    2
  • PHP验证二代身份证

    PHP验证二代身份证functionvalidation_filter_id_card($id_card){ if(strlen($id_card)==18){ returnidcard_checksum18($id_card); }elseif((strlen($id_card)==15)){ $id_card=idcard_15to18($id_card); return

    2022年6月27日
    34
  • 从零开始安装pytorch,并在pycharm中使用

    从零开始安装pytorch,并在pycharm中使用pytorch安装与使用步骤简述anaconda下载与安装anaconda环境配置anaconda安装pytorch包pycharm运行pytorch环境理解环境步骤简述pytorch是基于torch和Python语言的机器学习库。anaconda是环境与包的管理工具,pytorch的下载需要借助anaconda来完成。另外,安装的anaconda自带Python,因此没安装过Python的小伙伴也不必要再安装Python了。最后anaconda为我们提供了运行环境,为了编写程序的方便,我们还需要一款

    2022年8月26日
    10
  • 用户代码未处理MetadataException

    用户代码未处理MetadataException用户代码未处理MetadataException

    2022年4月24日
    41
  • 龙虾为什么这么登?

    龙虾为什么这么登?

    2026年3月16日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号