1、以下程序輸出的結果是
#include <stdio.h>
int main() {
int i=10,j=10;
printf("%d,%d\n", ++i+j++, j--);
}
A、 21,10
B、 20,10
C、 21,9
D、 20,9
答案:B
解析:C語言中函數參數處理順序是從右向左的。所以會先處理最右端的參數,然後依次向左處理。 j--
會先輸出 j 的值 10,再執行 --
操作。這個時候 j 的值會變成 9。繼續到左邊的參數,++i+j++
會先對 i 的值執行 ++
操作變成 11,因爲已經是最左邊的參數了,11 會再加上之前 j 的值 9 作爲最終傳入的參數結果,輸出 20。
2、以下程序輸出結果是
#include <stdio.h>
int main() {
int i = 0;
printf("%d,%d,%d,%d,%d\n", ++i, ++i, i++, ++i, i++);
}
A、 1,2,2,3,3
B、 1,2,2,4,4
C、 5,5,2,5,0
D、 5,4,2,2,0
答案:C
解析:
我們已經知道C語言中函數參數處理順序是從右向左的。但是這裏出現了 ++i
和 i++
先加和後加的區別。在從右往左的處理中,i++
表示符合從右向左處理的前提下,當即處理該參數。++i
表示只是執行 ++i 運算並不將結果作爲最終參數結果,而是將參數位置壓入堆棧,只有當所有參數從右向左處理完畢之後,才從堆棧彈出所有因爲延後操作語句而沒有填入最終結果的參數位置,將最終執行的結果 i,作爲相應的參數值填入。
回到本題,從右往左:
第一個參數 i 先輸出 0 再 ++,i 值變爲 1;
第二個參數先 ++,i 值變爲 2,但由於參數還沒有處理完,並不當成最終參數填入,繼續往左。
第三個參數先輸出 2,再 ++,i 值變爲 3。
第四個參數同第二個參數,只執行 ++ 操作,i 值變爲 4。
第五個參數執行 ++ 操作,i 值變爲 5。因爲所有參數已經處理完畢,所以從堆棧彈出剛纔記錄的所有因爲延後操作沒有填入結果的參數位置,將最終計算的 i 值 5,填入其中。
這樣最終輸出的結果就是 5,5,2,5,0。
3、以下函數值的類型是
fun (float x) {
float y;
y = 3*x - 4;
return y;
}
A、int
B、不確定
C、void
D、float
答案:A
解析:C 語言中,函數值類型的定義可以缺省,此時函數值的隱含類型是整型。
4、以下程序的輸出結果是
#include <string.h>
#include <stdio.h>
main() {
char st[20] = "hello\0\t\‘\\";
printf("%d,%d\n", strlen(st), sizeof(st));
}
A、 9,9
B、 5,20
C、 13,20
D、 20,20
答案:B
解析:strlen
是計算算字符串長度的,並且不包含結束符等特殊符號。sizeof
是計算所佔內存大小的。
5、若有說明 int i,j = 2, *p = &i;,則能完成 i = j 賦值功能的語句是
A、 i = *p
B、*p = *&j
C、 i = &j
D、 i = **p
答案:B
解析:
首先,先了解 “*” 的含義。在聲明中爲了把指針和一般變量區別開,所以在指針變量前加一個 “*”。注意此時 “*” 號只是起一個和普通變量相區別的作用。當 “*” 號不是在聲明語句中出現時,它有了另一個含義,就是表示指針變量指向地址所儲存的值。
回過頭我們再來看 int i,j = 2, *p = &i;
這是一個聲明語句,所以這裏的 “*” 只是一個區別普通變量的作用。可以改寫成 int *p; p = &i;
,意思就是將變量 i 的內存地址賦值給指針 p;
這樣答案中的 *p 沒有出現在聲明語句中,這裏 “*” 的意思就是就是p指針變量指向地址所存儲的值了,也就是 i。
同樣的,答案中 *&j 的意思就是先取 j 對應的內存地址,再取內存地址指向所對應的值,最終還是 j 本身。
6、下列程序輸出的結果是
#include <stdio.h>
main() {
char a[10] = { 9,8,7,6,5,4,3,2,1,0 }, *p = a+5;
printf("%d", *--p);
}
A、 非法
B、 a[4] 的地址
C、 5
D、 3
答案:C
解析:a 是一個字符串數組,數組在內存中是順序存儲的。*p = a+5 也就是把 a+5 的內存地址賦值給 p 了,從下標 0 開始往後數 5 位,這個地址剛好是元素 4 的地址。輸出的時候 *--p
就是元素 4 對應的地址先減一變成 5 的地址,再通過 * 取值剛好就是 5。