一道题浅析 i++,++i,i+1及(引用)&i的区别
我们可能很清楚i++,++i和i+1级&i的概念,但在实际运用中我们就有可能很容易搞混淆.特别是在递归中区别它们就显得尤为重要了.那首先我们先看一段利用递归逆序字符串的代码,你能回答出这段代码的正确输出吗?
#include <iostream>
using namespace std;
void print(char *s);
void print(char *s){
if(*s) {
print(++s);
cout<<*s<<endl;
}
}
int main(int argc,char **argv)
{
print(argv[]);
cout<<endl;
return ;
}
[disda@disdader bin]$ ./revStr abcd
d
c
b
这段代码时逆序输出字符串,然而仔细观察,我们发现字符a呢?为什么没有输出?那下面来仔细说说:1.*s为a,执行print(b),print(b)被压入堆栈倒数第一层.
2.*s为b,执行print(c),print(c)被压入堆栈倒数第二层. 3.*s为c,执行print(d),print(d)被压入堆栈倒数第三层. 4.*s为d,执行print(\0),print(\0)被压入堆栈倒数第四层.
5.开始跳出print,从上到下弹出堆栈中的内容.得到结果\0dcb.因次a并没有入栈,所以自然不会输出a;
如果此时你想到的是把++i改成i++的话!
#include <iostream>
using namespace std;
void print(char *s);
void print(char *s){
if(*s){
print(s++);
cout<<*s<<endl;
}
}
int main(int argc,char **argv)
{
print(argv[]);
cout<<endl;
return ;
}
这是一个段错误,因为在当*s为d时压入print(d)后s++会指向字符串的空间之外,自然会引起段错误.
想想如果我们将i++改成i+1能得到正确的结果吗?
#include <iostream>
using namespace std;
void print(char *s);
void print(char *s){
if(*s) {
print(s+);
cout<<*s<<endl;
}
}
int main(int argc,char **argv)
{
print(argv[]);
cout<<endl;
return ;
}
[disda@disdader bin]$ ./revStr abcd
d
c
b
a
这次我们得到终于正确的逆序字符串了!但这时我们就有可能有点混乱了.那先解释一下i+1的意义.i+1没有传递这个过程!加过去就结束了,后面i原来是多少还是多少!这点在递归中的时候特别值得注意!而我们如果利用指针的引用也可以解决这道题.
#include<iostream>
using namespace std; void print(char* &s)
{
if(*s){ p(++s); //if条件成立,即进行递归 注意不能进行s++会溢出
cout<<*s; //按反序输出字符串中的各个字符
}
s--;
}
int main(int argv,char **argc)
{
char *str = "iloveyou";
print(str);
cout<<endl;
return ;
}
一道题浅析 i++,++i,i+1及(引用)&i的区别的更多相关文章
- 浅析angular,react,vue.js jQuery使用区别
前端越来越混乱了,当然也可以美其名曰:繁荣.当新启动一个前端项目,第一件事就是纠结:使用什么框架,重造什么轮子? PS:大牛留言讨论那么,希望看完此篇,能够给你一个清晰的认识,或者让你更加地纠结和无所 ...
- 浅析jquery中attr属性和prop属性的区别
最近在做项目的时候,发现到了prop这个属性,然后之前一直使用的是attr属性,觉得感觉上都差不多,jQuery也不可能专门做了两个相同的属性撒.所以就结合这两个属性研究了一下,也谈谈我对他们最简单最 ...
- 浅析指针(pointer)与引用(reference)
在c++函数中,形式参数用引用和用指针都可以起到在被调用函数中改变调用函数的变量的作用.什么时候用引用作参数?什么时候用指针作参数呢 void function (int *ptr); void fu ...
- 浅析JavaScript解析赋值、浅拷贝和深拷贝的区别
文章首发于sau交流学习社区 一.赋值(Copy) 赋值是将某一数值或对象赋给某个变量的过程,分为: 1.基本数据类型:赋值,赋值之后两个变量互不影响 2.引用数据类型:赋**址**,两个变量具有相同 ...
- 浅析JAVA中堆内存与栈内存的区别
Java把内存划分成两种:一种是栈内存,一种是堆内存. 一.栈内存 存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则. 栈内存在函数中定义的“一些基本类型的变量和对象的引用变量”都 ...
- 浅析 python中的 print 和 input 的底层区别!!!
近期的项目中 涉及到相关知识 就来总结一下 ! 先看源码: def print(self, *args, sep=' ', end='\n', file=None): # known special ...
- 浅析php中抽象类和接口的概念以及区别[转]
//抽象类的定义: abstract class ku{ //定义一个抽象类 abstract function kx(); ...... } function aa extends ku{ //实现 ...
- 浅析套接字中SO_REUSEPORT和SO_REUSEADDR的区别
Socket的基本背景 在讨论这两个选项的区别时,我们需要知道的是BSD实现是所有socket实现的起源.基本上其他所有的系统某种程度上都参考了BSD socket实现(或者至少是其接口),然后开始了 ...
- (转)Java集合框架:HashMap
来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...
随机推荐
- 中文路径-接口路径url不能传输中文解决方案
服务端:
- EasyTouch5初步用法和其中的一个Bug
(一)配置部分:一.将预设体拖入场景中,我用的是下图这个预设体,因为既有摇杆又有按钮嘛,两个正好都能学习到 二.改变摇杆和按钮的外观,如下图所示,可以看出这个插件是用UGUI写的,改图片只需要改Ima ...
- ChemDraw Std 14如何标记同位素
ChemDraw软件是一款专业高效的化学绘图工具,能够绘制各种复杂的结构方程式,在基础化学.有机化学.材料化学等领域得到广泛应用.而ChemDraw Std 14 作为ChemDraw 的最新版本,增 ...
- JBPM4.4_jBPM4.4的流程定义语言(设计流程)
1. jBPM4.4的流程定义语言(设计流程) 1.1. process(流程) 是.jpdl.xml的根元素,可以指定的属性有: 属性名 作用说明 name 流程定义的名称,用于显示. key 流程 ...
- MVC源码
http://aspnetwebstack.codeplex.com/ MVC源码
- VC++第三方库配置-OpenSpirit 4.2.0 二次开发
在VS中右击项目,点击属性 1.配置属性--常规--输出目录:Windows\VS2010\debug\ 2.配置属性--常规--中间目录:Windows\VS2010\debug\ 3.配置属性-- ...
- 嵌入式系统UBOOT
一个完整的嵌入式linux系统包含4部分内容:Bootloader.Parameters.Kernel.Root File System.3.4.5.6部分详细介绍了这4部分的内容,这是Linux底层 ...
- C 标准库 - <stdio.h>
一般地,在C语言或C++中,会把用来#include的文件的扩展名叫 .h,称其为头文件. #include文件的目的就是把多个编译单元(也就是c或者cpp文件)公用的内容,单独放在一个文件里减少整体 ...
- Effective C++ —— 定制new和delete(八)
STL容器所使用的heap内存是由容器所拥有的分配器对象管理,不是被new和delete直接管理.本章并不讨论STL分配器. 条款49 : 了解new-handler的行为 当operator new ...
- Android项目结构介绍
src/存放Java源代码gen/中存放系统自动生成的配置文件Android 4.4.2下包含android.jar文件,这是一个Java归档文件,其中包含构建应用程序所需的所有的Android SD ...