一道题浅析 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集合框架无论是在工作.学习.面试中都 ...
随机推荐
- thinkphp模板中无法给自定义函数传多个参数
1.模板的用法 {:function(param1,param2,param3...)} 2.实例 <td>{:getChannelInfo($adminId,$v['sale_id']) ...
- php把时间戳转换成英文格式
<?php echo "时间格式1:".date("Y-m-d H:i:s ")."<br>";// 2010-06-12 ...
- 第四章 事务(MYBatis)
一个使用 MyBatis-Spring 的主要原因是它允许 MyBatis 参与到 Spring 的事务管理中.而不是给 MyBatis 创建一个新的特定的事务管理器,MyBatis-Spring 利 ...
- 重载 CreateParams 方法[2]: 重载 TForm.CreateParams 方法的几个例子
这里有所有相关参数的解释: http://www.cnblogs.com/del/archive/2008/04/15/1154359.html //最大化窗口 procedure TForm1.Cr ...
- fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
解决方法:设置cpp文件的Precompiled Header属性设置为Not Using Precompiled Headers
- 记录下一个自己不常用的关键字-yield
yield 这个关键字 一直很少用,也不知道具体用途.按照习惯就查询了下MSDN. 意思大致是这样的:在迭代器块中用于向枚举数对象提供值或发出迭代结束信号 表现形式:1. yield return & ...
- jquery插件大全
241个jquery插件—jquery插件大全 免费JQuery插件 推荐12款非常有用的流行 jQuery 插件
- oracle_存储过程_没有参数_更新过期申请单以及写日志事务回滚
CREATE OR REPLACE PROCEDURE A_MEAS_MIINSP_PLAN_UPDATEASvs_msg VARCHAR2(4000);log_body VARCHAR2(400); ...
- Rollup 与 webpack的区别
特性: webpack 拆分代码, 按需加载: Rollup 所有资源放在同一个地方,一次性加载,利用 tree-shake 特性来剔除项目中未使用的代码,减少冗余,但是webpack2已经逐渐支持t ...
- scala函数进阶篇
1.求值策略scala里有两种求值策略Call By Value -先对函数实参求值,在函数体中用这个求出的参数值.Call By Name -先不对函数实参求值,而是函数实参每次在函数体内被用到时都 ...