10.12复习题

  1. 下面的程序将打印什么内容?
    应该会打印出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;
}

这是运行后的结果:
C Primer Plus(第6版)第十章复习题答案-LMLPHP
和预期一样。

  1. 在复习题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};

  2. 在复习题1中,ref的地址是什么?ref + 1是什么意思?++ref指向什么?
    答:ref是数组名(的地址)是数组首元素ref[0]的地址,ref + 1是指数组ref的第二个元素也就是ref[1]的地址,++ref不是有效的表达式因为ref是数组首元素的地址是一个常量,指针变量可以使用递增运算符

  3. 问题:略。
    答:
    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

  4. 在下面的源代码中, ** ptr和 **(ptr+1)的值分别是什么?
    答:
    a. 12和16 ,*(ptr+1)是torf[1][0]的地址
    b. 12和14
    还是花括号的问题

  5. 假设有如下的声明:
    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]数组的地址,这两个地址的值,相同但是类型不同,使用强制类型转换将其转换成相同的类型

  1. 正确声明以下各变量:
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};
  1. 内含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; 						有效
  1. 声明一个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);	//[]中的数字可加可不加

10-07 11:22