大计人,大计魂,C不会写都是人下人!(指我)
写在前面
这是崔舒宁老师的一份答案 , 可供也仅供参考:
https://github.com/AndrewChui/CHomeWork
常识
闰年:1
2
3
4
5int judge(int n) {
if ((n % 4 == 0 && n % 100 != 0) || n % 400 == 0)
return 1;
return 0;
}
即年份被4整除但不被100整除 或 年份被400整除
%g
是一个以前没见过的占位符。g是 $general$ 的简写,意为它是普遍的。具体而言:$\%g$ 用来输出实数,它根据数值的大小,自动选 $f$ 格式或 $e$ 格式(选择输出时占宽度较小的一种),且不输出无意义的0。即%g是根据结果自动选择科学记数法还是一般的小数记数法:1
2
3
4
5
6
7
8
9
10printf("%g\n", 0.00001234);
printf("%g\n", 0.0001234);
printf("%.2g\n", 123.45);
printf("%.2g\n", 23.45);
//输出
1.234e-05
0.0001234
1.2e+02
23
烫烫烫烫烫烫烫
手持两把锟斤拷 , 口中直呼烫烫烫
例子
在对字符串逐个赋值时 , 如果没给它加入终止值 $0$ , 则输出字符串时就会出现如下情况:
原理

来源: https://www.zhihu.com/question/23600507
所以逐位给字符串赋值一定要记得加终止值!
const char [] 的用法
使用$const \ char \ [\ ]$ 储存要输出的已知字符串 , 或建立一个数组下标与字符串的简单映射 .
例
月份
指针
是一个变量,它的值为另一个变量的地址。
使用前需要初始化,且只能初始化为0,或指向一个已声明的变量。
声明一个指针变量:1
2int a=0;
int *p=&a;
其中&是取址符,顾名思义,用来获取该变量的地址。
指针使用
1 | int a=0; |
注意区分这里的 $p$ 与声明时的 $p$:
前者是代表我读这个指针所指位置的值,后者是说明我现在声明的变量是指针变量。
特别的,字符串可以用指向字符串头的指针声明/唯一表示。(\0的存在)
指针运算
想必你已经发现了指针变量也是有类型的,指向什么变量类型,该指针就是什么类型。但此类型不会影响指针变量储存的内容,而会影响它的运算。
普通运算
指针可进行
- +/-
- 比较(==,<,>)
这两种没啥好说的运算
特殊:递增/递减
即p++
若p不为指针变量,则p++与p=p+1基本相同。
但作为指针变量,他递增的step取决于它的类型:递增该类型长度。
本质上,是指针的每一次递增,会指向下一个元素的存储单元。
指针数组
同其他类型一样,指针变量也可使用数组。但我不会用
结构体指针
通过指针访问结构体的成员要用箭头操作符 “->”1
2
3
4
5
6
7
8
9typedef struct StudentType{
char id[10];
double score[5];
double GPA;
}Student;
Student xjtustu;
Student* ptr=&xjtustu;
ptr->score[1]=90;
数据类型带来的问题
来看一段代码:1
2
3
4
5
6
7
8
9
10
int main(){
int a;scanf(“%d”,%a);
int i=0;
while(a/pow(10,i)==0). //确定a的位数
break;
//more codes
}
代码功能如注释所示。
先不论该方法是否能实现所需功能,虽然语法上看起来没啥问题,但是如果你尝试运行的话,就会发现:
无论输出什么a,最后的i似乎都是不变的
排序算法
没了 $sort$ 跟 $swap$ 我好难受。
大计课只要求掌握两种$O(n^2)$排序:冒泡排序,插入排序。
排序技巧
一组数据排序中,下面两种方法经常用。
结构体排序
用于将一组数据绑定,使排序时的交换不仅限于被比较的那一类数据。
典型例子就是学生成绩排序:
可将学生构造成一个结构体 , 使得一个结构体中的几个数据绑定 , 再在排序过程中交换整个结构体 .
间接排序
排序时不改变数据位置,而是再开一个dir数组,记录大小顺序下的第i个元素,数据是a[i] b[i] c[i]等。(我个人喜欢用,因为不用写结构体,也不用写student[i].name这样的长变量名。
还是看上面的学生排序例子,直接贴我的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
for (int i = 1; i <= n; i++) {
scanf("%s", num[i]);
scanf("%s", name[i]);
scanf("%d%d%d", &score[i][1], &score[i][2], &score[i][3]);
dir[i] = i;//初始化
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if (cmp(dir[i], dir[j]) > 0) {//重要!不是ij
swap(&dir[i], &dir[j]);
}
冒泡排序
小鲤鱼吐泡泡。
原理
从第一个元素起,向后依次比较每一对相邻元素,若逆序则交换,使大的(不妨认为升序排序)数前往数组后方。
冒泡排序是稳定排序
代码实现
1 | for (i=0; i<n-1; i++) //外循环为排序趟数,n个数进行n-1趟 |
插入排序
大概是我玩扑克牌的样子。(图源 算法导论)
原理
通过交换使最小的被放在最前,再在2~n位置重复。
插入排序是不稳定排序
代码实现
1 | for(int i=1;i<=n;i++)//寻找第i小 |
