指針 地址的思考

#include <iostream>
#include<typeinfo>//---------------------類型判斷
using namespace std;
void main(){

	int a=0;
	int c[]={1,2,3,4,5};
	char b=' ';
	cout<<"c的類型:"<<typeid(c).name()<<'\t'<<"&c的類型:"<<typeid(&c).name()<<endl;//-------------輸出類型
	cout<<"(&c)[0][2]:"<<(&c)[0][2]<<'\t'<<"(*(&c))[2]:"<<(*(&c))[2]<<endl;//--------注:由於符號結合的優先性,&c和*(&c)都要用括號括起來
	cout<<"c:"<<c<<'\t'<<"&c:"<<&c<<'\t'<<"c+1:"<<c+1<<endl; 
	cout<<"sizeof(char *):"<<sizeof(char*)<<'\t'<<"sizeof(int*):"<<sizeof(int*)<<'\t'<<"sizeof(double*):"<<sizeof(double*)<<endl;


    int *ptr1=(int *)(&c+1);//----------對於地址加一是加多少地址,可以先看其類型,然後推知,,,此處即行指針加一變成下一行,然後-1指回上一行的5,所以ptr1[-1]爲5
    int *ptr2=(int *)((int)c+1);//---c爲int*地址,轉化int加一之後指向內存中16進制的字節:第二個00(因爲整數1在內存中地址從低到高排列爲:01 00 00 00)
	//將地址轉化爲int*之後,其取值就是當作int即4個字節來取
	cout<<"(int)c:"<<(int)c<<'\t'<<"(int*)(int)c:"<<(int*)(int)c<<'\t'<<"(int)c+1:"<<(int)c+1<<'\t'<<"(int*)((int)c)+1:"<<(int*)((int)c+1)<<endl;
    int *w = (c + 1);
    cout<<"關於數組C的地址查看:"<<ptr1[-1]<<'\t'<<*ptr2<<'\t'<<(int*)*ptr2<<'\t'<<*w<<endl;//---只有用int*轉化爲16進制地址纔會輸出02 00 00 00,
	//不然輸出的是16進制的10進制整數

    int *p=&a;
	char *q=&b;
	cout<<"&b:"<<&b<<endl;//----c++中遇到字符型指針將其當作字符串輸出(相當於數組名,是字符串地址),從而會得到亂碼
	cout<<"int型地址字節數:"<<sizeof(p)<<"  地址爲:"<<p<<endl;//-----------------可以看到p和q都是一個字節,也就
	//是地址都是32位,即使你在64位電腦上運行,只要你的編譯器是32位,那麼指針地址都是32位即4個字節
	cout<<"char型地址字節數:"<<sizeof(q)<<'\t'<<"  地址爲(int*)q:"<<(int*)q<<endl;//q前面加上這個(int*),就可以正確輸出地址
}

總結:1,字符地址不能直接取地址輸出,比如:char a=' a';時,如果輸出&a就相當於將a當做字符串輸出,因爲&a相當於char *a

2,地址/指針字節數只和編譯器有關

3,指針的類型可以用typeid(變量名).name()輸出,作用:1,)決定了加1後地址增加多少字節;2,)決定了用取值運算符時取幾個字節;

4,

int c[]={1,2,3,4,5};
int *ptr2=(int *)((int)c+1);

cout<<*ptr2<<'\t'<<(int*)*ptr2<<endl;

直接輸出*ptr2不會輸出02000000,只有將其用(int*)強制類型轉化之後纔會輸出02000000,前者相當於輸出十進制,轉化後纔會輸出16進制,即輸出地址

5,一個變量用了&取址之後,該變量類型就會變成原來該變量聲明的基礎上,將變量名改爲(*)的類型,例如char a;中變量a用&之後“&a”的類型就是char *,,如果是char  a[2];,則&a的類型就是char(*)[2],相當於行指針了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章