BUAA程设第五周总结


本周学习了函数和递归的知识。这部分知识对刚刚接触的同学来说可能有点困难。

这次就先谈谈写自定义函数的一些注意事项,然后简单谈一谈宏的事情。

自定义函数的注意事项

不要和已有的函数重名

在程序中不应该有任何两个变量、函数的命名是相同的。包括全局变量和局部变量。(局部的控制变量除外)

命名也不应该和库函数、库宏相同。

另外需要特别注意的一点, y 0 , y 1 , y n , j 0 , j 1 , j n y0,y1,yn,j0,j1,jn y0,y1,yn,j0,j1,jn 这几个名字在 math.h 库中已经被定义过了,因此你的变量和函数不能使用这些名字。

我建议大家不要无脑包含所有的头文件,你可能会觉得看上去很专业很爽,但事实上这样会拖慢程序编译的速度,并且会增加命名冲突的可能。

防止命名冲突的最好办法就是使用准确的英文名字命名你的变量,而不是使用 a , b , c , x , y , k a,b,c,x,y,k a,b,c,x,y,k 这样的简单名字。

此外还有一些传统的命名,诸如 a n s ans ans (意为答案) 、 c n t cnt cnt (计数变量)、 f l a g flag flag (标记变量)等。使用规范的命名方法会使其他人更容易读懂你的代码。

函数只能返回一个值

无论何时,你的函数只能拥有一个返回值,只能 r e t u r n return return 一个东西。虽然我们只能返回一个值,但是我们可以通过各种办法来达到返回多个返回值的效果。

一个简单的方法:使用全局变量。在任何地方对全局变量的修改的影响都是全局的。因此你在自定义函数内修改了全局变量,你在主函数内会发现全局变量也会发生改变。这样就可以做到函数之间的通信。

示例代码:

#include <stdio.h>
void fun();
int num;
int main(){
	num = 0;
	fun();
	printf("%d", num);
	return 0;
}
void fun(){
	num++;
	return;
}

合理运用全局变量的性质可以写出更优秀的代码。

注意使用函数过程中发生的隐式类型转换

在使用函数时,如果你传入的参数和函数的形式参数不一样,就会发生隐式类型转换;同理,在函数传回返回值时也可能在接受处发生类型转换。

math.h 库中的 pow() 函数举例子,这个函数的声明是这样的:

double pow(doublw _X, double _Y)

事实上的传入参数和返回值都应该是 d o u b l e double double 类型的。但是很多时候同学们会用它计算整数的幂。事实上,这样在传入和传出的过程中都会发生隐式的类型转换。之所以一直没有出什么问题是因为 d o u b l e double double 类型的精度有 17 17 17 位左右,足以计算 i n t int int 范围内的幂。但是如果涉及到 l o n g   l o n g long\ long long long ,数据比较大的时候, pow() 的精度不够,就可能会出现问题。

总之,同学们要时刻小心数据类型的隐式转换。特别是 i n t int int l o n g   l o n g long\ long long long 混用的时候。为了防止出现这样的问题,我的建议是如果要使用 l o n g   l o n g long\ long long long 数据类型,就将所有整数都定义为 l o n g   l o n g long\ long long long ,不使用 i n t int int 。虽然这样的做法看上去比较笨,但是确实有用。

使用各种方法替代define

在C语言中,define 最大的作用是辅助调试和编写头文件等(然而同学们还没有学这方面的知识,目前也不会用到),而不是辅助完成编写主体程序。

因此,我建议大家不要使用 define 。因为它只是一个简单的文本替换,有可能会出现晦涩、难以发现的问题。

那么我们要使用什么方法替代宏呢?

使用const全局变量

有时,我们需要一个常量,比如在写程序的过程中要对一个固定的数字取模。

我们需要做到:保证不对这个常量进行修改,保证他的值是恒定的。

以前大家可能会这么写:

#define mod 1000000007

但是我建议大家采取这样的写法:

const int mod = 1000000007;

使用 c o n s t const const 常量来替代 d e f i n e define define

使用typedef

当你觉得类型名 l o n g   l o n g long\ long long long 写起来太麻烦,想使用一个更简单的名字诸如 L L LL LL 来代替 l o n g   l o n g long\ long long long 时,可以使用 t y p e d e f typedef typedef 而不是 d e f i n e define define

t y p e d e f typedef typedef 实际上是给你的变量起一个别名,而不是 d e f i n e define define 的简单文本替换。

t y p e d e f typedef typedef 的使用方法:typedef <变量类型> <变量别名>;

以前大家可能会这么写:

#define LL long long
LL ans;

但是现在我向大家推荐使用 t y p e d e f typedef typedef 。于是写法就变成了:

typedef long long LL;
LL ans;

将来在大家学习结构体的时候会经常和 t y p e d e f typedef typedef 打交道。

使用函数替代宏

比如返回两个数字中的较大值,如果使用宏的写法是:

#define max(a, b) (a) > (b) ? (a) : (b)

但是使用宏完成这样类似函数的操作是相当愚蠢的。我们更应该为此定义一个简单的函数:

int max(int a, int b){
	return a > b ? a : b;
}

同学们常用的 d e f i n e define define 功能基本都可以用以上三个办法分别替代。因此,停止使用 d e f i n e define define 吧!

递归的学习建议

首先是多刷题,多看题解,多学习。递归是一个硬骨头,短期内快速提高比较困难,需要多接触、多写递归才能有进步。平时要多思考递归函数的运行逻辑,久而久之在熟悉了递归的过程后写递归才会变得简单。

我感觉初学者接触递归比较常见的题型是搜索和二叉树。我比较推荐大家在洛谷上刷题。推荐的题单有官方的搜索题单,和能力全面提升综合题单。大家可以按照自己的学习进度合理安排时间刷题。

总结

建议同学们自行预习字符串和多维数组的相关知识,为下次上机、期中做准备。

希望同学们再接再厉,努力学习程设,认真复习,在下周的期中考试中取得优秀的成绩!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值