你会做吗?《C语言程序设计与大学教程》习题及答案(第八章)
第八章 习题答案注:以下程序均在Dev C++4.9.9.2中调试通过!
1. 某函数原型声明为:void sort(int x, int y, int z);,函数体内按从小到大的顺序输出形参,请给出该函数定义。
答:
#include <stdio.h>
#include <stdlib.h>
void sort(int x, int y, int z)
{
int temp = 0;
if(x > y) /*交换完后,小的在前面, y x z*/
{
temp = x;
x = y;
y = temp;
}
if(y > z) /*交换完后,z x y*/
{
temp = y;
y = z;
z = temp;
}
if(x > y) /*交换完后,z y x*/
{
temp = x;
x = y;
y = temp;
}
printf("%d %d %d\n", x, y, z);
return;
}
int main(void)
{ /*测试*/
sort(1,2,3);
sort(3,2,1);
sort(1,3,2);
sort(2,3,1);
sort(2,1,3);
sort(3,1,2);
system("PAUSE");
return 0;
}
2. 某函数原型声明为:void sort(char *s1, char *s2, char *s3);,函数体内按从小到大的顺序输出形参,请给出该函数定义。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1000
void sort(char *s1, char *s2, char *s3)
{
char *tempStr = (char *)malloc(MAX_LEN);
if(strcmp(s1, s2) > 0)
{
strcpy(tempStr, s1);
strcpy(s1, s2);
strcpy(s2, tempStr);
}
if(strcmp(s2, s3) > 0)
{
strcpy(tempStr, s2);
strcpy(s2, s3);
strcpy(s2, tempStr);
}
if(strcmp(s1, s2) > 0)
{
strcpy(tempStr, s1);
strcpy(s1, s2);
strcpy(s2, tempStr);
}
free(tempStr);
printf("%s %s %s\n", s1, s2, s3);
}
int main(void)
{ /*测试*/
char s1[MAX_LEN] = "abcd";
char s2[MAX_LEN] = "abde";
char s3[MAX_LEN] = "abef";
sort(s1, s2, s3); /*不要使用:sort("abce", "abde", *abef");调用形式 为什么?*/
/*因为形参是指针,指针得有所指才行!*/
sort(s1, s3, s2);
sort(s2, s1, s3);
sort(s2, s3, s1);
sort(s3, s2, s1);
sort(s3, s1, s2);
system("PAUSE");
return 0;
}
3. 某函数原型声明为:int maxInArray(const int *const p, const int size);,形参p指向一维int型数组,size为一维数组的大小。函数体内要求找到一维数组中的最大值,并返回该值。请给出该函数定义。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int maxInArray(const int *const p, const int size)
{
int i = 0;
int max = INT_MIN;
for(i = 0; i < size; i++)
{
if(max < *(p + i))
{
max = *(p + i);
}
}
return max;
}
int main(void)
{
int a[10] = {10, 1, 3, 5, 6, 9, 111, 32, 4, 19};
int max = maxInArray(&a[0], sizeof(a)/sizeof(a[0]));
printf("max = %d\n", max);
system("PAUSE");
return 0;
}
4. 某函数原型声明为:void tranxMatrix(int ((*p)[ROW_SIZE][COL_SIZE]);,p指向一个行大小为ROW_SIZE、列大小为COL_SIZE的int型二维数组,函数体内实现对该二维数组的转置。请给出该函数定义。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define ROW_SIZE 3
#define COL_SIZE 3
void tranxMatrix(int (*p)[ROW_SIZE][COL_SIZE])
{
int i = 0, j = 0;
int temp;
int *q = (int *)p;
if(NULL == p)
{
printf("p不可为空!\n");
return;
}
if(ROW_SIZE != COL_SIZE)
{
printf("不可转置!\n");
return;
}
for(i = 0; i < ROW_SIZE; ++i)
{
for(j = 0; j < COL_SIZE; ++j)
{
if(i > j)
{
temp = *(q + i * COL_SIZE + j);
*(q + i * COL_SIZE + j) = *(q + j * COL_SIZE + i);
*(q + j * COL_SIZE + i) = temp;
}
}
}
}
int main(void)
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int i = 0, j = 0;
for(i = 0; i < ROW_SIZE; ++i)
{
for(j = 0; j < COL_SIZE; ++j)
{
printf("%4d", a[i][j]);
}
printf("%\n");
}
tranxMatrix(&a);
printf("转置后....\n");
for(i = 0; i < ROW_SIZE; ++i)
{
for(j = 0; j < COL_SIZE; ++j)
{
printf("%4d", a[i][j]);
}
printf("%\n");
}
system("PAUSE");
return 0;
}
5. 一块板上有三根针,A,B,C。A针上套有64个大小不等的圆盘,大的在下,小的在上,如下图(方便起见,图中仅给出了3个圆盘)。要把这64个圆盘从A针全部移至C针上,每次只能移动一个圆盘,移动可以借助B针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上,编程求移动的步骤。要求使用递归函数,并采用本章方法分析递归函数的执行过程。
#include <stdio.h>
#include <stdlib.h>
void move(char from, char to)
{
printf("从%c移到%c.\n", from, to);
}
void hanoi(int n, char A, char B, char C)
{
if(1 == n)
{
move (A ,C); /*只有一个盘子,则将它从A移到C*/
}
else
{
hanoi(n-1, A, C, B);
move(A, C);
hanoi(n-1, B, A ,C);
}
}
int main(void)
{
int m = 3;
printf("%d级汉诺塔移动的方案如下:\n", m);
hanoi(m,'A','B','C');
system("PAUSE");
return 0;
}
6. 请用typedef将long int“改名”为lint。
答:typedef long int lint;
7. 某函数原型为int *sortInHeap();,函数体内首先从堆中申请一块内存区域,p为指向该区域的指针,然后将int型集合{34, 56, 78, 98, 100, 203, 12}中的元素存入该区域。接下去,对这些元素进行降序排序。函数的返回值为指向排序后的堆中区域。请给出函数定义。
#include <stdio.h>
#include <stdlib.h>
int *sortInHeap()
{
#define SIZE 7
int *p = (int *)malloc(SIZE * sizeof(int));
int a[SIZE] = {34, 56, 78, 98, 100, 203, 12};
int temp = 0;
int i = 0, j = 0;
if(NULL == p)
{
printf("无法申请到内存!\n");
return NULL;
}
for(i = 0; i < SIZE; ++i)
{
*(p + i) = a[i];
}
for(i = 0; i < SIZE - 1; ++i)
{
for(j = 0; j < SIZE - 1 - i; ++j)
{
if(*(p + j) < *(p + j + 1))
{
temp = *(p + j);
*(p + j) = *(p + j + 1);
*(p + j + 1) = temp;
}
}
}
for(i = 0; i < SIZE; ++i)
{
printf("%d ", *(p + i));
}
return p;
}
int main(void)
{
int *p = sortInHeap();
if(NULL != p)
{
free(p);
}
system("PAUSE");
return 0;
}
8. 请声明一函数指针,指向标准库中的malloc函数(malloc的原型声明参见本章)。并通过该函数指针从堆中申请一块4字节的内存。
答:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void * (*q)(size_t size);
q = malloc;
int *p = (int*)q(4);
*p = 100;
printf("%d\n", *p);
free(p);
system("PAUSE");
return 0;
}
9. 请分析下述函数的错误。
int * foo()
{
int a = 3;
return &a;
}
答:&a为局部变量的地址,不可作为返回值。
10. 某函数原型为char *str_cat(char *s1, char *s2);,函数功能实现将s1、s2指向的字符串字面值进行连接,返回的指针指向连接后的字符串字面值存储空间。
答:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *str_cat(char *s1, char *s2)
{
#define MAX_LEN 1000
char *s = (char *)malloc(MAX_LEN);
int i = 0, len1 = 0, len2 = 0;
if(NULL == s1 || NULL == s2)
{
return NULL;
}
if(NULL == s1 && NULL != s2)
{
return s2;
}
if(NULL == s2 && NULL != s1)
{
return s1;
}
len1 = strlen(s1);
len2 = strlen(s2);
for(i = 0; i < len1; ++i)
{
s[i] = s1[i];
}
for(i = 0; i < len2; ++i)
{
s[len1 + i] = s2[i];
}
s[len1+len2] = '\0';
return s;
}
int main(void)
{
char s1[10] = "abcd";
char s2[10] = "efgh";
char *s = str_cat(s1, s2);
printf("%s\n", s);
if(NULL != s)
{
free(s);
}
system("PAUSE");
return 0;
}
11. 分析声明语句double *(*a[5])(int, char*);的作用,用typedef简化该声明。
解:(略)
12. 分析声明语句int (*)() (*e)[10];的作用,用typede简化该声明。
解:(略)
13. 请分析下述代码段的错误,并进行改进。foo返回p指向的数组中的第一个元素。
int foo(int (*p)[10]) /*返回p指向的数组中的第一个元素*/
{
/*TODO*/
return *(p + 1); /*有错误吗?:有*/
}
int main(void)
{
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /*有错误吗?:无*/
foo(a); /*有错误吗?:有*/
/*TODO*/
return 0;
}
答:
int foo(int (*p)[10]) /*返回p指向的数组中的第一个元素*/
{
/*TODO*/
/*return *(p + 1);*/ /*有错误吗?:有*/
return *((int*)p + 1);
}
int main(void)
{
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /*有错误吗?:无*/
foo(&a); /*有错误吗?:有*/
/*TODO*/
return 0;
}
14. 设有char *a[5] = {“abcd”, “1889”, “efga”, “666a”, “bcde”};,请编写函数,对a中各指针变量指向的字符串字面值进行排序后输出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sort( )
{
#define MAX_LEN 100
char *a[5] = {"abcd", "1889", "efga", "666a", "bcde"};
char *temp = NULL;
int size = 5;
int i = 0, j = 0;
for(i = 0; i < size - 1; ++i)
{
for(j = 0; j < size - 1 - i; ++j)
{
if(strcmp(a[j], a[j+1]) > 0)
{
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for(i = 0; i < 5; ++i)
{
printf("%s\n", a[i]);
}
}
int main(void)
{
sort( );
system("PAUSE");
return 0;
}
15. 分析下述代码段中,main函数执行过程中,内存的详细变化过程。
void foo(char *s)
{
printf(“%s”, s);
}
int main(void)
{
char *s = malloc(10);
strcpy(s, “abcdef”);
foo(“abdd”);
foo(s);
/*TODO*/
return 0;
}
解:(略)