字符串初始化

在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;
}

通过上面的代码,可以看出几点:

  1. 通过模板类实例化的类类型必须用string指针接收,指针步长为初始化变量的大小(上例中步长为3)
  2. 字符串常量赋值得到的类型可以用string类型接收
  3. 使用类对象对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;
}
  1. string类型在C++中被看做const char*,所以basic模板类对象的初始化需要用string*来接收
  2. 字符串常量也被看成是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++字符串与指针的更多相关文章

  1. c#编程指南(十) 平台调用P-INVOKE完全掌握, 字符串和指针

    可以说新手使用P-INVOKE最开始的头疼就是C#和C++的字符串传递,因为这里涉及到两个问题. 第一:C#的string和C++的字符串首指针如何对应. 第二:字符串还有ANSI和UNICODE(宽 ...

  2. 指向字符串的指针在printf与cout区别

    根据指针用法: * 定义一个指针, &取变量地址, int b = 1; int *a = &b; 则*a =1,但对于字符串而言并非如此,直接打印指向字符串的指针打印的是地址还是字符 ...

  3. C语言复习-字符串与指针

    C语言复习-字符串与指针 例一: [字符串处理 去除C代码中的注释] C/C++代码中有两种注释,/* */和//.编译器编译预处理时会先移除注释.就是把/*和*/之间的部分去掉,把//以及之后的部分 ...

  4. C语言之数组,字符串,指针

    一. 数组的定义 1.  数组初始化 初始化方式 int a[3] = {10, 9, 6}; int a[3] = {10,9}; int a[] = {11, 7, 6}; int a[4] = ...

  5. Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法

    由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...

  6. 「C」 数组、字符串、指针

    一.数组 (一)数组 概念:用来存储一组数据的构造数据类型 特点:只能存放一种类型的数据,如全部是int型或者全部是char型,数组里的数据成为元素. (二)数组的定义 格式: 类型 数组名[元素个数 ...

  7. c++学习day3(字符串_指针)

    1.字符串 1)三种形式 用双引号括起来的字符串常量:结尾会有一个'\0'字符,但该字符只占据字节数,不会使字符串长度增加. 存放于字符数组中,以'\0'字符结尾:数组元素个数应至少为字符串长度+1 ...

  8. 指向字符串的指针和char类型的数组

    指针数组的效率比二维字符数组的效率高 指针数组不能修改字符串字面量,而二维字符数组中的内容可以更改

  9. C语言程序设计--字符串与指针及数组与指针

    数组的基本知识 数组的定义 #define SIZE 5 int array_int[5]; //未声明初始化,默认填零 float array_float[5] = {1.01, 2.23, 3.1 ...

  10. VS2019 字符串对指针char*赋值编译器报错原因及解决方法

    2019-05-26   21:55:08 前几天在敲代码时,将字符串“Hellow world!”赋值给指针char*类型指针时编译器报错的问题 网上搜索后发现 char*是历史遗留问题,如果程序修 ...

随机推荐

  1. 7.1 NOI模拟赛 dp floyd

    这是一道非常垃圾的题目 且 数据范围简直迷惑选手.. 可以发现 题目中有 边权递增 边的条数 所有边权值不同 最小边权和等条件. 看起来很难做 一个想法 边权递增+边的1的权值都不相同可以想到 关系存 ...

  2. NOI Online 游戏 树形dp 广义容斥/二项式反演

    LINK:游戏 还是过于弱鸡 没看出来是个二项式反演,虽然学过一遍 但印象不深刻. 二项式反演:有两种形式 一种是以恰好和至多的转换 一种是恰好和至少得转换. 设\(f_i\)表示至多的方案数 \(g ...

  3. bzoj 4974 [Lydsy1708月赛]字符串大师 KMP 最小循环元 构造

    LINK:字符串大师 给出一个字符串的每个前缀的最小循环元 还原字典序最小的原字符串. 一个比较显然的结论 或者说 学过KMP的都知道 对于每个前缀i求出nex数组后 那么i-nex[i]为最小循环元 ...

  4. luogu P6091 原根

    LINK:原根 再复习一下原根 防止考场上要NTT求原根的时候不会求... 这道题要求求出n之内的所有原根 根据原根的定义. 原根指 若x对于模n的阶为phi(n)且\(1\leq x\leq n\) ...

  5. sql_to_csv

    将需要信息 导出成 csv,txt等格式 create or replace procedure sql_to_csv(p_query in varchar2, --sql query stateme ...

  6. 云小课 | IPv4枯了,IPv6来了

    摘要:本篇主要分享IPv4与IPv6的区别和IPv6的应用场景,助您快速理解华为云IPv6双栈及IPv6 EIP. IPv6的由来 上节课我们讲了公网IP与私网IP,了解了IP地址的一些知识. 我们一 ...

  7. JSON 和 POJO 互转,List<T> 和 JSON 互转

    JSON 和 POJO import com.alibaba.fastjson.JSONObject; import org.slf4j.Logger; import org.slf4j.Logger ...

  8. SmartDb代码修改

    在之前的一篇博客中介绍过SmartDB(https://blog.csdn.net/wuquan_1230/article/details/89145012),在使用的过程中发现一个问题,会造成内存泄 ...

  9. 主成分分析PCA数据降维原理及python应用(葡萄酒案例分析)

    目录 主成分分析(PCA)——以葡萄酒数据集分类为例 1.认识PCA (1)简介 (2)方法步骤 2.提取主成分 3.主成分方差可视化 4.特征变换 5.数据分类结果 6.完整代码 总结: 1.认识P ...

  10. C#LeetCode刷题之#766-托普利茨矩阵(Toeplitz Matrix)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3748 访问. 如果一个矩阵的每一方向由左上到右下的对角线上具有相 ...