前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >搞清C++中指针、数组、字符串的关系

搞清C++中指针、数组、字符串的关系

原创
作者头像
zlmai
发布2018-09-09 20:34:02
1.6K0
发布2018-09-09 20:34:02
举报
文章被收录于专栏:zlmai的专栏zlmai的专栏

字符串是存储在内存中连续字节的一系列字符,C++处理字符串的方式有两种:

1、来自C语言的C-风格字符串;

2、基于string类库中的方法。

本文主要讲第一种。

在C++中定义一个字符串的语句,可以是:

代码语言:javascript
复制
char arr[] = "aaa"; 

或者是:

代码语言:javascript
复制
char arr[4] = "aaa"; 

或者是:

代码语言:javascript
复制
char arr[4] = {'a','a','a','\0'};  // 注意,最后一个元素一定要是'\0',否则arr不表示字符串

这三种写法都是等效的。

但怎么表示这个字符串呢,有两种C-风格字符串的表示方式:

1、使用带双引号的字符串表示,比如"aaa";

2、使用指向字符串第一个字符的指针表示,比如arr(arr是数组名,也是指向数组第一个元素的指针,也是指向arr这整个数组的指针,其值实际为"aaa"字符串所在的内存地址)。

但是在一些时候,字符串、指针和数组的关系我们常常搞混,下面通过一些典型问题来展示它们间的关系:

1、字符串-数组:

代码语言:javascript
复制
#include <iostream>
int main()
{
    using namespace std;
    char arr[] = "aaa";
    cout << arr << endl;
    cout << &arr <<endl;
    cout << arr[0] << endl;
    cout << &arr[0] <<endl;
    return 0;
}

输出:

aaa(arr等同于字符串"aaa",是一个常量,所以直接输出"aaa")

0x7ffeefbff5d8(arr其实还是指向arr整个数组地址的指针,也是指向arr中第1个元素地址的指针,所以&arr输出了其指向的地址值)

a(输出arr第一个元素)

aaa(这个有点不好理解,&arr[0]其实是 char* 类型(指向第一个元素的指针)。 cout会把char*当做字符串,从指向处开始处理,一直输出直到\0,所以输出"aaa"。如果对它解引用 * &arr[0] 就得到单个字符char 类型。或者也可以这么理解:

因为arr[1] = *(arr + 1),所以有&arr[1] = arr + 1,所以有&arr[0] = arr,所以输出相同)

代码中的双引号做了三件事:

1)申请了空间(在常量区),存放字符串"abc";

2)在字符串尾加上'/0';

3)返回字符串地址给arr。

2、字符串-指针:

代码语言:javascript
复制
#include <iostream>
int main()
{
    using namespace std;
    char arr[] = "abc";
    char* pt = arr;
    cout << *pt << endl;
    cout << pt << endl;
    cout << *pt + 1 << endl;
    cout << *(pt + 1) << endl;
    cout << arr[1] << endl;
    cout << &arr[0] << endl;
    cout << &arr[1] << endl;
    return 0;
}

输出:

a(因为arr也是一个指向首元素地址的指针,赋值给pt后,*pt就是取首元素的值)

abc(同输出arr)

98(*pt为a,+1后转为整型,即97+1=98)

b(*(pt + 1) 相当于 arr[1])

b(数组第二个元素值)

abc(&arr[0]其实是 char* 类型(指向第一个元素的指针)。 cout会把char*当做字符串,从指向处开始处理一直输出直到\0,所以输出"abc")

bc(&arr[1]也是 char* 类型(指向第二个元素的指针)。 cout会把char*当做字符串,从指向处开始处理一直输出直到\0,所以输出"bc")

3、数组-指针:

1)

代码语言:javascript
复制
#include <iostream>
int main()
{
    using namespace std;
    char* p;
    p = "aaa";
    cout << p << endl;
    return 0;
}

2)

代码语言:javascript
复制
#include <iostream>
int main()
{
    using namespace std;
    char arr[4];
    arr = "aaa";
    cout << arr << endl;
    return 0;
}

为什么1)可以编译通过而2)会报错?

因为字符串常量"aaa"表达式使用的值其实是这个字符所存储的地址(在常量区),而不是这个字符本身。所以,可以把字符串赋值给指向字符的指针p,而不能把字符串赋值给一个字符数组名(因为字符数组名虽然也是一个指针,但它是一个(指针)常量,是不可变的,放在等号左边会报错)。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档