【C语言初阶】 对C语言函数的初步认识

目录

 

一、函数是什么?

二、函数的分类

1、库函数

一.

二.

三.

四.

五.

六.

2、自定义函数

 三、参数传递

形参和实参的区别和联系

C 语言中的参数传递方式有两种

引用传递

值传递


 

一、函数是什么?

函数是指一段在一起的、可以做某一件事儿的程序。也叫做子程序、(OOP中)方法。

一个较大的程序一般应分为若干个程序块,每一个模块用来实现一个特定的功能。所有的高级语言中都有子程序这个概念,用子程序实现模块的功能。在C语言中,子程序的作用是由一个主函数和若干个函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。

在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用。要善于利用函数,以减少重复编写程序段的工作量。

函数分为全局函数、全局静态函数;在类中还可以定义构造函数、析构函数、拷贝构造函数、成员函数、友元函数、运算符重载函数、内联函数等

 函数的定义包括函数头和函数体两部分,其一般形式如下:

返回值类型 函数名(参数列表) {
    // 函数体语句块
}

其中,返回值类型是函数返回值的数据类型,函数名是函数的标识符,用于在程序中调用函数,参数列表是函数接收的参数,多个参数之间用逗号分隔。

二、函数的分类

函数在C语言中可分为:库函数、自定义函数;

1、库函数

库函数简单来说已经封装好了的函数,包含一些常用的功能可以搭配头文件方便使用,以下是我搜索整理来的一些库函数

一. <ctype.h>


序号    函数原型    功能
1    int iscntrl(int c)    判断字符c是否为控制字符。
2    int isalnum(int c)    判断字符c是否为字母或数字
3    int isalpha(int c)    判断字符c是否为英文字母
4    int isascii(int c)    判断字符c是否为ascii码
5    int isblank(int c)    判断字符c是否为TAB或空格
6    int isdigit(int c)    判断字符c是否为数字
7    int isgraph(int c)    判断字符c是否为除空格外的可打印字符
8    int islower(int c)    判断字符c是否为小写英文字母
9    int isprint(int c)    判断字符c是否为可打印字符(含空格)
10    int ispunct(int c)    判断字符c是否为标点符号
11    int isspace(int c)    判断字符c是否为空白符
12    int isupper(int c)    判断字符c是否为大写英文字母
13    int isxdigit(int c)    判断字符c是否为十六进制数字
14    int toascii(int c)    将字符c转换为ascii码
15    int tolower(int c)    将字符c转换为小写英文字母
16    int toupper(int c);    将字符c转换为大写英文字母


二. <math.h>

序号    函数原型    功能
1    float fabs(float x)    求浮点数x的绝对值
2    int abs(int x)    求整数x的绝对值
3    float acos(float x)    求x(弧度表示)的反余弦值
4    float asin(float x)    求x(弧度表示)的反正弦值
5    float atan(float x)    求x(弧度表示)的反正切值
6    float atan2(float y, float x)    求y/x(弧度表示)的反正切值
7    float ceil(float x)    求不小于x的最小整数
8    float cos(float x)    求x(弧度表示)的余弦值
9    float cosh(float x)    求x的双曲余弦值
10    float exp(float x)    求e的x次幂
11    float floor(float x)    求不大于x的最大整数
12    float fmod(float x, float y)    计算x/y的余数
13    float frexp(float x, int *exp)    把浮点数x分解成尾数和指数
14    float ldexp(float x, int exp)    返回x*2^exp的值
15    float modf(float num, float *i)    将浮点数num分解成整数部分和小数部分
16    float hypot(float x, float y)    对于给定的直角三角形的两个直角边,求其斜边的长度
17    float log(float x)    计算x的自然对数
18    float log10(float x)    计算x的常用对数
19    float pow(float x, float y)    计算x的y次幂
20    float pow10(float x)    计算10的x次幂
21    float sin(float x)    计算x(弧度表示)的正弦值
22    float sinh(float x)    计算x(弧度表示)的双曲正弦值
23    float sqrt(float x)    计算x的平方根
24    float tan(float x);    计算x(弧度表示)的正切值
25    float tanh(float x)    求x的双曲正切值


三. <stdio.h>


序号    函数原型    功能
1    int printf(char *format...)    产生格式化输出的函数
2    int getchar(void)    从键盘上读取一个键,并返回该键的键值
3    int putchar(char c)    在屏幕上显示字符c
4    FILE *fopen(char *filename, char *type)    打开一个文件
5    FILE *freopen(char *filename, char *type,FILE *fp)    打开一个文件,并将该文件关联到fp指定的流
6    int fflush(FILE *stream)    清除一个流
7    int fclose(FILE *stream)    关闭一个文件
8    int remove(char *filename)    删除一个文件
9    int rename(char *oldname, char *newname)    重命名文件
10    FILE *tmpfile(void)    以二进制方式打开暂存文件
11    char *tmpnam(char *sptr)    创建一个唯一的文件名
12    int setvbuf(FILE *stream, char *buf, int type, unsigned size)    把缓冲区与流相关
13    int fprintf(FILE *stream, char *format[, argument,...])    传送格式化输出到一个流中
14    int scanf(char *format[,argument,...])    执行格式化输入
15    int fscanf(FILE *stream, char *format[,argument...])    从一个流中执行格式化输入
16    int fgetc(FILE *stream)    从流中读取字符
17    char *fgets(char *string, int n, FILE *stream)    从流中读取一字符串
18    int fputc(int ch, FILE *stream)    送一个字符到一个流中
19    int fputs(char *string, FILE *stream)    送一个字符到一个流中
20    int getc(FILE *stream)    从流中取字符
21    int getchar(void)    从 stdin 流中读字符
22    char *gets(char *string)    从流中取一字符串
23    int putchar(int ch)    在 stdout 上输出字符
24    int puts(char *string)    送一字符串到流中
25    int ungetc(char c, FILE *stream)    把一个字符退回到输入流中
26    int fread(void *ptr, int size, int nitems, FILE *stream)    从一个流中读数据
27    int fwrite(void *ptr, int size, int nitems, FILE *stream)    写内容到流中 int fseek
28    (FILE *stream, long offset, int fromwhere)    重定位流上的文件指针
29    long ftell(FILE *stream)    返回当前文件指针
30    int rewind(FILE *stream)    将文件指针重新指向一个流的开头
31    int fgetpos(FILE *stream)    取得当前文件的句柄
32    int fsetpos(FILE *stream, const fpos_t *pos)    定位流上的文件指针
33    void clearerr(FILE *stream)    复位错误标志
34    int feof(FILE *stream)    检测流上的文件结束符
35    int ferror(FILE *stream)    检测流上的错误
36    void perror(char *string)    系统错误信息


四. <stdlib.h>


序号    函数原型    功能
1    char *itoa(int i)    把整数i转换成字符串
2    void exit(int retval)    结束程序
3    double atof(const char *s)    将字符串s转换为double类型
4    int atoi(const char *s)    将字符串s转换为int类型
5    long atol(const char *s)    将字符串s转换为long类型
6    double strtod (const char*s,char **endp)    将字符串s前缀转换为double型
7    long strtol(const char*s,char **endp,int base)    将字符串s前缀转换为long型
8    unsinged long strtol(const char*s,char **endp,int base)    将字符串s前缀转换为 unsinged long型
9    int rand(void)    产生一个0~RAND_MAX之间的伪随机数
10    void srand(unsigned int seed)    初始化随机数发生器
11    void *calloc(size_t nelem, size_t elsize)    分配主存储器
12    void *malloc(unsigned size)    内存分配函数
13    void *realloc(void *ptr, unsigned newsize)    重新分配主存
14    void free(void *ptr)    释放已分配的块
15    void abort(void)    异常终止一个进程
16    void exit(int status)    终止应用程序
17    int atexit(atexit_t func)    注册终止函数
18    char *getenv(char *envvar)    从环境中取字符串
19    void *bsearch(const void *key, const void *base, size_t *nelem, size_t width, int(*fcmp)(const void *, const *))    二分法搜索函数
20    void qsort(void *base, int nelem, int width, int (*fcmp)())    使用快速排序例程进行排序
21    int abs(int i)    求整数的绝对值
22    long labs(long n)    取长整型绝对值
23    div_t div(int number, int denom)    将两个整数相除 , 返回商和余数
24    ldiv_t ldiv(long lnumer, long ldenom)    两个长整型数相除 , 返回商和余数


五. <time.h>


序号    函数原型    功能
1    clock_t clock(void)    确定处理器时间函数
2    time_t time(time_t *tp)    返回当前日历时间
3    double difftime(time_t time2, time_t time1)    计算两个时刻之间的时间差
4    time_t mktime(struct tm *tp)    将分段时间值转换为日历时间值
5    char *asctime(const struct tm *tblock)    转换日期和时间为ASCII码
6    char *ctime(const time_t *time)    把日期和时间转换为字符串
7    struct tm *gmtime(const time_t *timer)    把日期和时间转换为格林尼治标准时间
8    struct tm *localtime(const time_t *timer)    把日期和时间转变为结构
9    size_t strftime(char *s,size_t smax,const char *fmt, const struct tm *tp)    根据 fmt 的格式 要求将 *tp中的日期与时间转换为指定格式


六. <string.h>


序号    函数原型    功能
1    int bcmp(const void *s1, const void *s2, int n)    比较字符串s1和s2的前n个字节是否相等
2    void bcopy(const void *src, void *dest, int n)    将字符串src的前n个字节复制到dest中
3    void bzero(void *s, int n)    置字节字符串s的前n个字节为零
4    void *memccpy(void *dest, void *src, unsigned char ch, unsigned int count)    由src所指内存区域复制不多于count个字节到dest所指内存区域,如果遇到字符ch则停止复制
5    void *memcpy(void *dest, void *src, unsigned int count)    由src所指内存区域复制count个字节到dest所指内存区域
6    void *memchr(void *buf, char ch, unsigned count)    从buf所指内存区域的前count个字节查找字符ch
7    int memcmp(void *buf1, void *buf2, unsigned int count)    比较内存区域buf1和buf2的前count个字节
8    int memicmp(void *buf1, void *buf2, unsigned int count)    比较内存区域buf1和buf2的前count个字节但不区分字母的大小写
9    void *memmove(void *dest, const void *src, unsigned int count)    由src所指内存区域复制count个字节到dest所指内存区域
10    void *memset(void *buffer, int c, int count)    把buffer所指内存区域的前count个字节设置成字符c
11    void setmem(void *buf, unsigned int count, char ch)    把buf所指内存区域前count个字节设置成字符ch
12    void movmem(void *src, void *dest, unsigned int count)    由src所指内存区域复制count个字节到dest所指内存区域
13    char *stpcpy(char *dest,char *src)    把src所指由NULL结束的字符串复制到dest所指的数组中
14    char *strcpy(char *dest,char *src)    把src所指由NULL结束的字符串复制到dest所指的数组中
15    char *strcat(char *dest,char *src)    把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)并添加’\0’
16    char *strchr(char *s,char c)    查找字符串s中首次出现字符c的位置
17    int strcmp(char *s1,char * s2)    比较字符串s1和s2
18    int stricmp(char *s1,char * s2)    比较字符串s1和s2,但不区分字母的大小写
19    int stricmp(char *s1,char * s2)    比较字符串s1和s2,但不区分字母的大小写
20    int strcspn(char *s1,char *s2)    在字符串s1中搜寻s2中所出现的字符
21    char *strdup(char *s)    复制字符串s
22    int strlen(char *s)    计算字符串s的长度
23    char *strlwr(char *s)    将字符串s转换为小写形式
24    char *strupr(char *s)    将字符串s转换为大写形式
25    char *strncat(char *dest,char *src,int n)    把src所指字符串的前n个字符添加到dest结尾处(覆盖dest结尾处的’\0’)并添加’\0’
26    int strcmp(char *s1,char * s2,int n)    比较字符串s1和s2的前n个字符
27    int strnicmp(char *s1,char * s2,int n)    比较字符串s1和s2的前n个字符但不区分大小写
28    char *strncpy(char *dest, char *src, int n)    把src所指由NULL结束的字符串的前n个字节复制到dest所指的数组中
29    char *strpbrk(char *s1, char *s2)    在字符串s1中寻找字符串s2中任何一个字符相匹配的第一个字符的位置,空字符NULL不包括在内
30    char *strrev(char *s)    把字符串s的所有字符的顺序颠倒过来(不包括空字符NULL)
31    char *strset(char *s, char c)    把字符串s中的所有字符都设置成字符c
32    char *strstr(char *haystack, char *needle)    从字符串haystack中寻找needle第一次出现的位置(不比较结束符NULL)
33    char *strtok(char *s, char *delim)    分解字符串为一组标记串。s为要分解的字符串,delim为分隔符字符串

2、自定义函数

自定义函数简而言之就是自己定义的函数;与库函数一样,不过由自己实现;

例如,下面定义了一个名为 sum 的函数,它的作用是求两个整数的和并返回结果:

int sum(int a, int b) {
    int c = a + b;
    return c;
}

 三、参数传递

如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;从一定程度上讲,函数的作用就是根据不同的参数产生不同的返回值。

C语言函数的参数会出现在两个地方,分别是函数定义处和函数调用处,这两个地方的参数是有区别的。

形参(形式参数)

在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参

实参(实际参数)

函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参

形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。

形参和实参的区别和联系

1) 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

2) 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

3) 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。当然,如果能够进行自动类型转换,或者进行了强制类型转换,那么实参类型也可以不同于形参类型。

4) 函数调用中发生的数据传递是单向的,只能把实参的值传递给形参,而不能把形参的值反向地传递给实参;换句话说,一旦完成数据的传递,实参和形参就再也没有瓜葛了,所以,在函数调用过程中,形参的值发生改变并不会影响实参。

C 语言中的参数传递方式有两种

值传递和引用传递。值传递是指将实参的值传递给形参,形参是实参的副本,在函数内部对形参的修改不会影响实参的值。引用传递是指将实参的地址传递给形参,形参是实参的别名,在函数内部对形参的修改会影响实参的值。

引用传递

例如下面这个交换函数,作用为交换两个整数

#include<stdio.h>
void jiaohuan(int* pa, int* pb)
{
	int c = *pa;
	*pa = *pb;
	*pb = c;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	printf("交换前a=%d,b=%d\n", a, b);
	jiaohuan(&a, &b);
	printf("交换后a=%d,b=%d\n", a, b);
	return 0;
}

运行结果为: 

b7e248eb89fe414591aefc545cfac0bf.png

在调用 jiaohuan() 函数时,可以传递两个变量的地址作为实参,这样在函数内部就可以通过指针修改变量的值,这里的pa相当于&a,pb相当于&b;这里传递了地址,而当只传递值时

值传递

还是用交换函数

/void Swap(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);
//	//实际参数 - 实参
//	//当实参传递给形参的时候
//	//形参是实参的一份临时拷贝
//	//所以对形参的修改不会影响实参
//	//
//	Swap(a, b);
//	printf("交换后:a=%d b=%d\n", a, b);
//	
//	return 0;
//}

在调用Swap()函数时,可传递两个变量的值作为实参,而这里实参传递给形参的时候,形参是实参的一份零时拷贝,所以对形参的修改不会影响实参。

运行结果如下:

55d63604177d40b79623f9282bbe5012.png

可以看到交换前后a与b的值并未发生变化 ,这里就与前面所提到形参变量有关了, 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效。

这里我们对所传递的值进行监视得a与x 、b与y的地址并不同,而且调用结束后,还会立即释放内存,所以并不会实参产生影响!

368e803d4b7049fc9f78fe5dddaa885a.png

 综上所述,二者区别为:2016de64d3bc4337826c7b0d17026d36.png

82c03ea7a70c46faae7f063c3426802f.png

以上就是我现在对C语言函数的初步理解,若有不正确或不全面的地方,欢迎各位友友指出,博主一定会改正加油的。 

 

 

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇事问春风乄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值