C Primer Plus(第6版)第十章複習題答案
10.12複習題
- 下面的程式將列印什麼內容?
應該會打印出ref陣列元素的值,一行倆
#include <stdio.h>
int main(void)
{
int ref[] = {8, 4, 0, 2};
int * ptr;
int index;
for (index = 0, ptr = ref; index < 4; index++, ptr++)
printf("%d %d \n", ref[index], *ptr);
return 0;
}
這是執行後的結果:
和預期一樣。
-
在複習題1中,ref中有多少個元素?
答:4個。 ref[] 讓編譯器來自動識別確定大小,陣列中有8,4,0,2,ref[] = {8, 4, 0, 2}; 相當於ref[] = {8, 4, 0, 2};ref[] 讓編譯器來自動識別確定大小,陣列中有8,4,0,2,ref[] = {8, 4, 0, 2}; 相當於ref[] = {8, 4, 0, 2}; -
在複習題1中,ref的地址是什麼?ref + 1是什麼意思?++ref指向什麼?
答:ref是陣列名(的地址)是陣列首元素ref[0]的地址,ref + 1是指陣列ref的第二個元素也就是ref[1]的地址,++ref不是有效的表示式因為ref是陣列首元素的地址是一個常量,指標變數可以使用遞增運算子 -
問題:略。
答:
a. * ptr的值是12,*(ptr+2)的值16。注意這裡初始化列表中內層無花括號,所以陣列根據列的個數依次初始化, ptr指向的是torf[0][0],ptr是int型指標,所以ptr+2地址增加了 2 *sizeof(int),此時指向第三個元素的值為 16
b. * ptr的值是12, * (ptr + 2)的值14 。因為初始化在內部有花括號未被初始化的值為0 -
在下面的原始碼中, ** ptr和 **(ptr+1)的值分別是什麼?
答:
a. 12和16 ,*(ptr+1)是torf[1][0]的地址
b. 12和14
還是花括號的問題 -
假設有如下的宣告:
int gird[30][100];
這道題的中文翻譯有問題,看看原文是怎麼寫的 Suppose you have the following declaration: int grid[30][100];. a. Express the address of grid[22][56] one way. b. Express the address of grid[22][0] two ways. c. Express the address of grid[0][0] three ways. a. 用1種寫法表示gird[22][56]的地址 &grid[22][56] b. 用2種寫法表示gird[22][0]的地址 &gird[22][0], gird[22] //gird+22這種行不行??應該可以 c. 用3種寫法表示gird[0][0]的地址 &gird[0][0] (int *) gird //注意看下面紅字,強制轉換為指向int型別的指標, //gird[0][0]也指向int型別 gird[0]
注意這裡fird是內含100個元素的gird[0]陣列的地址,這兩個地址的值,相同但是型別不同,使用強制型別轉換將其轉換成相同的型別
- 正確宣告以下各變數:
Create an appropriate declaration for each of the following variables:
a. digits is an array of 10 ints .
b. rates is an array of six floats .
c. mat is an array of three arrays of five integers.
d. psa is an array of 20 pointers to char .
e. pstr is a pointer to an array of 20 chars .
a. digits是一個內含10個int型別值的陣列
int digits[10];
b. rates是一個內含6個float型別的陣列
float rates[6];
c. mat是一個內含3個元素的陣列,每個元素都有5個int型別的陣列
int mat[3][5];
d. psa是一個內含20個元素的陣列,每個元素都指向char型別
char * psa[20]; //指標陣列
e. pstr是一個指向陣列的指標,該陣列中含20個char型別的值
char (*pstr)[20];
// a. 宣告一個內含6個int型別值的陣列,並初始化個元素為1,2,4,8,16,32
int arr[6] = {1, 2, 4, 8, 16, 32};
// b. 用陣列表示法表示a宣告的陣列的第3個元素(其值為4)
arr[2];
// c. 假設編譯器支援C99/C11標準,宣告一個內含100個int型別值的陣列,
並初始化最後一個元素為-1,其他元素不考慮
int arr[100] = {[99] = -1};
// d. 假設編譯器支援C99/C11標準,宣告一個內含100個int型別值的陣列,
並初始化下標為5、10、11、12、13(書上少印了1)的元素為101,其他元素不考慮
int arr[100] = {[5] = 101, [10] = 101, 101, 101, 101};
-
內含10個元素的陣列下標範圍是什麼?
答:int arr[10]; arr[0]~arr[9]陣列從0開始計
Suppose you have these declarations:
float rootbeer[10], things[10][5], *pf, value = 2.2;
int i = 3;
Identify each of the following statements as valid or invalid:
a. rootbeer[2] = value; 有效
b. scanf("%f", &rootbeer ); 無效 應該指定一個下標元素的
c. rootbeer = value; 無效 應該指定一個下標元素的
d. printf("%f", rootbeer); 無效 應該指定一個下標元素的
e. things[4][4] = rootbeer[3]; 有效
f. things[5] = rootbeer; 無效 不能用陣列賦值
//錯誤的想法:有效 都是指向float的指標,
g. pf = value; 無效 pf是指標
h. pf = rootbeer; 有效
- 宣告一個800 x 600的 int 型別陣列
int arr[800][600];
下面聲明瞭3個數組:
double trots[20];
short clops[10][30];
long shots[5][10][15];
a. 分別以傳統方式和以變長陣列為引數的方式編寫處理trots陣列的void函式原型和函式呼叫
傳統方式void function1(double * dp, int row);
函式呼叫function1(trots, 20);
變長陣列void function1(int row, double arr[row]);
函式呼叫function1(20, trots);
b. 分別以傳統方式和以變長陣列為引數的方式編寫處理trots陣列的clops函式原型和函式呼叫
傳統方式void function2(short ar[][30], int row);
函式呼叫function1(clops, 10);
變長陣列void function2(int row, int col, short arr[row][col]);
函式呼叫function2(10, 30, clops);
c. 分別以傳統方式和以變長陣列為引數的方式編寫處理trots陣列的shots函式原型和函式呼叫
傳統方式void function3(long * [][10][15], int row);
函式呼叫function3(shots, 5);
變長陣列void function3(int x, int y, int z, long arr[x][y][z]);
函式呼叫function3(5, 10, 15, shots);
下面有兩個函式原型:
void show(const double ar[], int n); //n是陣列元素的個數
void show2(const double ar[2][3], int n); //n是二維陣列的行數
a. 編寫一個函式呼叫,把一個內容含8, 3, 9和2的複合字面量傳遞給show()函式
show((int []) {8, 3, 9, 2}, 4);
show((int [4]) {8, 3, 9, 2}, 4); //[]中的數字可加可不加
b. 編寫一個函式呼叫,把一個2行3列的複合字面量(8、3、9作為第1行,5、4、1作為第2行)
show2((int [][3]) {{8, 3, 9}, {5, 4, 1}}, 2);
show2((int [2][3]) {{8, 3, 9}, {5, 4, 1}}, 2); //[]中的數字可加可不加