打印结果的问题

看到一系列前缀++和后缀++和cout的东西,首先我要说的是,这根cout运算符没什么关系,可以试下printf是一样的。

有一点原则是:首先要计算后面的,原因跟汇编有关。所以函数的入口参数都是从右边算到左边。

就像c++的构造函数的:初始化,其实先初始化的是最右边的变量。

先说几个例子:

int i=0;

(1)cout<<i<<i++<<endl;

(2)cout<<i++<<i<<endl;

(3)cout<<++i<<i<<endl;

(4)cout<<i<<++i<<endl;

说下计算思想:先算靠近endl(最右边的)。

然后注意一点:

(++i表示取i的地址,对他的内容进行+1操作,然后把值放在寄存器。

i++表示取i的地址,把它的值装入寄存器,然后对内存中i的值执行+1操作。

由于我们使用的都是寄存器的值。所以有这样的结果。)

所以(1)1 0(2)0 1(3)1 1(4)1 1(不会真有人一个一个输进去试吧?)

以上的比较简单,但是有难得了

(1)cout << i++ << i++ << endl;

(2)cout << i++ <<++ i << endl;

(3)cout << ++i << i++ << endl;

(4)cout << ++i << ++i << endl;

有人无聊可以自己猜想下结果,然后vs一下,应该对不过半数吧?

再补充个概念:

左值和右值。左值就是可以出现在表达式左边的值(等号左边),可以被改变,它是存储数据值的那块内存的地址,也成为变量的地址;右值是指存储在某内存地址中的数据,也称为变量的数据。

左值可以作为右值,但是右值不可以是左值。

i++不能当做左值使用,++i可以当左值使用。

意思可以这样理解:i++是像函数一样可以返回的,它不可以被赋值。而++i(需要特别注意)是直接更新当前内存。

另外cout的执行过程可以这样理解:首先从右到左计算,最后再一次性把这坨东西显示到UI上。

所以,以后遇到i++,可以认为它返回了,也就是说i++输出的值是基于之前运算过的,不会再变(因为它已经更新的寄存器里面了)。而++i执行了自己的自增运算,但是在cout时,最后还要访问一遍自己的内存,也就是说它显示了自己最新的数据。

我拿cout<<++i<<i++<<++i<<endl;举例:

首先看到最右边的++i。

(1)i初始为0,经过++i,内存被更新了i为1了,但是并没有被cout显示到UI上

(2)到第二个i++,此时读i的值是1,直接返回i的值(cout已经记住了i为1,要默默念,默默念)。之后再给i的内存中的原来的值(为1)加上1,此时内存的值为2

(3)到最左边的++i。读i的内存,i为2,此时给内存值直接加上1,内存值为3.

(4)要cout了,从左向右看。第一个没有疑问是3,第二个刚才说过了(相当于返回1,不懂就看第(2)步),第三个,此时要访问i内存,i的内存是3

(5)输出3 1 3

可以用这种分析方法了专门针对无聊的cout输出。

时间: 2024-08-29 21:07:42

打印结果的问题的相关文章

c打印9*9乘法表

c打印9*9乘法表(这里提供了两种打印方法).乘号两边有规律可寻,其左边递减,右边递增. 1 #include <stdio.h> 2 int main() 3 { 4 int i, j, result; 5 for (i = 9; i >= 1; i--) //外层循环,从9开始,每次循环自减1 6 { 7 for (j = 1; j <= i; j++) //内层循环,从1开始,每次循环自加1 8 { 9 result = i*j; 10 printf("%d*%d=

按之字形顺序打印二叉树

题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } }; */ class Solution { public: vector<vect

设计一个程序能够将某一个目录下面的所有文件名打印出来---File类的使用

,设计一个程序能够将某一个目录下面的所有文件名打印出来 运用到的方法有:返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录:list()           测试此抽象路径名表示的文件是否是一个目录:isDirectory()           返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件:listFiles() package printfilename; import java.io.File; public class PrintFileNam

linux提取指定列字符并打印所有内容(awk)

假设有文件长如下样子: CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT  samplename 1 3552841 . G . 32.995 . DP=1;MQ0F=0;AF1=0;AC1=0;DP4=1,0,0,0;MQ=40;FQ=-29.9912 GT:PL:DP 0/0:0:1 1 3552842 . T . 32.995 . DP=1;MQ0F=0;AF1=0;AC1=0;DP4=1,0,0,0

完成打印购物小票并计算积分

import java.util.Scanner; /** * @author 蓝色以太 * 完成打印购物小票并计算积分 */ public class ShoppingReceipt { public static void main(String[] args) { Scanner sc=new Scanner(System.in); final int NUM1=245,NUM2=570,NUM3=320; System.out.println("请输入购买T恤数量:"); in

题目:打印出如下图案(菱形)

×× ×××××× ×××××××××× ×××××× ×× class HomeWork0604{public static void main (String[] args){int i,j,k;for(i=0;i<=3;i++) //控制前三行 { for(j=0;j<(2*(3-i));j++) //控制前三行空格System.out.print(" ");for(k=0;k<(4*i-2);k++) //控制前三行* System.out.print(&qu

java初学打印星星以及九九乘法表

Java中打印星星,就是为了让初学者熟悉和掌握循环的使用方法: 给定一个图形如: * *** ***** ******* 第一种方式:由循环输出各个部分,再结合起来 for(int i=1;i<=4;i++){< p=""> for(int j=1;j<=7-i;j++){< p=""> system.out.print(" "); } for(int j=1;j<=2*i-1;j++){< p=&

Citrix XenApp和XenDesktop 打印系统解析③

Citrix Universal PrintServer(UPS) 3.3.1.Citrix UPS概述 Citrix UniversalPrinter Server(以下简称UPS)是一个XenApp和XenDesktop环境中的一个打印组件,它有助力提高用户在网络打印方面的体验. 首先我们来说,Citrix已经有了UPD为什么还需要推出UPS?根据前文我们的描述,Citrix UPD只是解决了基于客户端的打印问题(当然并不是完全解决,部分驱动还存在兼容问题),而对于网络打印呢?Citrix

打印W图案

一:规律 二维图形的展示都可以使用二维数组来解决,W图形x轴0,1,2,1,0,1,2.....在0到2直接来回的徘徊 y轴是在一直递增........ 二:代码 1 @Test 2 /** 3 * 测试打印w图案 4 */ 5 public void testPrintW() { 6 int[][] arr = new int[3][9]; 7 // 初始化x,y 8 int x = 2; 9 int y = 0; 10 boolean flag = false; 11 for (int i

Linux C打印IP地址信息

1.由文件描述符打印IP地址及端口.(参考) #include <stdio.h> #include <netdb.h> #include <sys/socket.h> #include <arpa/inet.h> //由文件描述符打印对应IP地址和端口 void PrintAddrByFd(int sockfd) { struct sockaddr_in addr_in; socklen_t len = sizeof(addr_in); getsockna