C语言入门篇 二.函数

目录

一.函数的组成

1.实际参数(实参):

2.形式参数(形参):

二.函数的调用

1.传值调用

2.传址调用

3.函数的嵌套调用和链式访问

三.函数的声明和定义 

1.函数的声明:

2.函数的定义:

四.函数的递归和迭代

1.函数的递归

2.函数的迭代

3.用函数递归解决经典问题

(1)汉诺塔问题

(2)青蛙跳台阶问题


函数分为库函数和自定义函数。在开发的过程中每个程序员都可能用的到, 为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序开发。

C语言有许多库,每个库包含许多库函数。

C语言常用的库函数都有:
IO函数
字符串操作函数
字符操作函数
内存操作函数
时间/日期函数
数学函数
其他库函数

常见的内存操作函数:

  1. memcpy:用于将一块内存的内容复制到另一块内存中。 函数原型:void *memcpy(void *dest, const void *src, size_t n) 参数说明:

    • dest:目标内存的指针,指向要复制到的内存区域。
    • src:源内存的指针,指向要复制的内存区域。
    • n:要复制的字节数。
  2. memset:用于将一块内存的内容设置为指定的值。 函数原型:void *memset(void *s, int c, size_t n) 参数说明:

    • s:要设置的内存的指针,指向要设置的内存区域。
    • c:要设置的值,以字符形式表示。
    • n:要设置的字节数。
  3. memmove:用于将一块内存的内容移动到另一块内存中,可以处理内存重叠的情况。 函数原型:void *memmove(void *dest, const void *src, size_t n) 参数说明:

    • dest:目标内存的指针,指向要移动到的内存区域。
    • src:源内存的指针,指向要移动的内存区域。
    • n:要移动的字节数。
  4. memcmp:用于比较两块内存的内容是否相等。 函数原型:int memcmp(const void *s1, const void *s2, size_t n) 参数说明:

    • s1:第一块内存的指针。
    • s2:第二块内存的指针。
    • n:要比较的字节数。
  5. memchr:用于在一块内存中搜索指定的字符。 函数原型:void *memchr(const void *s, int c, size_t n) 参数说明:

    • s:要搜索的内存的指针。
    • c:要搜索的字符。
    • n:要搜索的字节数。

常用的IO函数包括:

  1. printf:用于输出格式化的数据到标准输出设备(通常是屏幕),语法为:printf("格式控制字符串", 参数列表);

  2. scanf:用于从标准输入设备(通常是键盘)读取格式化的数据,语法为:scanf("格式控制字符串", 参数列表);

  3. getchar:用于从标准输入设备读取一个字符,语法为:int getchar(void);

  4. putchar:用于向标准输出设备输出一个字符,语法为:int putchar(int c);

  5. gets:用于从标准输入设备读取一行字符,语法为:char *gets(char *str);

  6. puts:用于向标准输出设备输出一行字符,语法为:int puts(const char *str);

  7. fprintf:用于将格式化的数据输出到指定的文件中,语法为:int fprintf(FILE *stream, "格式控制字符串", 参数列表);

  8. fscanf:用于从指定的文件中读取格式化的数据,语法为:int fscanf(FILE *stream, "格式控制字符串", 参数列表);

  9. fgets:用于从指定的文件中读取一行字符,语法为:char *fgets(char *str, int n, FILE *stream);

  10. fputs:用于向指定的文件输出一行字符,语法为:int fputs(const char *str, FILE *stream);

字符串操作函数:

  1. strlen(s):返回字符串s的长度(不包括结束符'\0')。
  2. strcpy(dest, src):将字符串src复制到dest中。
  3. strncpy(dest, src, n):将字符串src的前n个字符复制到dest中。
  4. strcat(dest, src):将字符串src连接到dest的末尾。
  5. strncat(dest, src, n):将字符串src的前n个字符连接到dest的末尾。
  6. strcmp(s1, s2):比较字符串s1和s2,返回一个整数,表示两个字符串的大小关系。
  7. strncmp(s1, s2, n):比较字符串s1和s2的前n个字符,返回一个整数,表示两个字符串的大小关系。
  8. strchr(s, c):在字符串s中查找字符c的第一次出现的位置,返回一个指向该位置的指针。
  9. strrchr(s, c):在字符串s中查找字符c的最后一次出现的位置,返回一个指向该位置的指针。
  10. strstr(s1, s2):在字符串s1中查找字符串s2的第一次出现的位置,返回一个指向该位置的指针。

字符操作函数:

  1. isalpha(c):判断字符c是否为字母。
  2. isdigit(c):判断字符c是否为数字。
  3. isalnum(c):判断字符c是否为字母或数字。
  4. isspace(c):判断字符c是否为空白字符(空格、制表符、换行符等)。
  5. toupper(c):将字符c转换为大写字母。
  6. tolower(c):将字符c转换为小写字母。

一.函数的组成

ret_type fun_name(para1, * )
{
        statement;//语句项
}
ret_type:返回类型
fun_name:函数名
para1,*:函数参数
例如:实现一个能交换两数的函数
#include <stdio.h>
//方式一不能完成任务
void Swap1(int x, int y) {
 int tmp = 0;
 tmp = x;
 x = y;
 y = tmp; 
}
//方式二才能实现
void Swap2(int *px, int *py) {
 int tmp = 0;
 tmp = *px;
 *px = *py;
 *py = tmp; 
}

​​​​​​​1.实际参数(实参):

真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式(表达式的值)、函数(函数的返回值)等。
无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形
参。

2.形式参数(形参):

形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内
存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。
代码一:形参是实参的拷贝,形参和实参的地址不同,形参和实参是独立的空间,形参的改变不影响实参的改变。
代码二:传入实参的地址,形参拷贝的是实参的地址,解引用去修改形参,就能修改实参。
(解引用就是*,对指针解引用就得到指针指向的数据)
形参是实参的拷贝,在调用函数的地方传入的实参,而实际在函数执行代码的形参

二.函数的调用

1.传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。

2.传址调用

传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操
作函数外部的变量。(通过解引用的方式)

3.函数的嵌套调用和链式访问

嵌套调用:
不同函数之间可以根据实际的需求进行组合的,也就是互相调用的。函数可以嵌套调用,但是不能嵌套定义。
例如:函数二嵌套调用了函数一。
#include <stdio.h>
void new_line() // 函数一
{
    printf("hehe\n");
}
void three_line() // 函数二
{
    int i = 0;
    for(i=0; i<3; i++)
    {
        new_line();
    }
}
链式访问
把一个函数的返回值作为另外一个函数的参数。例如:strcat函数的返回值作为strlen函数的参数

三.函数的声明和定义 

1.函数的声明:

1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。(声明时函数的形参名可以省略)
2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用
3. 函数的声明一般要放在头文件中的。(.h后缀的文件)

2.函数的定义:

函数的定义是指函数的具体实现,交待函数的功能实现。

四.函数的递归和迭代

1.函数的递归

程序调用自身的编程技巧称为递归( recursion)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身。递归的主要思考方式在于:把大事化小
递归的条件:存在终止递归的限制条件,每次递归不断接近限制条件,最终达成限制条件。
例如:实现打印一个数的各位数的函数,限制条件是n为非0.
#include<stdio.h>
void print(int n) {
	if (n) {
		print(n / 10);
		printf("%d ", n % 10);
	}
}

递归实现求字符串长度函数:

2.函数的迭代

迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。函数的迭代指循环实现,是非递归的过程。
例如求n的阶乘函数实现:
//函数的递归实现
int fun1(int n){
  if(n==1)return 1;
  else
  return n*fun1(n-1)
}
//函数的迭代实现
int fun2(int n){
  int ret,i;
  for(i=1;i<=n;i++){
    ret=ret*i;
  }
return ret;
}

3.用函数递归解决经典问题

(1)汉诺塔问题

 由分析可得,步骤一和三递归实现即可。

总次数=将n-1个盘移到B杆 + 将第n盘移到C杆 + 将n-1个盘移到C杆

//实现求出需要移动圆盘总次数的函数
int fun(int n){
  if(n==1) return 1;
  else
  return 2*fun(n-1)+1;
}

(2)青蛙跳台阶问题

一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。

列出函数表达式:(与斐波那契数列类似)

int fun(int n){
  if(n==1)return 1;
  if(n==2)return 2;
  if(n>2) return fun(n-1)+fun(n-2);
}

​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值