CC++ 疑難點(不斷更新中……) -开发者知识库

CC++ 疑難點(不斷更新中……) -开发者知识库,第1张

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;
}
CC++ 疑難點(不斷更新中……) -开发者知识库,第2张

CC++ 疑難點(不斷更新中……) -开发者知识库,第2张

1,0,1
1,2147483647,1
1,1,0
請按任意鍵繼續. . .


為什么會這樣?我最開始也沒想明白,我認為自己輸出自己的就好了嘛!~

但是情況不是這樣的,輸出結果如上。分析一下原因:(個人見解,可能不對,請指出)

(1)unsigned long long 是8字節的,int是4字節的。(32位機器)

(2)%d,是不進行安全檢查的,都只是去取4個字節使用。

(3)現在的X86的機器都是使用的內存小端存儲的方式。這3個變量在內存中的位置如下:

CC++ 疑難點(不斷更新中……) -开发者知识库,第2张CC++ 疑難點(不斷更新中……) -开发者知识库,第2张0x0012FF08  class="superseo">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成員函數產生編譯錯誤。



最佳答案:

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复