C语言程序设计精髓 第十一周 指针的孪生兄弟

从这一章开始难度才算是真正开始加大了,前面可以说都在过家家。

练兵区——编程题——不计入总分

1找出按字典顺序排在最前面的国名(4分)

题目内容:
输入5个国名,编程找出并输出按字典顺序排在最前面的国名。
提示:所谓字典顺序就是将字符串按由小到大的顺序排列,因此找出按字典顺序排在最前面的国名指的就是最小的字符串。

#include<stdio.h>
#include<string.h>
#define NUM 5
#define STR_LEN 10void findMinimumStr(char *str, int row, int column);int main(){// we haven't learned how to define dynamic array char country[NUM][STR_LEN];printf("Input five countries' names:\n");for(int i = 0; i < NUM; i++){gets(country[i]);}findMinimumStr(*country, NUM, STR_LEN);printf("The minimum is:%s\n", country[0]);return 0;
}// search by row needle, so that we can ignore the size of array
void findMinimumStr(char *str, int row, int column){char temp[column];for(int i = 0; i < row - 1; i++){for(int j = 1; j < row - i; j++){if(strcmp(str + j * column, str + (j - 1) * column) < 0){// swapstrncpy(temp, str + j * column, column);strncpy(str + j * column, str + (j - 1) * column, column);strncpy(str + (j - 1) * column, temp, column);}}}
}
  • 为了练习指针的使用,函数里没有用传统的下标来遍历数组,而是使用列指针来访问数组。
  • 球球别写这种code了,因为没有初始化指针,搁着乱用指针!(感觉自己有点蠢
    char *temp = NULL;
    *temp = "ddd";
    

    所以试图使用char *country[];但是没有初始化的指针数组,来存储多个不同长度的字符串方式是不可取的!

  • 切记:对指针进行的运算操作,加上或减去的是sizeof(基类型)
    • 例如: char str[2][3]
      对于str++等同于:str + sizeof(char [3])
      对于str[0]++等同于:str + sizeof(char)
    • 再例如:str + j * column,来遍历多维字符数组,每一纬度代表一个字符串,为什么要加j * column?因为传入的是一个字符指针,它指向str[0][0],要指向第j个字符串,注意指针的指针char *str的基类型,str + j只是指向了str[0][1],而不是str[1][0]!
  • 另外,这道题不能用前面视频里那样:字符指针数组 + 交换指针提升效率。因为我们还没学到动态数组,所以只能采取最原始的方式。

3月份表示(4分)

题目内容:
用指针数组保存表示每个月份的英文单词以及“Illegal month”的首地址,然后编程实现:从键盘任意输入一个数字表示月份值n,程序输出该月份的英文表示,若n不在1~12之间,则输出“Illegal month”。

#include<stdio.h>int main() {int input;char *month[] = {"Illegal month", "January", "Feburary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};printf("Input month number:\n");scanf("%d", &input);if(input > 0&&input <= 12){printf("month %d is %s\n", input, month[input]);}else printf("%s\n", month[0]);return 0;
}

4程序改错——1(4分)

题目内容:
从键盘任意输入m个学生n门课程的成绩,然后计算每个学生各门课的总分sum和平均分aver。下面程序存在极为隐蔽的错误,请分析错误的原因,并修改程序,同时按照给出的程序运行示例检查修改后的程序。

#include  <stdio.h>
#define STUD 30            //最多可能的学生人数
#define COURSE 5             //最多可能的考试科目数
void  Total(int *score, int sum[], float aver[], int m, int n);
void  Print(int *score, int sum[], float aver[], int m, int n);
int main(void)
{int     i, j, m, n, score[STUD][COURSE], sum[STUD];float   aver[STUD];printf("Enter the total number of students and courses:\n");scanf("%d%d",&m,&n);printf("Enter score:\n");for (i=0; i<m; i++){for (j=0; j<n; j++){scanf("%d", &score[i][j]);}}Total(*score, sum, aver, m, n);Print(*score, sum, aver, m, n);return 0;
}void  Total(int *score, int sum[], float aver[], int m, int n)
{int  i, j;for (i=0; i<m; i++){sum[i] = 0;for (j=0; j<n; j++){sum[i] = sum[i] + *(score + i * COURSE + j);}aver[i] = (float) sum[i] / n;}
}void  Print(int *score, int sum[], float aver[], int m, int n)
{int  i, j;printf("Result:\n");for (i=0; i<m; i++){for (j=0; j<n; j++){printf("%4d", *(score + i * COURSE + j));}printf("%5d%6.1f\n", sum[i], aver[i]);}
}

5程序改错——2(4分)

题目内容:
下面主函数调用函数SortString()按奥运会参赛国国名在字典中的顺序对其入场次序进行排序,目前程序存在错误,请修改正确,并按照给出的程序运行示例检查修改后的程序。

#include  <stdio.h>
#include  <string.h>
#define   M  150 /* 最多的字符串个数 */
#define   N  10 /* 字符串最大长度 */
void SortString(char ptr[][M], int n);
int main()
{int    i, n; char   pStr[N][M];printf("How many countries?\n");scanf("%d",&n);getchar();        /* 读走输入缓冲区中的回车符 */printf("Input their names:\n");for (i=0; i<n; i++)  {gets(pStr[i]);  /* 输入n个字符串 */}SortString(pStr, n); /* 字符串按字典顺序排序 */printf("Sorted results:\n");for (i=0; i<n; i++)                    {puts(pStr[i]);  /* 输出排序后的n个字符串 */}return 0;
}
void SortString(char ptr[][M], int n)
{int   i, j;char temp[M];for (i=0; i<n-1; i++)    {for (j=i+1; j<n; j++){ // 交换排序if (strcmp(ptr[j], ptr[i]) < 0)    {strncpy(temp, ptr[i], M);strncpy(ptr[i], ptr[j], M);strncpy(ptr[j], temp, M);} }   }
}

6找数组最值(4分)

题目内容:
按如下函数原型编程从键盘输入一个m行n列的二维数组,然后计算数组中元素的最大值及其所在的行列下标值。其中,m和n的值由用户键盘输入。已知m和n的值都不超过10。
void InputArray(int *p, int m, int n);
int FindMax(int *p, int m, int n, int *pRow, int *pCol);//函数返回最大值,pRow和pCol分别返回最大值所在的行列下标

#include<stdio.h>
#define MAX_SIZE 10void InputArray(int *p, int m, int n);
int  FindMax(int *p, int m, int n, int *pRow, int *pCol);//函数返回最大值,pRow和pCol分别返回最大值所在的行列下标int main(){int arr[MAX_SIZE][MAX_SIZE], row, column, pRow, pCol;printf("Input m,n:\n");scanf("%d,%d", &row, &column);InputArray(*arr, row, column);FindMax(*arr, row, column, &pRow, &pCol);printf("max=%d,row=%d,col=%d\n", arr[pRow][pCol], pRow, pCol);return 0;
}void InputArray(int *p, int m, int n){printf("Input %d*%d array:\n", m, n);for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){scanf("%d", p + i * MAX_SIZE + j);}}
}int  FindMax(int *p, int m, int n, int *pRow, int *pCol){*pCol = 0;*pRow = 0;for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(*(p + i * MAX_SIZE + j) > *(p + *pRow * MAX_SIZE + *pCol)){*pCol = j;*pRow = i;}}}return 0;
}
  • 感觉直接融会贯通了。

7冒泡排序(4分)

题目内容:
采用冒泡法进行升序排序法的基本原理是:对数组中的n个数执行n-1遍检查操作,在每一遍执行时,对数组中剩余的尚未排好序的元素进行如下操作:对相邻的两个元素进行比较,若排在后面的数小于排在前面的数,则交换其位置,这样每一遍操作中都将参与比较的数中的最大的数沉到数组的底部,经过n-1遍操作后就将全部n个数按从小到大的顺序排好序了。

  • 比较基础,所以加上之前思考题两种优化

    • 去除排序开始末尾为有序时的无用排序
    • 去除排序将要结束时数组前面的元素已经有序
#include<stdio.h>
#define N 10void inputArr(int n, int *arr);
void outputArr(int n, int *arr);
void bubbleSort(int n, int *arr); int main(){int n, arr[N];printf("Input n:");scanf("%d", &n);inputArr(n, arr);bubbleSort(n, arr); printf("Sorting results:");outputArr(n, arr);return 0;
}void inputArr(int n, int *arr){printf("Input %d numbers:", n); for(int i = 0; i < n; i++){scanf("%d", arr + i);}
}void outputArr(int n, int *arr){for(int i = 0; i < n; i++){printf("%4d", *(arr + i));}
} void bubbleSort(int n, int *arr){int temp, flag, lastChangeIndex, boundaryPoint = n;for(int i = 0; i < n - 1; i++){flag = 0;for(int j = 1; j < boundaryPoint; j++){if(*(arr + j) < *(arr + j - 1)){temp = *(arr + j);*(arr + j) = *(arr + j - 1);*(arr + j -1) = temp;flag = 1;lastChangeIndex = j; }}boundaryPoint = lastChangeIndex;if(!flag) {break;}}
}

8删除字符串中与某字符相同的字符(4分)

题目内容:
在字符串中删除与某字符相同的字符,要求用字符数组作函数参数。

#include<stdio.h>
#define N 100int deleteDuplicates(char str[], char ch);int main(){char str[N], ch;printf("Input a string:\n");gets(str);printf("Input a character:\n");ch = getchar();deleteDuplicates(str, ch);printf("Results:%s\n", str);return 0;
}int deleteDuplicates(char str[], char ch){int count = 0;char *temp;for(; *str; str++){if(*str == ch){count++;temp = str;while(*temp){*temp = *(temp + 1);temp++;}}}return count;
}

9求最大数和最小数的最大公约数(4分)

题目内容:
从键盘输入10个正整数,求出最大数,最小数,以及他们的最大公约数。要求用数组实现。

#include<stdio.h>
#define N 10void inputArr(int *arr, int size);
void findMinMax(int *min, int *max, int *arr, int size);
int commonDivisor(int a, int b);int main(){int arr[N];int minP;int maxP;printf("Input 10 numbers:\n");inputArr(arr, N);findMinMax(&minP, &maxP, arr, N);int res = commonDivisor(arr[minP], arr[maxP]);printf("maxNum=%d\n", arr[maxP]);printf("minNum=%d\n", arr[minP]);if(res > 0){printf("%d", res);}return 0;
}void inputArr(int *arr, int size){for(int i = 0; i < size; i++){scanf("%d", arr + i);}
}void findMinMax(int *min, int *max, int *arr, int size){*min = 0;*max = 0;for(int i = 0; i < size; i++){if(*(arr + i) < *(arr + *min)){*min = i;}if(*(arr + i) > *(arr + *max)){*max = i;}}
}int commonDivisor(int a, int b){if(a <= 0 || b <= 0) return -1;if(a == b) return a;if(a > b) commonDivisor(a - b, b);else commonDivisor(a, b - a);
}

10数列合并(4分)

题目内容:
已知两个不同长度的降序排列的数列(假设序列的长度都不超过5),请编程将其合并为一个数列,使合并后的数列仍保持降序排列。

#include<stdio.h>
#define N 5void Merge(int a[], int b[], int c[], int m, int n);
void inputArr(int *arr, int size);
void outputArr(int *res, int size);int main(){int m, n, arr1[N], arr2[N], res[2*N];printf("Input m,n:");scanf("%d,%d", &m, &n);printf("Input array a:");inputArr(arr1, m);printf("Input array b:");inputArr(arr2, n); Merge(arr1, arr2, res, m, n);outputArr(res, m + n);return 0;
}void inputArr(int *arr, int size){for(int i = 0; i < size; i++){scanf("%d", arr + i);}
}void outputArr(int *res, int size){for(int i = 0; i < size; i++){printf("%4d", *(res + i));}
}void Merge(int a[], int b[], int c[], int m, int n){int i = 0, j = 0;while(i < m&&j < n){if(*(a + i) >= *(b + j)){*(c + i + j) = *(a + i);i++;}else{*(c + i + j) = *(b + j);j++;}}if(i != m){for(;i < m;i++){*(c + i + j) = *(a + i);}}if(j != n){for(;j < n;j++){*(c + i + j) = *(b + j);}}}

第11周编程题在线测试

1山地训练(4分)

题目内容:
为了能在下一次跑步比赛中有好的发挥,小白在一条山路上开始了她的跑步训练。她希望能在每次训练中跑得尽可能远,不过她也知道农场中的一条规定:女孩子独自进山的时间不得超过M秒(1 <= M <= 10,000,000)。假设整条山路划分成T个长度相同的路段(1 <= T <= 100,000),并且小白用si表示第i个路段的路况,用u、f、d这3个字母分别表示第i个路段是上坡、平地、下坡。小白跑完一段上坡路的耗时是U秒(1 <= U <= 100),跑完一段平地的耗时是F秒(1 <= F <= 100),跑完一段下坡路的耗时是D秒(1 <= D <= 100)。注意,沿山路原路返回时,原本是上坡的路段变成了下坡路段,原本是下坡的路段变成了上坡路段。小白想知道,在能按时返回农场的前提下,她最多能在这条山路上跑多少个路段。请你编程帮助她计算。

#include<stdio.h>
#define T_MAX 100000long Fun(long M, long T, long U, long F, long D, char str[]);int main(){long m, t, u, f, d;char str[T_MAX];printf("Input M,T,U,F,D:");scanf("%ld%ld%ld%ld%ld", &m, &t, &u, &f, &d);printf("Input conditions of road:");scanf("%s", str);long res = Fun(m, t, u, f, d, str);printf("num=%ld\n", res);return 0;
}long Fun(long M, long T, long U, long F, long D, char str[]){long count  = 0, timeUsed = 0;while(*str){if(*str == 'u'){timeUsed += (U + D);}if(*str == 'd'){timeUsed += (U + D);}if(*str == 'f'){timeUsed += 2 * F;}if(timeUsed > M){break;}count++;str++;}return count;
}

2奇偶数分离(4分)

题目内容:
输入n个整数(n从键盘输入,假设n的值不超过100),按奇偶数分成两组并输出。输出两行,第一行为所有奇数,第二行为所有偶数,保持数据的相对顺序与输入顺序相同。

#include<stdio.h>
#define N 100void inputArr(int *arr, int n);
void Seperate(int a[], int n); //数组a[]存放用户输入的n个整数int main(){int n, arr[N];printf("Input n:");scanf("%d", &n);inputArr(arr, n);Seperate(arr, n);return 0;
}void inputArr(int *arr, int n){printf("Input numbers:");for(int i = 0; i < n; i++){scanf("%d", arr + i);}
}void Seperate(int a[], int n){int flag = 1;for(int i = 0; i < n; i++){if(a[i] % 2 != 0){if(flag) {printf("%d", a[i]);flag = 0;}else printf(",%d", a[i]);a[i] = -1;}}flag = 1;for(int i = 0; i < n; i++){if(a[i] >= 0||a[i] % 2 == 0){if(flag) {printf("\n%d", a[i]);flag = 0;}else printf(",%d", a[i]);}}
}

3子串判断(4分)

题目内容:从键盘输入两个长度小于80的字符串A和B,且A的长度大于B的长度,编程判断B是不是A的子串,如果是,则输出”Yes”,否则输出”No”。这里所谓的该串的子串是指字符串中任意多个连续的字符组成的子序列。

#include<stdio.h>
#define N 80int isSubstring(char str1[], char str2[]);int main(){char str1[N], str2[N];printf("Input the first string:");gets(str1);printf("Input the second string:");gets(str2);int res = isSubstring(str1, str2);if(res == 1){printf( "Yes\n");}else if(res == 0){printf("No\n");}return 0;
}   int isSubstring(char str1[], char str2[]){char *temp1, *temp2;while(*str1){temp1 = str1;temp2 = str2;while(*temp2){if(*temp1 != *temp2){break;}temp1++;temp2++;}if(*temp2 == '\0'){return 1;}str1++;}return 0;
}

4星期查找(4分)

题目内容:
任意输入英文的星期几,通过查找如图所示的星期表,输出其对应的数字,若查到表尾,仍未找到,则输出错误提示信息。

#include<stdio.h>
#include<string.h>
#define N 10int search(char *str[], char *target, int size);int main(){char *str[] = {"Sunday", "Monday", "TuesDay", "Wednesday", "Thursday","Friday", "Saturday"}, target[N];printf("Please enter a string:\n");gets(target);int res = search(str, target, 7);if(res >= 0){printf("%s is %d\n", str[res], res);}else{printf("Not found!\n");}return 0;}int search(char *str[], char *target, int size){for(int i = 0; i < size; i++){if(strcmp(*(str + i), target) == 0){return i;}}return -1;
}

哈工大C语言程序设计精髓 第十一周编程题相关推荐

  1. 哈工大c语言编程题中国大学mooc第四周,中国大学MOOC哈工大C语言程序设计精髓第六周编程题答案.doc...

    下面代码的功能是将百分制成绩转换为 5 分制成绩,具体功能是: 如果用户输入的是 非法 字符或者不在合理区间内的数据 (例如输入的是 a,或者 102 ,或-45 等),则程序输出 Input err ...

  2. C语言2020年作业,2020年哈尔滨工业大学C语言程序设计精髓 第七周编程题作业

    /加油加油,这周的题目不难,大家仔细听课就可以做出来!/ 1 n层嵌套平方根的计算(4分) 题目内容: 编写程序利用递归法实现如下所示n层嵌套平方根的计算: 递归函数原型:double Y(doubl ...

  3. 哈工大C语言程序设计精髓第三周

    由于这些代码也是我初学时写的代码,故其中的规范程度及简洁程度并不很好(此处我后来写的有可以参考一下->C语言代码规范),但是能很好的接近出初学者的水平,也更有参考价值!排版不易,喜欢就点个赞吧! ...

  4. 哈工大C语言程序设计精髓第六周

    由于这些代码也是我初学时写的代码,故其中的规范程度及简洁程度并不很好(此处我后来写的有可以参考一下->C语言代码规范),但是能很好的接近出初学者的水平,也更有参考价值!排版不易,喜欢就点个赞吧! ...

  5. 哈工大C语言程序设计精髓第五周

    由于这些代码也是我初学时写的代码,故其中的规范程度及简洁程度并不很好(此处我后来写的有可以参考一下->C语言代码规范),但是能很好的接近出初学者的水平,也更有参考价值!排版不易,喜欢就点个赞吧! ...

  6. 哈工大C语言程序设计精髓第十三周

    由于这些代码也是我初学时写的代码,故其中的规范程度及简洁程度并不很好(此处我后来写的有可以参考一下->C语言代码规范),但是能很好的接近出初学者的水平,也更有参考价值!排版不易,喜欢就点个赞吧! ...

  7. c语言程序设计精髓 第14周练兵题

    1学生成绩管理系统V5.0(4分) 题目内容: 某班有最多不超过30人(具体人数由键盘输入)参加期末考试,最多不超过6门(具体门数由键盘输入).参考学生成绩管理系统V4.0,定义结构体类型,用结构体数 ...

  8. c语言程序设计精髓 第13周练兵题

    1学生成绩管理系统V4.0(4分) 题目内容: 某班有最多不超过30人(具体人数由键盘输入)参加期末考试,最多不超过6门(具体门数由键盘输入).参考学生成绩管理系统V3.0,用二维数组作函数参数编程实 ...

  9. c语言程序设计精髓 第三周练兵题

    1日期显示(3分) 题目内容: 编写一个程序, 接收用户录入的日期信息并且将其显示出来. 其中, 输入日期的形式为月/日/年(mm/dd/yy), 输出日期的形式为年月日(yy.mm.dd). 以下为 ...

最新文章

  1. Struts 2基础入门
  2. 9篇!悉尼科技大学入选CVPR2021都研究什么?
  3. 微软 VS Code 或将取代 Visual Studio!
  4. 关于按钮背景透明 + div拖拽
  5. Qt编写Onvif搜索及云台控制工具
  6. 如何通过win10资源监视器来查看对方QQ的IP地址
  7. ESXI安装网卡或HBA卡驱动
  8. Windows MSDOS的批处理文件命令
  9. 北大计算机考研复试线,北京大学计算机考研分数线及报录比
  10. 解决click事件在移动端操作延迟300ms问题和点击时穿透问题
  11. Java面试题 Error和Exception有什么区别?列出你见过的Execption并简要说明?
  12. SVG - 在Android中使用矢量图全攻略
  13. java面试题大全(整理版)
  14. JDK1.8下载与安装(完整图文教程含安装包)
  15. python pos函数_如何用Python画一只肥肥的柯基狗狗—turtle库绘制椭圆与弧线实践
  16. 流体力学控制方程——能量方程
  17. java实现发送短信验证码、短信验证码防刷校验-49
  18. kong(微服务网关的简单部署)(一)
  19. 半导体器件 - 特殊二极管
  20. 今天有个做测试的朋友跳槽涨薪20k,我惊呆了

热门文章

  1. linux怎么发送邮件到qq邮箱,centos7命令行下用QQ邮箱发送邮件教程
  2. 前端使用pdf.js插件在线浏览pdf
  3. 如何做一个基于微信校园运动场地预约小程序系统毕业设计毕设作品
  4. 一款开源的协作文本编辑器
  5. mybatis和mybatis-plus集成springboot的配置区别
  6. jquery中ajax中的参数,jquery中的ajax参数
  7. Pandas 元素选取
  8. Java: 聚合数据API接口调用城市天气预报
  9. MySQL数据库练习3
  10. Max-Min 带宽公平分配算法