测试题:
0. 如果不上机,你能看出下边代码将打印什么值吗?
#include <stdio.h>
int main()
{
char matrix[3][5] = {
'I', 'l', 'o', 'v', 'e',
'F', 'i', 's', 'h', 'C',
'.', 'c', 'o', 'm', '!'
};
char *p;
p = &matrix[0][3];
printf("%c", *p);
printf("%c", *p++);
printf("%c", *++p);
printf("\n");
return 0;
}
答:*p:v *p++ :h *++p:m (错误)
答案:vvF
分析:
- 字符指针 p 指向二维数组 matrix 第一行第四个元素('v')
- 由于 p 是一个字符指针(其跨度为一个字符),所以 p++ 指向 matrix 第一行第五个元素('e'),但加加运算符(++)作为后缀使用时,是先使用原来的值再进行加一运算,因此 *p++ 仍然打印 'v',随后指针指向 'e'
- 加加运算符(++)作为前缀使用时,则先让指针(p)指向下一个元素,再间接取出里边的值。由于二维数组实质上是一维数组的线性扩展,所以 ++p 指向的是第二行第一个元素('F')
1. 假如定义了二维数组 int matrix[4][5] = {0};,请问 matrix 和 matrix + 0 的含义一样吗?
答:一样
答案:一样啊,怎么不一样?!
2. 假设有二维数组如下,请问 *(matrix + 1) + 2 的含义是?
char matrix[3][5] = {
'I', 'l', 'o', 'v', 'e',
'F', 'i', 's', 'h', 'C',
'.', 'c', 'o', 'm', '!'
};
答:为 's' 的地址
答:*(matrix + 1) + 2 的含义是一个指向字符变量的指针,其值是二维数组 matrix 第二行第三个元素的地址(即 &matrix[1][2])。
3. 请问 array[x][y][z] 用指针法如何表示?
答:*(*(*(array+x)+y)+z)
答案:*(*(*(array+i)+j)+k)
4. 请问下边代码将打印什么值?
#include <stdio.h>
int main()
{
char array[2][3][5] = {
{
{'x', 'x', 'x', 'x', 'x'},
{'x', 'x', 'o', 'x', 'x'},
{'x', 'x', 'x', 'x', 'x'}
},
{
{'x', 'x', 'x', 'x', 'x'},
{'x', 'x', 'o', 'x', 'x'},
{'x', 'x', 'x', 'x', 'x'}
}
};
printf("%c%c%c%c\n", *(*(*array + 1) + 2), *(*(*(array + 1) + 1) + 2), ***array, *(**array + 1));
return 0;
}
答:ooxx
*(*(*array + 1) + 2) = ‘o’ *(*(*(array + 1) + 1) + 2) = 'o' ***array = 'x' *(**array + 1)) = 'x'
答案:ooxx(这道简直是送分题嘛!)
5. 如果不上机,你能看出下边代码将打印什么值吗?
#include <stdio.h>
int main()
{
int array[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int (*p)[3] = (int (*)[3])&array;
printf("%d\n", p[2][2]);
return 0;
}
答:迷惑了,解不出来(错误)
答案:9
分析:对于初学者来说,这道题的难度级别很高,但当你尝试去理解它其中的原理之后,你会发现对指针的认识又深入了一点儿呢!
等号右边强制将 array 这个一位数组重新划分成 3 * 3 的二维数组,然后用数组指针指向它(本章最后说如果要使用指针来指向二维数组,只能使用数组指针,还记得吗?)。
So,p 指向的应该是这么一个二维数组:
1 2 3
4 5 6
7 8 9
所以,p[2][2] 的结果是 9。
动动手:
0. 编写一个程序,接收用户的输入,并将前 9 个字符以正方形矩阵(3 * 3)的方式输出。
程序实现如下:
答:
#include <stdio.h>
int main()
{
int i = 0;
char str[100];
char *target = str;
scanf("%s",str);
while(i< 9){
printf("%2c",*target++);
i++;
if(i%3 == 0)
{
printf("\n");
}
}
}
答案:
#include <stdio.h>
int main()
{
int matrix[3][3] = {0};
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
matrix[i][j] = getchar();
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%c ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
1. 这次不限制正方形矩阵的尺寸,要求程序自动计算用户输入的字符,并以最大的正方形矩阵输出(比如用户输入 17 个字符,输出 4 * 4 矩阵)。
程序实现如下:
答:
#include <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
char str[100];
char *target = str;
int len,x=0;
int i,j;
fgets(str,100,stdin);
len = strlen(str);
#if 0 //用这种方法算最大的x不行
while(1)
{
x++;
if((x * x) > len);
break;
}
printf("x :%d\n",x);
x = x-1;
#endif
x = sqrt(len);
for(i=0;i<x;i++)
{
for(j=0;j<x;j++)
{
printf("%2c",str[i*x + j]);
}
printf("\n");
}
}
答案:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAX 1024
int main()
{
int length, aver;
int i, j;
char str[MAX];
scanf("%s", str);
length = strlen(str);
aver = sqrt(length);
for (i = 0; i < aver; i++)
{
for (j = 0; j < aver; j++)
{
printf("%c ", str[i * aver + j]);
}
printf("\n");
}
return 0;
}
2. 下表为广州市最近两年(2014年8月份 ~ 2016年8月份)的 PM2.5 检测数据表,请按要求编程。
年\月 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2014 | / | / | / | / | / | / | / | 31.3 | 35.5 | 58.7 | 49.6 | 55.5 |
2015 | 59.8 | 54.9 | 33.1 | 38.2 | 26.6 | 20.5 | 27.8 | 38.5 | 41.5 | 44.7 | 38.1 | 41.5 |
2016 | 34.9 | 36.4 | 47.5 | 37.9 | 30.6 | 23.4 | 26.6 | 34.3 | / | / | / | / |
要求A:编写一个程序,用户输入待查询年月份(输入格式:2015-03),输出该月份的 PM2.5 值。
程序实现如下:
答:
int main()
{
int str[10];
char *target = str;
int year,month;
float PM[3][12]={
{0,0,0,0,0,0,0,31.3,35.5,58.7,19.6,55.5},
{59.8,54.9,33.1,38.2,26.6,20.5,27.8,38.5,41.5,44.7,38.1,41.5},
{34.9,36.4,47.5,37.9,30.6,23.4,26.6,34.4,0,0,0,0}
};
printf("请输入待查询年月份(年-月);");
scanf("%d-%d",&year,&month);
if((year<=2016 && year >= 2014) && (month <=12 && month >= 1) )
{
if(PM[year-2014][month-1] == 0)
{
printf("抱歉,该月份未收录数据!\n");
}
else{
printf("%d年%d月广州的PM2.5值是:%.1f\n",year,month,PM[year-2014][month-1]);
}
}
else{
printf("抱歉,该年份未收录数据!\n");
}
}
答案:
#include <stdio.h>
int main()
{
float pm25[3][12] = {
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 31.3, 35.5, 58.7, 49.6, 55.5},
{59.8, 54.9, 33.1, 38.2, 26.6, 20.5, 27.8, 38.5, 41.5, 44.7, 38.1, 41.5},
{34.9, 36.4, 47.5, 37.9, 30.6, 23.4, 26.6, 34.3, 0.0, 0.0, 0.0, 0.0}
};
int year, month;
printf("请输入待查询年月分(年-月): ");
scanf("%d-%d", &year, &month);
if (year < 2014 || year > 2016 || month < 1 || month > 12)
{
printf("输入数据错误!\n");
}
else
{
year -= 2014;
month -= 1;
if (pm25[year][month])
{
printf("%d年%d月广州的PM2.5值是: %.2f\n", year + 2014, month + 1, pm25[year][month]);
}
else
{
printf("抱歉,该月份未收录数据!\n");
}
}
return 0;
}
要求B:将所有记录的数据打印为横向直方图。
程序实现如下:
答:参考答案
#include <stdio.h>
int main()
{
int year,month;
float max,min;
int i,j,data,step;
float PM[3][12]={
{0,0,0,0,0,0,0,31.3,35.5,58.7,19.6,55.5},
{59.8,54.9,33.1,38.2,26.6,20.5,27.8,38.5,41.5,44.7,38.1,41.5},
{34.9,36.4,47.5,37.9,30.6,23.4,26.6,34.4,0,0,0,0}
};
max=max=PM[1][0];
for(i=0;i<3;i++)
{
for(j=0;j<12;j++)
{
if(PM[i][j])
{
min=min>PM[i][j] ? PM[i][j] : min;
max=max<PM[i][j] ? PM[i][j] : max;
}
}
}
printf("最小值:%.2f ,最大值:%.2f\n",min,max);
// 计算步进值
if ((int)(max - min) > 80)
{
step = 2;
}
else
{
step = 1;
}
//打印直方图
for(i=0;i<3;i++)
{
for(j=0;j<12;j++)
{
data=PM[i][j];
if(data)
{
printf("%d年%2d月: ", i + 2014, j + 1);
while (data >= min)
{
printf("*");
data -= step;
}
printf("\n");
}
}
}
}
答案:
#include <stdio.h>
int main()
{
float pm25[3][12] = {
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 31.3, 35.5, 58.7, 49.6, 55.5},
{59.8, 54.9, 33.1, 38.2, 26.6, 20.5, 27.8, 38.5, 41.5, 44.7, 38.1, 41.5},
{34.9, 36.4, 47.5, 37.9, 30.6, 23.4, 26.6, 34.3, 0.0, 0.0, 0.0, 0.0}
};
int i, j, step;
float min, max, data;
// 找出最大值和最小值
min = max = pm25[1][0];
for (i = 0; i < 3; i++)
{
for (j = 0; j < 12; j++)
{
if (pm25[i][j])
{
min = min > pm25[i][j] ? pm25[i][j] : min;
max = max < pm25[i][j] ? pm25[i][j] : max;
}
}
}
// 计算步进值
if ((int)(max - min) > 80)
{
step = 2;
}
else
{
step = 1;
}
printf("最小值: %.2f, 最大值: %.2f\n", min, max);
// 打印直方图
for (i = 0; i < 3; i++)
{
for (j = 0; j < 12; j++)
{
data = pm25[i][j];
if (data)
{
printf("%d年%2d月: ", i + 2014, j + 1);
while (data >= min)
{
printf("*");
data -= step;
}
printf("\n");
}
}
}
return 0;
}