1、cout和 指针输出
#include <iostream>
using namespace std;
int main(){
char s[] = "012345678", *p = s;
cout << *p++ << *(p++) << (*p)++ << *++p << *(++p) << ++*p << ++(*p)<< endl;
return 0;
}
cout的运算是从右向左进行的,但最后输出还是从左到右。也就是说,先运算++(*p)从后向前。
(1).++*p:先运算*p,值++:P指向S[0],并把S[0]加1做为表达式的值,所以输出为1,此时S[0]=='1'
(2).++(*p):同1,先运算*p,值++:P还指向S[0](S[0]现在的值为1),并把S[0]加1做为表达式的值,所以输出为2,此时S[0]=='2'
(3).*(++p):指针p位置++,然后*取值:p指向S[1],然后取S[1]的值作为表达式的值,输出'1'
(4).*++p :同3,指针p位置++,然后*取值:P指向S[2],然后取S[2]的值作为表达式的值,输出'2'
(5).(*p)++:同1,先运算*p,值++:P还是指向S[2],取S[2]的值作为表达式的值,所以输出'2',然后S[2]的值加1,S[2]==3
(6).*(p++):先取*p的值,然后指针p位置++:P还是指向S[2](现值为3),取S[2]的值作为表达式的值,所以输出'3',然后P指向S[3]
(7).*p++ :同6,先取*p的值,然后指针p位置++:P指向S[3],取S[3]的值作为表达式的值,所以输出'3',然后P指向S[4];
结果:s数组为 "213345678",输出“3324444”
2、%d的内存读取 和 内存存储
#include <stdio.h>
int main()
{
int i=1;
unsigned long long x = 1;
int n = 2147483647;
printf("%d,%d,%d\n",x,i,n);
printf("%d,%d,%d\n",i,n,x);
printf("%d,%d,%d\n",i,x,n);
return 0;
}
1,0,1
1,2147483647,1
1,1,0
请按任意键继续. . .
为什么会这样?我最开始也没想明白,我认为自己输出自己的就好了嘛!~
但是情况不是这样的,输出结果如上。分析一下原因:(个人见解,可能不对,请指出)
(1)unsigned long long 是8字节的,int是4字节的。(32位机器)
(2)%d,是不进行安全检查的,都只是去取4个字节使用。
(3)现在的X86的机器都是使用的内存小端存储的方式。这3个变量在内存中的位置如下:
0x0012FF08 cc cc cc ccff ff ff 7f ????....
0x0012FF10 cc cc cc cc cc cc cc cc ????????
0x0012FF18 01 00 00 00 00 00 00 00 ........
0x0012FF20 cc cc cc cc cc cc cc cc ????????
0x0012FF28 01 00 00 00 cc cc cc cc ....????
可以看出内存中是 从高位向低位 存放,先声明的i在最内存的高位,而且数据的低字节在低位,高字节在高位,这就是小端存储的原因。
(4)解释(3)可能与本题无关哈,就当拓展下吧。当输出(x,i,n)顺序时,通过(1)(2)可知,第一个%d其实取的是x的前4位也就是低位它的值是1;到第2个i的时候,本来应该取i的内存值,但是发现紧接着第一个%d的值的后面还有4个字节,它就取了这4个字节的数据当值,而这4个字节其实是x的高位值是0;到了第三个%d自然接着向后取到的是原本i的数据。所以输出结果是(1,0,1)。
(5)第二组和第三组,原理是一样的。第三组结果看似正确,是因为最后取的X。其实是X值失去了高位的4字节的值。只不过因为它是0,没有体现出来而已。
(6)出现这样取值的原因,还有就是 printf %d 的 运算顺序是从右向左。但输出的顺序是从左向右进行取值的。
3、const和指针
int * const p = &n; //必须先初始化
*p=20; //OK,值可以改变
p = &n; //ERROR,不能改变指向
const int * p1; //可以不初始化
*p1=20; //ERROR,值不可以改变
p1 = &n; //OK,可以改变指向
int const * p2; //可以不初始化
*p2=20; //ERROR,值不可以改变
p2 = &n; //OK,可以改变指向
const int * const p3 = &n; //必须先初始化
*p3=20; //ERROR,值不可以改变
p3 = &n; //ERROR,不能改变指向
4、const成员函数
class A
{
private:
int m_a;
public:
A() : m_a(0) {}
int getConstA() const
{
return m_a; //同return this->m_a;。
}
int GetA()
{
return m_a;
}
int setConstA(int a) const
{
m_a = a; //这里产生编译错误,如果把前面的成员定义int m_a;改为mutable int m_a;就可以编译通过。
}
int SetA(int a)
{
m_a = a; //同this->m_a = a;
}
};
A a1;
const A a2;
int t;
t = a1.getConstA();
t = a1.GetA();
t = a2.getConstA();
t = a2.GetA(); //a2是const对象,调用非const成员函数产生编译错误。