字符串初始化

在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. 如何使用PHP验证客户端提交的表单数据

    PHP 表单验证 本章节我们将介绍如何使用PHP验证客户端提交的表单数据. PHP 表单验证 在处理PHP表单时我们需要考虑安全性. 本章节我们将展示PHP表单数据安全处理,为了防止黑客及垃圾信息我们 ...

  2. PHP in_array() 函数

    实例 在数组中搜索值 "Runoob" ,并输出一些文本: <?php $sites = array("Google", "Runoob&quo ...

  3. MOSFET 的 I / V 特性曲线

    https://www.cnblogs.com/yeungchie/ MOSFET 线性区(三极管区,\(V_{DS} \leq V_{GS} - V_{TH}\)) \[I_{D} = \mu_{n ...

  4. 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...

  5. CF Contest 526 G. Spiders Evil Plan 长链剖分维护贪心

    LINK:Spiders Evil Plan 非常巧妙的题目. 选出k条边使得这k条边的路径覆盖x且覆盖的边的边权和最大. 类似于桥那道题还是选择2k个点 覆盖x那么以x为根做长链剖分即可. 不过这样 ...

  6. 学会这些Python美图技巧,就等着女朋友夸你吧

    一.前言 Python中有许多用于图像处理的库,像是Pillow,或者是OpenCV.而很多时候感觉学完了这些图像处理模块没有什么用,其实只是你不知道怎么用罢了.今天就给大家带了一些美图技巧,让你的图 ...

  7. CentOS yum 安装nginx

    当使用以下命令安装Nginx时,发现无法安装成功 yum install -y nginx 需要做一点处理. 安装Nginx源 执行以下命令: rpm -ivh http://nginx.org/pa ...

  8. Nginx配置SSL证书,提高网络安全性

    首先区别Http与Https HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高 ...

  9. gym102586 部分题解

    目录 Evacuation Sum Modulo Count Modulo 2 Robots Construct Points Amidakuji Yosupo's Algorithm link 出于 ...

  10. Qt之先用了再说系列-定时器的用法

    Qt 定时器是一个比好用的东西,在此就地简单记录一下使用的方式: 1.首先包含头文件 #include <QTimer> 2.具体用法有几种,我就写其中2种吧 1>执行一次 这种方式 ...