Part one 感悟
今天没有啥特别的感悟,但是有一点,男人不能说自己不行。
Part Two Knowledge
1.函数
1.1函数的定义
通俗来讲,在C语言的定义中,函数就是解决问题的一串代码。
1.2函数的分类
在C语言中,函数可以分为两种-库函数和自定义函数。
1.2.1库函数
在学习C语言的过程中,我们会经常用到一些函数,例如printf函数,scanf函数...... 不难发现我们在使用这些函数时只需要在代码顶端引用相关的头文件,之后敲出这一行代码就能实现相关功能了。
像这一些实现非常基础功能的非业务向代码,每一个程序员可能在开发的时候都会用的到,为了支持可以执行和提高程序的效率,所以C语言的基础函数库里就预先为我们准备好了,这类函数我们统称为-库函数。 (假如说,C语言不为我们提供这些基础的函数,那么程序员A写了代码A来执行打印操作,程序员B写了代码B来执行打印操作,这样的话整个行业没有一个统一的标准,在代码复用和代码移植方面就会带来很大的不便,毕竟每个人的代码版本都不一样,大大的增加了阅读代码的学习成本)
如前文所言,在引用库函数的时候,我们需要引用一些头文件,这里用printf举例。
#include <stdio.h>
int main() {
printf("hello world");
return 0;
}
就以这个最经典的代码来做一些讲解,我们在使用printf函数的时候,需要引用<stdio.h>这个头文件,如果不引用的话,程序会报错,代码无法顺利的执行。
但是,C语言的库函数非常非常多,不可能我们都能记得住,那么当我们需要使用一些库函数的时候,应该怎么查找呢?
这里推荐一些方法,第一可以通过msdn来查找相关的库函数,第二可以通过cplusplus的官方网址来查找一些库函数。通过这两种方法都可以查找到相关库函数应该包括的头文件、语法...... 很方便的啦~
TIP:虽然有的库函数确实比较冷门,需要通过查找来实现。但是一些经常使用的函数是需要记住头文件和语法的,下面的函数是C语言中经常使用的函数类型。
1.2.2 自定义函数
前面说的库函数相信各位已经理解了,但是,现在我想通过代码来实现交换两个数字的值,那么使用库函数可以做到吗?
答案是否定的(我也不知道不要骂我),像这样带有业务性的代码,我们就称其为自定义函数。
自定义函数的语法如下
接下来我就通过引用交换数值的代码,来帮各位理解自定义函数应该如何用。
//代码1
void Swap1(int x, int y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
printf("交换前:a=%d b=%d\n", a, b);
Swap1(a, b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
通过代码1来看自定义函数的结构,不难发现,由于函数不要返回值,所以函数的返回类型我们是用void(空),同时因为函数的具体需要,我们需要交换两个整形的值,所以我们需要两个变量x、y来接收我输入的a、b。同时在自定义函数Swap1中利用了空杯来实现交换的功能。
但是结果却并不让我们满意,我们执行代码的时候会发现整个代码根本就没有交换函数?这又是怎么一回事呢???
这个时候就要跟各位补充亿些知识了-形参、实参。
1.3形参 实参
1.3.1形参与实参的定义
所以在形参的定义中我们不难看出,形参实例化之后其实相当于实参的一份临时拷贝。
我们来调试代码1,深刻的理解一下这句话。
通过调试代码1,我们可以发现,实参num1和num2跟形参x,y根本不在同一个空间,只是具有了一模一样的值,而在代码1的Swap1执行结束之后x,y就都被销毁了,原来输入的a、b还是他们自己,没有发生改变,自然而然最后输出的结果还是我们之前输入的结果。
那有没有什么解决方法呢?看下面这个代码。
//代码2
void Swap2(int* pa, int* pb)
{
int tmp = *pa;//tmp = a;
*pa = *pb; //a=b;
*pb = tmp; //b=tmp
}
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
printf("交换前:a=%d b=%d\n", a, b);
Swap2(&a, &b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
来看看代码2有什么不同,在执行完代码2的时候,我们发现最后的输出结果的确a、b交换了他们自己的数值。代码2和代码1又有什么不同呢?
我们发现,在编写Swap2时,我们传入的并非是a、b的值,而是a、b的地址,这样我们就能通过形参直接访问到a、b的地址,有了a、b的地址我们就可以直接对a、b本身进行操作,这样即便是出了自定义函数,在自定义函数外部的a、b也被我们改变了。
而这两种不同的代码对应了我们自定义函数中不同的两种调用方式-传值调用和传址调用
1.4传值调用和传址调用
定义如下