当前位置: 首页 > news >正文

C++与C语言中的字符串

目录

1、关于c语言中的字符串

(1)c语言中字符串与字符指针

(2)字符串结尾

2、关于c++中的字符串string

(1)从本质上了解string

(2)c++中的字符串转换与关联

(3)关于字符串中的'\0'

        为了方便对字符串进行操作与弥补c语言对字符串操控的不足,c++推出了string类,并且随着c++不断发展,string类完全可以当做一个容器(vector等)进行使用(此处不进步展开)。那么c++中的string与c语言又有那些联系与区别:

1、关于c语言中的字符串

(1)c语言中字符串与字符指针

char* str="hello!";

         本质上:字符指针str指向字符串首(也就是首元素的地址),c语言中的字符串存储于全局区(具体来讲是全局区中的常量区),那么问题来了,在c语言中指向的字符串可以改变吗?

答:在c语言中可以改变(为了指针操控地址的方便)
char* str="hello!";
*str='a';

        上述代码改变了首元素的值。

        c++从声明规范了字符串不可以改变,声明字符串前必须加const,如下:

const char* str1="hello";
char* str2="hello";//代码会报错,因为变量存储于常量区,其值不可以改变

        因此可以得出结论:C++中的字符串才是真正的字符串,C语言中的字符串并非严格意义上的字符串。

(2)字符串结尾

        有人好奇,为什么仅仅通过一个字符指针指向字符串的首元素就可以知道整个字符串的值,因为字符串在逻辑内存中连续存储,且以'\0'结尾。

        我们可以通过以下方式进行遍历字符串中的每一个元素:

const char* str="hello";
while(*str!='\0')
{
    printf("%c\n",*str);
}

        因此进行字符串拷贝时,一定不要忘记'\0'也需要占一个字节空间,空间需要扩充一个字节:

const char* str="hello";
char* str1=(char*)malloc(strlen(str)+1);

        于是有人好奇,那么字符数组是否也是以'\0'结尾?

答:并不是,字符数组通过数组的数目可以知道整个字符串的值,因此完全没有必要这样做
另外:字符数组是在栈区开辟空间,并不是在常量区!

        我们可以通过以下例子来进一步来证明我们的猜想:

	char ch[] = { 'h','e','l','l','o' };
	cout << sizeof(ch) << endl;
	if (ch[5]=='\0')
	{
		cout << "the string end is \\0" << endl;
	}
	else
	{
		cout << "the string end is not \\0" << endl;
	}

输出如下:

 

2、关于c++中的字符串string

(1)从本质上了解string

        string其实是c++中标准库的一个类,不过该类确实很“聪明”与“灵活”,既可以当做一个类来使用,也可以当做一个容器来使用(begin(),end()……等模板容器中的东西几乎都快要使用,想玩,自己亲自写代码去体会一下,哈哈哈)。

         那么问题来了,c++中的string类是否也是以'\0'结尾?

答:是的,这一点继承了C语言的风格!

        我们来看以下例子:

	string str1("hello world!");
	if (str1[str1.size()] == '\0')
	{
		cout << "该字符串以\\0结尾" << endl;
	}

        输出:

(2)c++中的字符串转换与关联

        我们可以通过string的成员函数获取字符串的首地址:c_str();注意:该首地址是一个指针常量,指向的内容不可以改变。

	string str1("hello world!");
	const char* str2 = str1.c_str();//注意必须是const,否则报错

        面对const,令人比较棘手,因为我们无法进行修改指针对应的内容,而有时候我们又必须进行修改该内容,那么我们应该怎么办?例如以下函数:

//转为小写字母
string toLowerCase(string s) 

因此我们需要建立一个char* str指向s[0],并且建立一个临时字符串,如下所示:

//转为小写字母
string toLowerCase(string s) 
{
	string tmp;
	if (s.empty())
	{
		return NULL;
	}
	char* str =  &s[0];
	while (*str!='\0')
	{

	   if (*str<='Z'&&*str>='A')
	   {
		   *str = *str + 32;
	   }
	   tmp.push_back(*str);
	   str++;
	}
	return tmp;

}

(3)关于字符串中的'\0'

        我们看以下例子:

	string str1("hello\0 world!");
	cout << str1 << endl;

        那么输出为什么呢?hello呢还是hello\0 world!?

        因为遇到'\0'自动忽略后面的字符,于是有人好奇,str1的字符长度(不包含'\0')又为多少呢?

	string str1("hello\0 world!");
	cout << str1.length() << endl;
	cout << strlen(str1.c_str()) << endl;

 最后,送一句话给自己,同时也给每一个奋斗在代码第一线的同志:打破砂锅问到底,你将战无不胜攻无不克!

相关文章:

  • 8. 无线体内纳米网:基于蓝牙LE接口的数字ID系统
  • 极智AI | 昇腾 CANN ATC 模型转换
  • 富文本编辑器(添加列表)
  • 格理论与密码学-2-2-公钥密码体制和哈希函数
  • Vue框架的学习(Vue操作指令学习三 V-bind )第三课
  • C语言之指针(中)
  • neo4j-jdbc-driver这个坑货
  • 云存储系统架构及优势
  • Oracle SQL执行计划操作(1)——表相关操作
  • C语言实现三子棋小游戏(源码+教程)
  • 解读数据可用性赛道:如何讲好模块化区块链的叙事?
  • 如何进入 mysql?
  • java计算机毕业设计VUE商场库存管理系统MyBatis+系统+LW文档+源码+调试部署
  • LeetCode链表练习(上)
  • 面试不面试,你都必须得掌握的vue知识
  • 墙裂推荐,阿里内网价值9K的Java中高级核心全解析笔记
  • VS2022 程序打包过程总结
  • 第三章:Java基本语法
  • centos7安装python3.7
  • Ansys Zemax | 大功率激光系统的 STOP 分析1:如何使用 OpticStudio 优化光学设置