前言:
指针我们已经知道如何使用了,也知道指针和数组配合起来使用,这次我们来讲讲指针与字符串,以及指针和动态结构的一些知识。
1.指针与字符串
1.1cout接收char类型的地址的反应
我们知道字符数组的数组名是首字符的地址,当我们用cout工具来显示字符数组里的字符串的时候,无疑是把首地址传给cout了。cout将顺着这个地址依次往下打印,当它遇到字符串的结束标志时,就停下来不打印了。
所以我们就知道,cout在打印字符串的时候,接收的是一个字符的地址,并认为我们是要它打印一个字符串,为了与cout对字符串输出的处理保持一致,引号括起来的字符串也应当是一个地址。
1.2字符串字面值
双引号括起来的字符串是常量字符串,是一个不能被修改的值,一般出现在用字符指针来接收常量字符串的首字符地址。但我们知道,字符串还可以给字符数组初始化,但内容可以被修改,大家注意区分。
对bird指针进行const修饰,使得代码更加健壮,当发现错误时,主动抛出错误。
对指向常量字符串的字符指针进行输入是错误的:
有些编译器将字符串字面值视为只读常量,如果修改了它们,编译器将会报错。在C++中,字符串字面值都被视为常量,而有一些编译器并没有改过来,仍可以对其进行修改。
有些编译器只使用一个字符串字面值副本来为程序使用。
补充:C++不能保证字符串字面值被唯一得存储。
1.3字符串备份
怎么将一个字符串给存起来呢?首先我们可以想到用数组,但这个数组如果是静态的话缺点很多,所以我们考虑用new创建一个动态数组,将其地址返回个一个字符指针管理更好。
在C++中strlen、strcpy的头文件是<cstring>,使用方法和C语言里的一样。
这里还需要首的一点就是在开辟动态数组时,元素个数的确定+1的问题。因为我们计算字符串长度的时候,空字符是不算内容的,但表示一个字符串,结尾必须有空字符,我们加上这个单位空间,就是给空字符留的。
2.使用new创建动态结构
创建动态结构和前面的都很相似,我注释里说明清楚啦,这里就不再赘述啦。
关于为动态结构成员赋值,我们需要使用cin和cin.get()工具分别为变量和字符数组赋值,这一点很重要。可不敢直接像C一样p->name = "张三";如果不是很懂cin.get()请跳转:
链接:《认识C++字符串符合类型》
而如何访问到结构成员呢?首先p是一个指向结构体的指针,指针通过箭头操作符可以轻松访问到结构体成员。这里读者可能也很好奇,为啥没有结构名称的结构体可以通过(*p).成员名来访问。博主经过一番学习,总结经验,认为是因为内存单元是唯一性的原因。我们知道,两个没有名称的结构体,即使成员一模一样,在声明类型的时候创建出来的变量也会被认为是不同类型的结构体变量。这正是因为两个变量的存储地址不同呀。虽然有名称的结构体创建的变量也不在同一个存储位置上,但它们是由相同名称创建出来的。说这个原因是,因为计算机在对没有名称的结构体进行操作时,可以用(*指针).结构体成员,是因为,类型是独立的,计算机认得这块空间里放得是什么东西。
3.使用new和delete搭配存储键盘输入的字符串
当我们想将输入的字符串内容放到一个开辟在堆区的数组中,可以使用new来实现。
可能读者不太理解这么做的意义在哪,博主解释一下。我们在以往输入一个字符串到一个动态数组的时候,是不是事前还要确定动态数组要开辟多大的空间,我们需要决定元素个数。但在这里,我们先是用了一个较大的静态数组接收我们输入的字符串(保证接收的下),然后用字符串备份的方式,开辟一个合理的数组大小,并将其地址返回去。而getname()函数内部的局部变量pn和数组都销毁掉了,没有浪费空间。
最后的结果就相当于将键盘输入的字符串放到一个大小恰好不过的数组里面去了。
好啦,今天的指针内容就到这告一段落啦。后面还有一些细碎的指针知识,我们以后遇到就写出来,进入下一篇章。
希望读者读完有所收获,如果文章有误的地方,请读者留言至评论区下方,博主看到及时更改。
求点赞,求点赞,求点赞!