《C语言入门》
热情篇 — — 热情像一对翅膀,带我飞过山岭。
目录
前言
前面写的小练习都是由一个主函数构成的。但当我们遇到和处理一些复杂的问题时,一般要把它分成若干个相对独立的模块,每一个模块实现一个特定的功能。函数模块关系明确,可读性好,便于查错和修改。一个C语言程序可以由一个主函数和若干个其它函数构成,主函数调用其它函数实现程序想要达到的效果,其它函数之间也可以相互调用。C语言中函数分为两类, 库函数, C语言的基础库中提供的。自定义函数,根据需求自己设计的。
1. 函数是什么
定义:函数也可以叫做 子程序 ,是一个大型程序中的某部分代码, 由一个或多个语句块组成。它 负责完成某项特定任务 ,而且相较于其他代 码, 具备相对的独立性 。 一般会有 输入参数并有返回值 ,提供对过程的封装和细节的隐藏。
函数的语法:函数的返回值类型 函数名(参数1,参数2,){语句序列};
2. 库函数
在编程的过程中我们会频繁的使用一些功能,例如:将信息按照一定的格 式打印到屏幕上(printf)。所以C语言的基础库中提供了一系列类似的库函数供程序员直接使用。使用库函数,必须包含对应的头文件。
2.1"小试牛刀" --函数学习
getchar:
介绍:int getchar ();
功能:获取字符。
使用:每个字符都有对应的ASCLL值,ch存放获取字符的ASCLL值。
int ch = getchar();
返回值:成功时返回读取的字符,失败返回EOF。
头文件:#include <stdio.h>
putchar:
介绍:int putchar ( int character );
功能:将一个字符写入标准输出。
参数:int character
使用:
putchar(ch);
返回值:成功时,返回写入的字符。失败返回EOF。
头文件:#include <stdio.h>
应用:循环接收,打印
#include <stdio.h> int main() { while (1) { int ch = getchar(); putchar(ch); } return 0; }
效果:
strcpy:
介绍:char * strcpy ( char * destination, const char * source );功能:源指针指向的字符串复制到目标指针指向的空间
参数:1.目的地:目标数组的指针,2.源头:要复制的字符串。
头文件:#include <string.h>
应用:把arr1中的字符串复制到了arr2中
#include <stdio.h> #include <string.h> int main() { char arr1[] = "Hello World"; char arr2[20] = { 0 }; strcpy(arr2, arr1);//传入两个实际参数,要复制到的目的地,复制的对象 printf("%s", arr2); return 0; }
效果:
memset:介绍:void * memset ( void * ptr, int value, size_t num );
功能:将ptr指向的内存块 的前num字节设置为指定值。
参数:1、指向要填充的内存块的指针 2、要设置的值 3、改的大小
头文件:#include <string.h>
应用:把##########的前5个字符改成“A”
#include <stdio.h> #include <string.h> int main() { char arr[20] = "###############"; memset(arr,'A', 5); printf("%s",arr); return 0; }
结果:
3. 自定义函数
自定义函数和库函数一样,有函数名,返回值类型和函数参数。这些都是我们自己根据程序需要来设计的。
实践: 写一个函数找出两个整数中的最大值。
#include <stdio.h> int get_MAX(int a,int b) { if (a > b) { return a; } return b; } int main() { int a = 0; int b = 0; scanf("%d %d",&a,&b); int max = get_MAX(a,b); printf("%d ",max); return 0; }
结果:
综上所述:自定义函数可以完成你想做的事情,“人有多大胆,代码就有有多大产”。
4. 函数参数
实参:真实传给函数的参数,叫实参。 实参可以是:常量、变量、表达式、函数等。
形参:形式参数是指函数名后括号中的变量。当函数调用完成之后就自动销毁了。形式参数只在函数中有效。
函数在调用的时候, x , y 开辟了 自己的空间,同时拥有了和实参一模一样的内容。综上所述:形参实例化之后其实相当于实参的一份临时拷贝 。
5. 函数调用
传值调用:函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。
Swap1(num1, num2);
传址调用:函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操 作函数外部的变量。
Swap2(&num1, &num2);
小练习:写一个函数可以交换两个整形变量的内容。(观察传值调用和传址调用的区别)
传值调用:
传址调用:
#include <stdio.h> void swap(int* a,int* b) { int temp = 0; temp = *a; *a = *b; *b = temp; } int main() { int a = 0; int b = 0; scanf("%d %d",&a,&b); swap(&a,&b); printf("%d %d",a,b); return 0; }
传值调用: 传址调用
综上所述:当想要通过形参直接操作的时候,例如交换a,b的值,就要需选择传址调用。
6. 函数的嵌套调用和链式访问
嵌套调用:函数和函数之间可以互相调用的。
int A() { printf("HaHa\n"); } int B() { int i = 0; for (i = 0; i < 3; i++) { A(); } } int main() { B(); return 0; }
链式访问:把一个函数的返回值作为另外一个函数的参数。
例:
#include <stdio.h> int main() { printf("%d", printf("%d", 24)); return 0; }
7. 递归
什么是递归:函数自己调用自己。
思考方向:“大事化小,小事化了”。
两个必要条件:
1、有一个限制条件。
2、每次递归都更接近这个条件。
小练习:求n的阶乘。(递归)
#include <stdio.h> int mult(int n) { if (n <= 1) return 1; else return n * mult(n - 1); } int main() { int num = 0; scanf("%d",&num); int ret = mult(num); printf("%d",ret); return 0; }