C程序設計(第五版)第八章(指針)習題答案(手寫系統版)
全部題目以函數的方式存放,在主函數中輸入題號即可運行
以下代碼均經過上機測試(編譯器爲Visual Studio2017)
歡迎相互交流學習!!
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<typeinfo>
void t1();
void t2();
void t3();
void t4();
void t5();
void t6();
void t7();
void t8();
void t9();
void t10();
void t11();
void t12();
void t13();
void t14();
void t15();
void t16();
void t17();
void t18();
void t19();
void t20();
void t21();
void swap (int* a, int* b);
void swap2(char** a, char** b);
void t3_1(int*p, int n);
void t3_2(int*p, int n);
void t3_3(int*p, int n);
void sort(int *p, int n);
void stringSort(char strs[][20], int n);
void stringSort2(char *p[], int n);
void stringSort3(char **p, int n);
double getDef(int up, int low, double(*p)(int, int));
double sin(int up, int low);
double cos(int up, int low);
double ex(int up, int low);
void t15_1(int(*p)[5], int n);
void t15_2(int(*p)[5], int n);
void t15_3(int(*p)[5], int n);
int power(int a, int b);
int myStrcmp(char *p1, char *p2);
char * myNew(int n);
void myFree(char *p);
void matrixSet(int(*p)[5], int n);
void sort2(int **p, int n);
//t19用
#define buffSize 1000
char strArray[buffSize];
char *str = strArray;
int main() {
/*
在各個函數的輸入環節後可加上以下語句,避免影響後來的輸入流
//清空緩存區 避免用戶輸入多餘的字符影響後續操作
int c;
while ((c = getchar()) != '\n' && c != EOF);
*/
int num=0;
int c;
while (true)
{
printf("查看第幾題?\n");
scanf("%d", &num);
if (num < 1 || num>21) {
printf("無此題%d,請重新輸入\n", num);
//清空緩存區非法輸入
while ((c = getchar()) != '\n' && c != EOF);
continue;
}
//讀入回車鍵 清空緩存區 //Bug:需要輸入字符串時少輸入了一行
getchar();
void (*nums[21])() = {t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21};
void(*num_point)() = *(nums + num - 1);
num_point();
//num置0 //Bug: 下一次輸入非數字類型非法字符會進入上一個調用的函數,且緩存區(非法字符)會進入函數調用中
num = 0;
}
}
static void t1() {
printf("請輸入三個整數: \n");
int a, b, c;
int *p1, *p2, *p3;
p1 = &a;
p2 = &b;
p3 = &c;
scanf("%d%d%d", p1,p2,p3);
if(a>b)
swap(p1, p2);
if(a>c)
swap(p1, p3);
if(b>c)
swap(p2, p3);
printf("從小到大順序是: %d %d %d\n", a,b,c);
printf("\n");
}
//t1用
static void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
static void t2() {
printf("please input three strings:\n");
char *str[3];
char s1[100],s2[100],s3[100];
str[0]= gets_s(s1);
str[1] = gets_s(s2);
str[2] = gets_s(s3);
if (strcmp(s1, s2) == 1)
swap2(str, str+1);
if (strcmp(s1, s3) == 1)
swap2(str, str+2);
if (strcmp(s2, s3) == 1)
swap2(str+1, str+2);
printf("now after sort:\n");
for (int i = 0; i < 3; i++)
printf("%s ", *(str + i));
printf("\n");
}
//t2用
//改變形參的值毫無價值,如果形參是指針變量,則能改變指針指向的值,但不能改變指針本身
static void swap2(char** a, char** b) {
char *temp = *a;
*a = *b;
*b = temp;
}
static void t3() {
int a[10];
t3_1(a, 10);
t3_2(a, 10);
t3_3(a, 10);
printf("\n");
}
static void t3_1(int*p,int n) {
printf("please input 10 Integers\n");
for (int i = 0; i < n; i++) {
scanf("%d", p++);
}
}
static void t3_2(int*p, int n) {
int max = *p, min = *p;
int maxIndex = 0, minIndex = 0;
for (int i = 0; i < n; i++) {
if (*(p + i) > max) {
max = *(p + i);
maxIndex = i;
}
if (*(p + i) < min) {
min = *(p + i);
minIndex = i;
}
}
int temp;
temp = *p;
*p = *(p + minIndex);
*(p + minIndex) = temp;
temp = *(p + n - 1);
*(p + n - 1) = *(p + maxIndex);
*(p + maxIndex) = temp;
}
static void t3_3(int*p, int n) {
printf("Output 10 Integers\n");
for (int i = 0; i < n; i++) {
printf("%d ", *(p + i));
}
}
static void t4() {
int n;
printf("please input numbers\n");
scanf("%d", &n);
int *p = (int *)malloc(n * sizeof(int));
printf("please input %d Integers\n",n);
for (int i = 0; i < n; i++) {
scanf("%d", p + i);
}
printf("Show Integers\n");
for (int i = 0; i < n; i++) {
printf("%d ", *(p+i));
}
printf("\n");
int m;
printf("please input the offset\n");
scanf("%d", &m);
int *save = (int *)malloc(n * sizeof(int));
int j = 0;
for (int i = n - m; i < n; i++,j++)
*(save + j) = *(p + i);
for (int i = 0; i < n - m; i++,j++)
*(save + j) = *(p + i);
printf("after deviating: \n");
for (int i = 0; i < n; i++) {
printf("%d ", *(save + i));
}
free(p);
free(save);
printf("\n");
}
static void t5() {
int sum=0;
printf("please input the number of people\n");
scanf("%d", &sum);
//存活人數
int live = sum;
//計數
int count = 0;
//動態數組 不浪費 不流失 不蒸發
int *p = (int *)malloc(sum * sizeof(int));
int *initial = p;
for (int i = 0; i < sum; i++) {
//1爲存活
*(p + i) = 1;
}
printf("before: \n");
for (int i = 0; i < sum; i++) {
printf("%d ", *(initial + i));
}
while (live > 1)
{
//仍存活
if (*p) {
count++;
if (count % 3 == 0) {
*p = 0;
live--;
}
if (p == initial + sum - 1) {
p = initial;
}
else
p++;
}
//已死亡
else
{
if (p == initial + sum - 1) {
p = initial;
}
else
p++;
}
}
printf("\n");
printf("after:\n");
for (int i = 0; i < sum; i++) {
printf("%d ", *(initial + i));
}
printf("\n");
int luckyDog=1;
for (; !*initial++; luckyDog++);
printf("最後倖存者是第%d位",luckyDog);
printf("\n");
}
static void t6() {
char a[100];
printf("please input String\n");
char *p=gets_s(a);
int sum = 0;
while (*p++)
sum++;
printf("該字符串長度爲: %d\n", sum);
printf("\n");
}
//n個字符,從第m個字符開始複製
static void t7() {
char a[100];
printf("please input String\n");
char *p = gets_s(a);
int n = 0;
while (*p++)
n++;
//恢復指針位置
p=a;
int m=0;
printf("Please input the startNumber:\n");
scanf("%d", &m);
char *copy = (char *)malloc((n - m+2) * sizeof(char));
int j = 0;
for (int i = m - 1; i < n; i++,j++) {
*(copy+j) = *(p + i);
}
*(copy+j) = '\0';
printf("The new String:\n");
//puts(copy);
int i = 0;
while (*(copy+i)) {
printf("%c", *(copy+i));
i++;
}
free(copy);
printf("\n");
}
static void t8() {
char a[100];
printf("please input String\n");
char *p = gets_s(a);
char ch;
int lwr = 0;
int upr = 0;
int space = 0;
int num = 0;
int others = 0;
while (ch = *p++) {
if (ch >= 'A'&&ch <= 'Z') {
upr++;
}
else if (ch >= 'a'&&ch <= 'z') {
lwr++;
}
else if (ch == ' ') {
space++;
}
else if (ch >= '1'&&ch <= '9') {
while (*p>='0'&&*p<='9')
{
p++;
}
num++;
}
//數字0需單獨處理
else if (ch == '0') {
num++;
}
else {
others++;
}
}
printf("大寫字母:%d 小寫字母:%d 空格:%d 數字:%d 其他字符:%d\n", upr, lwr, space, num, others);
printf("\n");
}
static void t9() {
int matrix[3][3];
int(*p)[3] = matrix;
printf("please input a matrix: 3*3:\n");
for (int i = 0; i < 3*3; i++) {
scanf("%d", *p + i);
}
printf("The Matrix is: \n");
for (int i = 0; i < 3 * 3; i++) {
if (i % 3 == 0) {
printf("\n");
}
printf("%d ", *(*p + i));
}
for (int i = 0; i < 3; i++) {
for (int j = i+1; j < 3; j++) {
int temp = *(*(p + i) + j);
*(*(p + i) + j) = *(*(p + j) + i);
*(*(p + j) + i) = temp;
}
}
printf("after the transposition of the Matrix:\n");
for (int i = 0; i < 3 * 3; i++) {
if (i % 3 == 0) {
printf("\n");
}
printf("%d ", *(*p + i));
}
printf("\n");
}
void t10() {
int matrix[5][5];
int(*p)[5] = matrix;
printf("please input a matrix: 5*5:\n");
for (int i = 0; i < 5 * 5; i++) {
scanf("%d", *p + i);
}
matrixSet(p,5);
}
//t10用
void sort(int *p, int n) {
int i, j, k,temp;
for (i = 0; i < n-1; i++) {
k = i;
for (j = i + 1; j < n; j++) {
//這裏容易出錯,不是*(p+j)<*(p+i),k保存的是最小的下標,而不是隻比*(p+i)小的下標(k保存的將是最後一個比*(p+i)小的下標)
if (*(p + j) < *(p + k)) {
k = j;
}
}
if (k!=i) {
temp = *(p + i);
*(p + i) = *(p + k);
*(p + k) = temp;
}
}
}
//t10用 形參n表示矩陣的列數
static void matrixSet(int(*p)[5],int n){
printf("The Matrix is: \n");
for (int i = 0; i < 5 * n; i++) {
if (i % n == 0) {
printf("\n");
}
printf("%2d ", *(*p + i));
}
printf("\n\n");
sort(*p, 5 * n);
//最大
swap(*p + 5 * n - 1, *(p + n/2) + n/2);
//第二小
swap(*p + 1, *p + n - 1);
//第三小
swap(*p + 2, *(p + n - 1));
//第四小
swap(*p + 3, *(p + n - 1) + n - 1);
printf("After Reset: \n");
for (int i = 0; i < 5 * n; i++) {
if (i % n == 0) {
printf("\n");
}
printf("%2d ", *(*p + i));
}
printf("\n\n");
}
//字符數組指針
static void t11() {
char strs[10][20];
printf("Please input 10 strings:\n");
for (int i = 0; i < 10; i++) {
gets_s(strs[i]);
}
printf("before:\n");
for (int i = 0; i < 10; i++) {
puts(strs[i]);
}
printf("\n");
stringSort(strs, 10);
printf("After:\n");
for (int i = 0; i < 10; i++) {
puts(strs[i]);
}
printf("\n");
}
//t11用
static void stringSort(char strs[][20], int n) {
int i, j, k;
char temp[20];
for (i = 0; i < n - 1; i++) {
k = i;
for (j = i + 1; j < n; j++) {
if (strcmp(strs[j], strs[k]) < 0) {
k = j;
}
}
if (i != k) {
strcpy(temp, strs[i]);
strcpy(strs[i], strs[k]);
strcpy(strs[k], temp);
}
}
}
//字符指針數組
static void t12() {
char strs[10][20];
char *row[10];
printf("Please input 10 strings:\n");
for (int i = 0; i<10; i++) {
row[i]=gets_s(strs[i]);
}
printf("before:\n");
for (int i = 0; i < 10; i++) {
puts(row[i]);
}
printf("\n");
stringSort2(row, 10);
printf("After:\n");
for (int i = 0; i < 10; i++) {
puts(row[i]);
}
printf("\n");
}
//t12用
static void stringSort2(char *p[], int n) {
int k;
char *temp;
for (int i = 0; i < n - 1; i++) {
k = i;
for (int j = i + 1; j < n; j++) {
if (strcmp(p[j],p[k])<0) {
k = j;
}
}
if (i != k) {
temp = p[i];
p[i] = p[k];
p[k] = temp;
}
}
}
static void t13() {
int upper, lower,n;
double sum;
printf("請輸入定積分類型: 1:sinx 2:cosx 3:ex\n");
scanf("%d", &n);
printf("請分別輸入定積分下限和上限 中間以逗號隔開:\n");
scanf("%d,%d", &lower, &upper);
switch (n)
{
case 1:sum = getDef(upper, lower, sin); break;
case 2:sum = getDef(upper, lower, cos); break;
case 3:sum = getDef(upper, lower, ex); break;
default:printf("輸入錯誤!");
}
printf("該定積分的值是:%lf \n", sum);
}
static double getDef(int up, int low,double (*p)(int,int)) {
return (*p)(up, low);
}
static double sin(int up, int low) {
double sum = 0.0;
double part = (up - low) / 100.0;
for (int i = 0; i < 100; i++) {
sum += part * sin(low+part*(i+0.5));
}
return sum;
}
static double cos(int up, int low) {
double sum = 0.0;
double part = (up - low) / 100.0;
for (int i = 0; i < 100; i++) {
sum += part * cos(low + part * (i + 0.5));
}
return sum;
}
static double ex(int up, int low) {
double sum = 0.0;
double part = (up - low) / 100.0;
for (int i = 0; i < 100; i++) {
sum += part * exp(low + part * (i + 0.5));
}
return sum;
}
static void t14() {
int n;
printf("輸入整數的個數:\n");
scanf("%d", &n);
int *p = (int *)malloc(n * sizeof(int));
int *initial = p;
printf("輸入整數:\n");
for (int i = 0; i < n; i++) {
scanf("%d", p + i);
}
printf("這些數爲:\n");
for (;p<initial+n;) {
printf("%d ",*p++);
}
printf("\n");
printf("逆序輸出這些數:\n");
for (; p>initial;) {
printf("%d ", *--p);
}
printf("\n");
}
static void t15() {
int score[4][5] = { {99,80,90,94,92},{80,60,13,85,59},{99,85,61,92,89},{91,86,95,92,90} };
int(*p)[5] = score;
t15_1(p, 4);
t15_2(p, 4);
t15_3(p, 4);
}
static void t15_1(int(*p)[5],int n) {
int sum = 0;
//p++是錯誤的用法,p是指向數組的地址,不能改變
for (int i=0;i<n;i++) {
sum += **(p+i);
}
//printf("%d\n", **(p+2));
printf("第一門的平均分是: %f\n", sum*1.0 / n);
}
static void t15_2(int(*p)[5], int n) {
for (int i = 0; i < n; i++) {
int fail = 0;
double sum = 0.0;
for (int j = 0; j < 5; j++) {
sum += *(*(p + i) + j);
if (*(*(p + i) + j)<60) {
fail++;
}
}
if (fail >= 2) {
const char *format = "該學號爲%d的學生有兩門以上科目不及格\n";
printf(format, i + 1);
printf("各成績如下:\n");
for(int k = 0; k < 5; k++) {
printf("%d ", *(*(p + i) + k));
}
printf("\n");
printf("平均分是: %f\n",sum*1.0/5);
}
}
}
static void t15_3(int(*p)[5], int n) {
for (int i = 0; i < n; i++) {
int fine = 1;
double sum = 0.0;
double aver = 0.0;
for (int j = 0; j < 5; j++) {
sum += *(*(p + i) + j);
if (*(*(p + i) + j) <=85) {
fine=0;
}
}
aver = sum * 1.0 / 5;
if (fine||aver>90) {
const char *format = "該學號爲%d的學生平均成績90分以上或全部課程成績在85分以上\n";
printf(format, i + 1);
}
}
printf("\n");
}
static void t16() {
//printf("字符與數字差別:%d %d %d \n", 1 - '1', 2 - '2',3-'3');
//printf("指數函數 %d\n",power(10,3));
printf("please input a string:\n");
char str[100];
char *p = gets_s(str);
int a[100];
int *arr = a;
int sum = 0;
char ch;
//10進制
int sys = 10;
while(*p) {
if (*p >= '1'&&*p <= '9') {
int length = 1;
while ((ch = *++p) >= '0'&&ch <= '9') {
length++;
}
//返回數字最後一位
char *inverse = p-1;
int number = 0;
for (int i = 0; i < length; i++) {
number += (*inverse - 48)*power(sys,i);
inverse--;
}
sum++;
*arr++ = number;
}
else if (*p == '0') {
sum++;
*arr++ = 0;
p++;
}
else {
p++;
}
}
arr = a;
printf("一共有%d個整數,它們分別爲:\n", sum);
for (int i = 0; i < sum; i++) {
printf("%d ", *arr++);
}
printf("\n");
}
//t16用
static int power(int a, int b) {
if (a==0) {
if (b == 0) {
return -999;
}
else {
return 0;
}
}
else
{
if (b == 0) {
return 1;
}
int cardinal = 1;
for (int i = 0; i < b; i++) {
cardinal *= a;
}
return cardinal;
}
}
static void t17() {
char a[100], b[100];
printf("Please input two strings:\n");
scanf("%s", a);
scanf("%s", b);
printf("The Major string is %s value=%d\n\n", myStrcmp(a, b)>0?a:b, myStrcmp(a, b));
}
//t17用
static int myStrcmp(char *p1, char *p2) {
while (*p1&&*p2)
{
if (*p1 != *p2) {
return *p1 - *p2;
}
p1++;
p2++;
}
return *p1!=*p2?*p1-*p2:0;
}
static void t18() {
int month;
const char *m[12] = {"January","Febrary","March","April","May","June","July","August","Septemper","October","November","December"};;
printf("Please input the month number:\n");
scanf("%d", &month);
printf("The month is %s", *(m + month-1));
printf("\n");
}
static void t19() {
int n;
printf("輸入開闢n個字符的空間---\n");
scanf("%d", &n);
char *p = myNew(n);
printf("開闢成功---\n");
printf("開始釋放---\n");
myFree(p);
printf("釋放成功--\n");
}
static char * myNew(int n){
if (str + n <= strArray + buffSize) {
str += n;
return (str - n);
}
else {
return NULL;
}
}
static void myFree(char *p) {
if (p >= strArray && p <= strArray + buffSize) {
str = strArray;
}
}
static void t20() {
char strings[5][20];
char *p[5];
char **pp = p;
printf("請輸入5個字符串: \n");
for (int i = 0; i < 5; i++) {
p[i]=gets_s(strings[i]);
}
printf("\n");
printf("before:\n");
for (int i = 0; i < 5; i++) {
puts(p[i]);
}
printf("\n");
stringSort3(pp, 5);
printf("After:\n");
for (int i = 0; i < 5; i++) {
puts(p[i]);
}
printf("\n");
}
//t20用
static void stringSort3(char **p, int n){
int k;
char *temp;
for (int i = 0; i < n-1; i++) {
k = i;
for (int j = i + 1; j < n; j++) {
if (strcmp(*(p + j), *(p + k)) < 0) {
k = j;
}
}
if (i != k) {
temp = *(p + i);
*(p + i) = *(p + k);
*(p + k) = temp;
}
}
}
static void t21() {
int n;
printf("please input the number of array\n");
scanf("%d", &n);
int *arr = (int *)malloc(n * sizeof(int));
int *p[100];
int **pp = p;
printf("please input the array:\n");
for (int i = 0; i < n; i++) {
scanf("%d", arr + i);
p[i] = arr + i;
}
printf("\n");
printf("before:\n");
for(int i = 0; i < n; i++) {
printf("%d ", *(arr + i));
}
printf("\n");
sort2(pp, n);
printf("After:\n");
for (int i = 0; i < n; i++) {
printf("%d ",**(p+i));
}
printf("\n");
}
//t21用
static void sort2(int **p, int n) {
int k;
int *temp;
for (int i = 0; i < n - 1; i++) {
k = i;
for (int j = i + 1; j < n; j++) {
if (**(p+j)<**(p+k)) {
k = j;
}
}
if (i != k) {
temp = *(p + i);
*(p + i) = *(p + k);
*(p + k) = temp;
}
}
}