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*是历史遗留问题,如果程序修 ...
随机推荐
- C/C++编程笔记:C++入门知识丨认识C++的函数和对象
一. 本篇要学习的内容和知识结构概览 二. 知识点逐条分析 1. 混合型语言 C++源文件的文件扩展名为.cpp, 也就是c plus plus的简写, 在该文件里有且只能有一个名为main的主函数, ...
- 7.1 NOI模拟赛 dp floyd
这是一道非常垃圾的题目 且 数据范围简直迷惑选手.. 可以发现 题目中有 边权递增 边的条数 所有边权值不同 最小边权和等条件. 看起来很难做 一个想法 边权递增+边的1的权值都不相同可以想到 关系存 ...
- 4.15 省选模拟赛 编码 trie树 前缀和优化建图 2-sat
好题 np. 对于20分 显然可以爆搜. 对于50分 可以发现每个字符串上的问号要么是0,要么是1.考虑枚举一个字符串当前是0还是1 这会和其他字符串产生矛盾. 所以容易 发现这是一个2-sat问题. ...
- idea修改module name后重启失效
技术交流群 : 816227112 idea每次修改module name后重启,module还是会在后面加上原来的name. 这时修改: .idea下的modules.xml 内的module名即可 ...
- 网络通信-RESTful API 设计指南
http://www.ruanyifeng.com/blog/2014/05/restful_api.html 作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前 ...
- Spring学习总结(1)-注入方式
Spring实现IOC的思路是提供一些配置信息用来描述类之间的依赖关系,然后由容器去解析这些配置信息,继而维护好对象之间的依赖关系,前提是对象之间的依赖关系必须在类中定义好,比如A.class中有一个 ...
- CentOS 7.0防火墙设置
CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙.1.关闭firewall:systemctl stop firewalld.servicesystemctl ...
- python获取系统内存占用信息的实例方法
psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控, ...
- Java流程控制,for,switch,while.break,continue,return
Java流程控制,for,switch,while.break,continue,return
- java_线程、同步、线程池
线程 Java使用 java.lang.Thread 类代表线程,所有的线程对象都必须是Thread类或其子类的实例 Thread类常用方法 构造方法 public Thread():分配一个新的线程 ...