扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
请看下面的例子:
#include <iostream>
using std::cout;
using std::endl;
const char *st = "c++";
void c_char()
{
int len = 0;
while(*st++)
++len;
st = st - len;
cout << len << ":" << st << endl;
}
st在内存中的分配大概是这样子的(为了分析方便,地址编址从0开始):
地址: 0 1 2 3 4 5
-------------------------
C + + 0
程序的执行结果可能令你吃惊(如果你认为后缀式自增是先使用再自增的话).
const char *st = "c++"
这一句令 st 指向字符串在内存中的首地址(废话一下:B),在这个例子中是指向地址为0的地方.接下来我们来分析while循环的执行情况:
一. 我们来分析如果是先使用再自增程序执行结果应该是怎样的:
如果 st 令 while的条件式 为真的话,那么 st 自增, len = len + 1, 否则退出while循环.
步骤 old_st while条件 st len
-----------------------------------------------
1 0 真 1 1
2 1 真 2 2
3 2 真 3 3
4 0 假
执行到第4步的时候,while条件为假,所以退出while循环, len = 3, st应该是指在地址为 3 的地方.
所以 st = st - len -> st = 3 - 3 -> st = 0. 故程序的输出应该是
3:c++
可是如果你有执行上面的程序的话,你就会发现,情况并不是这样的!那到底是哪里出错了呢?就是后缀式自增是先使用再自增这个基本假设是错的!
二. 我们再来分析一下自增是先自增再使用的情况会是怎样:
st 先自增,并返回原值,如果 原值 令 while的条件式 为真的话, len = len + 1,否则退出while循环.
步骤 st old_st while条件 len
-----------------------------------------------
1 1 0 真 1
2 2 1 真 2
3 3 2 真 3
4 4 3 假 3
执行到第4步的时候,while条件为假,所以退出while循环.此时, st 指向地址为 4 的地方,即已经逾过了字符串的尾(pass-the-end),如果有接触过STL,对逾尾指针这个概念应该是很熟悉的:B
所以 st = st - len -> st = 4 - 3 -> st = 1
故程序的输出应该是: 3:++
不过这应该不是我们想要的结果:B
想正确输出字符串,程序应该改为: st = st - len - 1;
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者