C語言裡面的指標問題

2021-08-04 14:17:11 字數 4234 閱讀 2368

一、變數與指標

1.變數

c語言中每次宣告乙個變數,則內存在會申請乙個該變數型別應該佔據的空間.

假設int

型別佔四個位元組(不同系統的位元組數不同),那麼語句

int a;

a=10;

即在記憶體中申請了四個位元組的空間,並將其命名為

a,其值為

10. 2.

變數位址

int型變數

a在記憶體有乙個具體的位址編號,用

&a 可以讀取到,如

print

(「%d

」,&a);

即可列印出變數

a的記憶體位址編號。

3.指標變數

指標其實也是一種變數,語句

int* pointer

;即在記憶體中申請了

int型別變數的空間,將其取名為

pointer.

它和之前的

a其實沒有本質不同。區別在於,

pointer

的內容是某個

int變數的位址。

如pointer = &a

即把變數

a的位址賦給

pointer。

那麼通過語句

printf

(「%d

」,*pointer

)即可列印出

a,這裡

*pointer

即為按照

pointer

的內容定址,得到的具體變數內容。

這裡pointer

裡面存的是

a的位址,那麼按照該位址尋找就得到變數a了,

*pointer

就顯示出

a的內容,即為10;

4.思考

假設給出這樣一段**:

int a, *pi;

a = 10;

pi = &a;

*pi = 20;

printf("%d", a)

那麼列印出的

a值是多少?(20

二、陣列與指標

1.c語言中定義乙個陣列,那麼陣列名實質上是個指標"常量

",比如

int a=;

printf("%d",a);//

得到的是記憶體位置

printf("%d",*a);//

得到第乙個元素

printf("%d",*(a+1));//

得到第二個元素

那麼列印

a得到的就是陣列第乙個元素所在的記憶體編號位置,列印

*a 得到的就是1。

需要注意的是列印

*(a+1)

得到恰好是第二個元素,因為

a是指標變數,加

1其實是加乙個

int型別的寬度

所以a+1

得到的是後乙個元素的位置,從而

*(a+1)

即可得到第二個元素。

再者,a是乙個常量,若使用

a++

這樣的賦值語句會出現編譯報錯。

不過可以將

a的值賦給乙個指標變數

pi,從而就可以使用

pi++

這樣的語句進行遍歷:

inti, *pi, a=

pi = a//將a

的值賦給pi,

pi就記錄了陣列的起始位置

for(i=0;i<4;i++)

以上**就依次列印出了陣列

a的元素,迴圈裡的

pi不能用

a代替。

2.指標常量

除了指標變數,我們也可以宣告乙個指標常量,如下:

int i, a=

int * const pi = a//

注意const

的位置 此時

pi就無法進行

1中的遍歷,因為此時

pi已經是個常量了。

需要注意的是一般定義陣列時:

int * consta = //

這樣不行

int a = //

可以,一般定義陣列的方式

3.const

關鍵字與指標

用const

修飾過的變數不能進行重新賦值,如:

const int ic=20;//

這句等價於

int const ic = 20

,int

和const

哪個放前面都可以

ic = 40 //

這句編譯會出錯

那麼const

修飾指標變數時,會出現

const int * a, int const * a, int * const a

這三種情況,其實前兩種等價;

首先看const int * pi,

這裡const

修飾的是

*pi,所以不能對

*pi直接重新賦值,但是

pi所指向的那個變數可以重賦值

int a = 10;

int b = 20;

const int *pi = &a

pi = &b //pi

是可以重賦值的,

const

修飾的是整個

*pi

b = 40; //

這裡可以用

*pi=40

來更新值嗎?不行,

const

修飾了*pi

printf("%d",*pi); //

得到的是40

這裡pi

還是可變的,只是不能直接對

*pi

進行修改,那麼如果想讓

pi 無法更改怎麼辦呢?這對應第三種情況。

對於int * const pi

,這裡pi

是個常量了,不能重新賦給它另外乙個位址值,但是此時可以對

*pi

重賦值

int a = 10;

int b = 20;

int * const pi = &a;

//pi = &b

是錯的,

pi無法再指向另外乙個位址

a = 80;//

這裡可以用

*pi = 80

來代替

printf("%d",*pi);

所以總結如下:

當const

修飾在pi

前,那麼

pi是個不可更改的值,永遠指向乙個位址,但可以通過

*pi=xx

來更改所指的變數的值。

當const

修飾在*pi

前,那麼不能出現

*pi=xx

這樣的語句,

pi可更改,

pi所指向的變數也可以更改。

4.const

型別指標與

const

型別變數

有三種情況。

情況一:

int *pi

指標指向

const int i常量

const int a = 10;

int *pi;

pi = &a; //

此種情況下據說

vc會報錯,因為

pi指向

a,那麼就可以通過

pi更改

a的值,違背了**初衷

pi = (int*) &a //

強制轉換,

vc編譯通過,但是仍不能

*pi=xx

來修改a的值

但是上面的**在

codeblocks

下面可編譯通過,也能修改

a的值,不過一般最好不要這麼寫

情況二:

const int *pi

指標指向

const int i1

const int a = 10;

const int *pi;

pi = &a; //

編譯通過,不過此時無法通過

*pi或者

a來更新變數的值,但

pi可以重賦值為另乙個變數位址

情況三:

用const int * const pi

宣告的指標

int i;

const int * const pi = &i; //

此時pi

不能更改,

*pi亦不能更改

C 語言 裡面的 指標 , 陣列, 位址算數

如果說,c 語言比較有特色的東西是什麼。我覺得就是,講指標,陣列,位址算數結合在了一起。當然,這也引起了一些問題,使得,c語言的程式非常的靈魂,有些時候,一些寫法對初學者還比較的 晦澀難懂。比如複製字串,可以有下面的幾種寫法。void strcpy char s,char t void strcpy...

C語言 C語言裡面的冒號

原博 看下面一段 cpp view plain copy struct test 這裡提出的問題是,結構體裡面的冒號的作用是什麼。這種冒號的用法不是我隨便杜撰的,而是在實際的 裡面看到的。在c 的函式定義時,引數列表之後可以使用冒號來給變數賦值,這裡的冒號是不是也起著給結構體成員賦預設值的作用呢?是...

C 裡面的編碼問題

1 net中的string只有unicode一種。所以編碼格式的位元組序列轉換成string時最終都是以unicode表示。2 system.text.encoding.default 是取系統的當前ansi 頁的編碼,即當前系統的編碼。在我們的機子上一般都是 gb2312 這就每次用default...