C++字符串与指针
字符串初始化
在C++中基本数据类型并不包括string,string类型其实是一种类类型,通过STL函数库中的模板类basic_string 实例化得到。
int main ()
{
// string a = new string("123"); // 报错,需要将std::basic_string<char> * 转换到 std::basic_string<char>,
// 也就是编译器无法完成转换
string *a = new string("123");
string b = "456";
string *c = new string(b); // 并不是拷贝构造的浅拷贝
*c = "789";
cout << *a << endl; // 输出 123
cout << b[0] << endl; // 输出4
cout << c[0] << endl; // 输出789
return 0;
}
通过上面的代码,可以看出几点:
- 通过模板类实例化的类类型必须用string指针接收,指针步长为初始化变量的大小(上例中步长为3)
- 字符串常量赋值得到的类型可以用string类型接收
- 使用类对象对string类进行初始化,并不是浅拷贝,对指针的操作与原对象无关
string & 字符串常量 & char*
字符串常量在C++中的表示(const char):
int main()
{
// string a = 123; // 报错,invalid conversion from 'int' to 'const char*'
// int a = "123"; // 报错,invalid conversion from 'const char*' to 'int'
const char *a = "123"; // 通过
cout << a << endl; // 输出 123
string b = a; // 通过
delete a,b;
return 0;
}
- string类型在C++中被看做const char*,所以basic模板类对象的初始化需要用string*来接收。
- 字符串常量也被看成是const char* 类型,所以用string接收字符串常量是合法的。
特殊的字符串常量操作:
既然上面提到字符串常量被看成是const char*类型,那么许多奇奇怪怪的用法就来了。
int main ()
{
*("123") = '2'; // 报错,无法使用解引用符对常量进行修改
cout << &("123") << endl; // 输出指针的地址
printf("常量\"123\"的所有元素:%c,%c,%c\n", *("123"), *("123"+1), *("123"+100));// 对指针的操作,输出1,2
const char *p = "123"; // 常量char指针的赋值
cout << (p == "123") << endl; // 因为指向同一个地址,输出 1
cout << (*p == "123"[0]) << endl; // 指向的元素是同一个元素,输出 1
cout << &(*("123"))<< endl; // 对某一元素的取地址,输出123
delete p;
return 0;
}
在上面的最后一个输出中,首先 *("123")得到的结果应该是字符'1',而对字符'1'取地址是没有问题的,为什么最后输出的不是正确地址而是字符串呢?
奇怪的字符指针取地址:
在回答问题之间,先来看下面这个例子:
int main ()
{
char p[5] = {'1','2','3','4'};
cout << p[0] << '\n' << &p[0] << endl; // 打印char数组第一个元素及其地址
int q[5] = {1,2,3,4,5};
cout << q[0] << '\n' << &q[0] << endl;// 打印int数组第一个元素及其地址
delete p,q;
return 0;
}

在2.1的代码中,我们将字符串常量赋值给了常量指针,并利用指针完成了字符串的输出,由此我们可知指针中储存的就是常量的首字符地址。即p = &("123"[0]) = &(p[0])。如下所示:
int main ()
{
const char* a = "123";
cout << (a == &("123"[0])) <<endl; // 输出1
cout << (a == &(a[0])) <<endl; // 输出1
cout << a <<endl; // 输出 123
int b[] = {1,2,3};
cout << (b == &(b[0])) <<endl; // 输出 1
cout << b << endl; // 输出 0x28fe90
return 0;
}
由于字符指针的指针的特殊性:字符指针可能会被认为代表一个字符串,而不是一个地址,在这种情况下,编译器会一直打印字符串,而不是地址。
而相应的其他数据类型就不存在这种问题了。
因此如果想要得到字符数组或字符串中某个元素的地址,可以将char类型强转为非char类型打印。
int main ()
{
const char* a = "123";
cout << &(a[0]) << endl;
cout << (void *)&(a[0])<< endl;
return 0;
}

结语
无
时间:2020/08/16 10:55
坐标:广东深圳
C++字符串与指针的更多相关文章
- c#编程指南(十) 平台调用P-INVOKE完全掌握, 字符串和指针
可以说新手使用P-INVOKE最开始的头疼就是C#和C++的字符串传递,因为这里涉及到两个问题. 第一:C#的string和C++的字符串首指针如何对应. 第二:字符串还有ANSI和UNICODE(宽 ...
- 指向字符串的指针在printf与cout区别
根据指针用法: * 定义一个指针, &取变量地址, int b = 1; int *a = &b; 则*a =1,但对于字符串而言并非如此,直接打印指向字符串的指针打印的是地址还是字符 ...
- C语言复习-字符串与指针
C语言复习-字符串与指针 例一: [字符串处理 去除C代码中的注释] C/C++代码中有两种注释,/* */和//.编译器编译预处理时会先移除注释.就是把/*和*/之间的部分去掉,把//以及之后的部分 ...
- C语言之数组,字符串,指针
一. 数组的定义 1. 数组初始化 初始化方式 int a[3] = {10, 9, 6}; int a[3] = {10,9}; int a[] = {11, 7, 6}; int a[4] = ...
- Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法
由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...
- 「C」 数组、字符串、指针
一.数组 (一)数组 概念:用来存储一组数据的构造数据类型 特点:只能存放一种类型的数据,如全部是int型或者全部是char型,数组里的数据成为元素. (二)数组的定义 格式: 类型 数组名[元素个数 ...
- c++学习day3(字符串_指针)
1.字符串 1)三种形式 用双引号括起来的字符串常量:结尾会有一个'\0'字符,但该字符只占据字节数,不会使字符串长度增加. 存放于字符数组中,以'\0'字符结尾:数组元素个数应至少为字符串长度+1 ...
- 指向字符串的指针和char类型的数组
指针数组的效率比二维字符数组的效率高 指针数组不能修改字符串字面量,而二维字符数组中的内容可以更改
- C语言程序设计--字符串与指针及数组与指针
数组的基本知识 数组的定义 #define SIZE 5 int array_int[5]; //未声明初始化,默认填零 float array_float[5] = {1.01, 2.23, 3.1 ...
- VS2019 字符串对指针char*赋值编译器报错原因及解决方法
2019-05-26 21:55:08 前几天在敲代码时,将字符串“Hellow world!”赋值给指针char*类型指针时编译器报错的问题 网上搜索后发现 char*是历史遗留问题,如果程序修 ...
随机推荐
- 【保姆级教学】新手第一次搭建vue项目和初始化
前端项目初始化步骤 安装vue脚手架 通过vue脚手架创建项目 配置vue路由 配置Element-UI组件库 配置axios库 初始化git远程仓库 将本地项目托管到github或者码云上 通过vu ...
- MediaDevices.getUserMedia()
MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道.此流可以包含一个视频轨道(来自硬件或 ...
- Spring bean作用范围
1,singleton Spring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在:2,prototype 每次从容器中调用 Bean 时,都返回一个新的实例:3,request ...
- spring boot中使用mybatis的注意点!!!
1 生成的mapper接口上打上注解 2 在pom.xml中需要导入mysql(根据需要),jdbc和mybatis的依赖 3 在主类上设置扫描 4 com.mysql.cj.exceptions等报 ...
- Java—匿名对象/内部类/访问修饰符/代码块
匿名对象 匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. //创建一个普通对象 Person p = new Person(); //创建一个匿名对象 new Pers ...
- go微服务系列(四) - gRPC入门
1. 前言 2. gRPC与Protobuf简介 3. 安装 4. 中间文件演示 4.1 编写中间文件 4.2 运行protoc命令编译成go中间文件 5. 创建gRPC服务端 5.1 新建Produ ...
- HTML5+css3 的开心网游戏页面
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 剑指Offer——II平衡二叉树
class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None # 这道题使用中序遍历加上 ...
- Ubuntu18.04安装Nautilus-actions自定义文件管理器鼠标右键列表
sudo add-apt-repository ppa:daniel-marynicz/filemanager-actions #需要添加源 sudo apt-get install filemana ...
- day6 函数
1.关键字参数 给实参对应的形参 调用函数时 设置关键字参数,形参=实参,把实参固定给那个形参 2.元组的可变(不定长参数)的使用 可变参数可以接收任意数量的普通的形参,并且组包 ...