#include <iostream>
#include <stdlib.h>
using namespace std;
void f(int n[])
{
int i = sizeof(n);
cout << n << endl;
n++; //ok
cout << n << endl;
cout << "The size of n is:" << sizeof(n) << endl;
}
int main()
{
int m[5]={1,2,3,4,5};
int *p = m;
int *q=NULL;
char cc='a';
char dd='v';
cout <<"The address of m is:"<<(int)m<<endl;
cout <<"The address of p is:"<<p<<endl;
++p;
cout <<"The address of p is:"<<p<<endl;
f(p);
cout <<"The address of p is:"<<p<<endl;
//m++; //error
cout <<"sizeof m is:"<<sizeof(m)<<endl;
cout <<"m is:"<<p[0]<<endl;
cout <<"The address of q is:"<<&q<<endl;
cout <<"The content of q is:"<<(int)q<<endl;
// cout <<"The value of q is:"<<*q<<endl; // error
cout <<"The address of cc is:"<<(int)&cc<<endl;
cout <<"The address of dd is:"<<(int)&dd<<endl;
getchar();
return 0;
}
用dev-c++運行結果如下:
The address of m is:2293584
The address of p is:0x22ff50
The address of p is:0x22ff54
0x22ff54
0x22ff58
The size of n is:4
The address of p is:0x22ff54
sizeof m is:20
m is:2
The address of q is:0x22ff48
The content of q is:0
The address of cc is:2293575
The address of dd is:2293574
我們發現,列印的地址越來越小,為什嗎?
C語言的3個主要儲存區為:堆、棧、全域區;其中堆是程式員自己分配的,必須程式員自己手工釋放,比如malloc/free。棧是系統管理的,自己釋放。像函數中的形參、局部變數都是在棧裡,而且(大部分編譯器中)棧是由高地址向底地址生長,像一個倒扣的捅一樣,參數進棧的順序是先進後出。所以上面列印的地址越來越小。
//m++; //error
這句話為何報錯?因為數組名只是個常量,編譯器沒為它分配空間,所以不能++
// cout <<"The value of q is:"<<*q<<endl; // error
這句話為何報錯,因為q是一個null 指標,null 指標的概念是:指標中的內容為0
我們可以看下面一個小例子:
int i=10;
int * q= = &i;
其為:
××××:××××
××××:10
也即:
q本省自己的地址:i的地址
i的地址:10
q本身的地址可以用&q得到
q指標中的內容可以用(int)q得到,即i的地址
q指標所指向的直可以通過*q得到,即10;本例中:
cout <<"The address of q is:"<<&q<<endl;
cout <<"The content of q is:"<<(int)q<<endl;
就是這意思。
但是本題中,我們是這樣定義 int *q=NULL;這時q指標中所存的地址為0,我們又知道,0地址的內容是作業系統保護的,不能訪問,所以想通過0地址去訪問值是錯誤的,也即此時*p報錯。
所以// cout <<"The value of q is:"<<*q<<endl; 一句是錯誤的
最後我們說說為什麼2次sizeof結果不一樣,一次為20,一次為4
在主函數中的sizeof是算一個數組的大小,數組的大小=數組元素個數*類型大小;即5*4=20,int類型在32位平台下是4位元組大小。
在一個函數中,如果用數組名做形參,那麼編譯器會把其退化為一個指標對待,所以sizeof結果為4,正好是一個指標的大小。所以我們在f函數中可以寫:n++,而在main中m++卻報錯,就是這個原因,一個是指標,一個是數組,指標是變數可以修改,數組名是常量,不可以修改。