注:本文是作者以前發表在其個人博客,現在發布到“聚豐開發”專欄
這也是面試時常碰到的題,通常是把一個指針作為函數的輸入參數,在函數內部會改變輸入參數對應的指針,問面試者在函數調用過程中指針的具體內容。
這里我也設計一個這樣的函數,功能是對輸入參數指定的地址連續寫入指定個數的指定內容。問在位置(1)(2)(3)指針p的值,在位置(4)(5)指針 buf的值。
答案是:
位置(1)指針p還沒賦值為空指針0
位置(2)(3)指針p的值均為&data_buf[0]
位置(4)針buf值為&data_buf[0]
位置(5)指針buf值為&data_buf[100]
void fill_buffer(unsigned char* buf,unsigned char data,unsigned char size)
{ //位置(4)
unsigned char i;
for(i=0;i
*buf=data;
buf++;
}
}//位置(5)
void main(void)
{
unsigned char data_buf[256];
unsigned char *p;
p=(char*)data_buf; //位置(1)
fill_buffer(p,0,100); //位置(2)
while(1); //位置(3)
}
可能有的人會疑惑,明明指針p作為函數的參數,在函數中有進行遞增操作,為什么函數返回后在位置三還是保持內容為&data_buf[0]不變?
有這種想法的人理解的邏輯流程如下,看上去也好像有道理。
void main(void)
{
unsigned char data_buf[256];
unsigned char *p;
p=(char*)data_buf;
fill_buffer(p,0,100); p在這里是輸入參數
//unsigned char i;
//for(i=0;i
// *p=data;
// p++; 執行到這里不就是改變了p嗎?
//}
while(1); 函數返回p應該也改變了
}
這種理解自然不對,對于函數的參數,不能簡單的在函數中進行替代理解,以這里的fill_buffer(p,0,100)為例子,函數中并不會對p進行任何處理,而是先將p的值用一個臨時變量保存起來(也可以為寄存器),在函數中使用的是這個臨時變量。
如果用匯編來表示 fill_buffer(p,0,100)的調用過程,參考流程如下:
;lda x 為把x裝到A中
;sta x 為把A的內容存到裝x中
;得到第一個參數
lda p
sta buf_para
;得到第二個參數
lda #0
sta data_para
;得到第三個參數
lda #100
sta size_para
;跳轉到具體函數代碼位置
jsr fill_buffer
從這個流程可以看出指針p實際上沒有被改寫,雖然p所指的位置會被函數寫入指定的內容,函數只是從p得到一個起始地址,在函數內部是通過另外一個指針來改寫這個地址開始位置的內容,在調試中觀察到的寫指針是另外那個指針,并不是p。這也是C函數指針可以做輸入輸出參數,而變量只能做輸入參數的原因。
如func(char *p,char data),函數可以讀p所指的地址內容,也可以向p所指的地址寫入指定內容,但data只能供函數使用,不能將函數中的值反存到data中。
-
C語言編程
+關注
關注
6文章
90瀏覽量
21108 -
面試題
+關注
關注
1文章
11瀏覽量
8011
發布評論請先 登錄
相關推薦
評論