完全自学C(干货) —— 函数

目录

一,函数声明与定义

二,函数的分类

三,函数参数

四,函数的调用

五,函数的嵌套调用和链式访问

六,案例


  • 即子程序,是大型程序中某部分代码,由一个或多个语句块组成,通常被集成为软件库;
  • 负责完成某项特定任务,相较于其他代码具有独立性;
  • 一般会输入参数并返回值,提供对过程的封装和细节的隐藏;

一,函数声明与定义

函数的组成:包含函数名返回值类型函数参数函数体

//int 返回值
//Add 函数名
// int x/int y 参数
int Add(int x, int y)
{
    //函数体
	return x + y; 
}

函数声明

  • 告诉编译器,此函数的返回类型函数名参数类型,不关心是否存在;
  • 函数要满足先声明后使用;
  • 一般放在头文件内;
//头文件Add.h
//函数声明
int Add(int x, int y);

函数定义

  • 指函数具体实现的内容;
  • 定义时不开辟空间,只有调用时才开辟空间;
  • 注:不写函数返回类型,默认是返回int类型;
int Add(int x, int y)
{
	return x + y; 
}
int main()
{
	int a = 10;
	int b = 20;
    int Add(int, int); //如未声明,可能会报Add未定义错误;
	int c = Add(a, b);
	printf("%d\n", c);
	return 0;
}

int Add(int x, int y)
{
	return x + y;
}

二,函数的分类

  • 库函数
  • 自定义函数

库函数

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

常用库函数

  • io函数,输入输出函数printf/scanf/getchar/putchar等;
  • 字符串操作函数,strcmp/strlen等;
  • 字符操作函数,toupper等;
  • 内存操作函数,memcpy/memset/memcmp等;
  • 时间/日期函数,time等;
  • 数学函数等,sqrt/pow等;

注:使用库函数时,需引用对应的头文件,以#include开头;

#include <stdio.h> //printf库函数引用
#include <string.h> //strcpy库函数引用
int main()
{
	char str1[10] = { 0 };
	char str2[] = "abcde";
	printf("%s", strcpy(str1, str2));
}
//结果:abcde

库函数网站

自定义函数

与库函数一样,但是有程序员自己设计的;

int Add(int x, int y)
{
	return x + y; 
}

int Sub(int x, int y)
{
	return x - y; 
}

三,函数参数

  • 实际参数,简称实参;
  • 形式参数,简称形参;

实际参数

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

形式参数

  • 是指函数名后括号中的变量;
  • 形式参数只有在函数被调用的过程中才实例化(分配 内存单元),所以叫形式参数。
  • 当函数调用完成之后,形式参数就自动销毁了;
int Add(int x, int y) //x/y为形参
{
	return x + y;
}

int main()
{
	int a = 1;
	int b = 2;
	int c = Add(a, b); //a/b为实参
	printf("%d", c);
	return 0;
}

注:形参实例化之后其实相当于实参的一份临时拷贝;

四,函数的调用

  • 传值调用
  • 传址调用

传值调用

  • 形参实例化时,将实参的值,赋予给函数的参数;
  • 因为函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参;
int Add(int x, int y) //x/y为形参
{
	return x + y;
}

int main()
{
	int a = 1;
	int b = 2;
	int c = Add(a, b); //a/b为实参,调用时直接将1赋予x,2赋予给y,即传值调用
	printf("%d", c);
	return 0;
}

传址调用

  • 形参实例化时,将实参的内存地址,赋予给函数的参数;
  • 因为函数的形参和实参是同一块内存,对形参的修改会影响实参;
  • 即函数内部可直接修改函数外部的变量;
int Add(int* x, int* y) //x/y为形参
{
	return *x + *y;
}

int main()
{
	int a = 1;
	int b = 2;
	int c = Add(&a, &b); //a/b为实参,调用时直接将a的地址赋予x,b的地址赋予给y,即传址调用
	printf("%d", c);
	return 0;
}
void Swap(int* x, int* y) //x/y为形参
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

int main()
{
	int a = 1;
	int b = 2;
	Swap(&a, &b); //a/b为实参,调用时直接将a的地址赋予x,b的地址赋予给y,即传址调用
	printf("%d %d", a, b); //通过地址可修改函数外变量
	return 0;
}

五,函数的嵌套调用和链式访问

函数的嵌套调用

  • 函数定义时,可以包含其他已定义好的函数调用,形成嵌套;
  • 函数定义时,可以包含自身函数的调用,形成的嵌套即为递归
//嵌套调用
void Swap(int* x, int* y) 
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

int DividSwap(int x, int y)
{
	Swap(&x, &y); 
	return x / y;
}

int main()
{
	int a = 1;
	int b = 2;
	printf("%d", DividSwap(a, b)); 
	return 0;
}
//结果:2

链式访问

  • 把一个函数的返回值作为另外一个函数的参数;
int Add(int x, int y) 
{
	return x + y;
}

void print(int x)
{
	printf("%d\n", x);
}

int main()
{
	int a = 1;
	int b = 2;
	print(Add(a, b)); //链式访问
	return 0;
}
int main()
{
	printf("%d", printf("%d", printf("%d", 43))); //4321
	return 0;
}

六,案例

  • 判断素数
#include<stdio.h>
#include<math.h>

int is_prime(int num)
{
	int i = 0;
	for (i = 2; i <= sqrt(num); i++)
	{
		if (num % i == 0)
			return 0;
	}
	return 1;
}

int main()
{
	for (int i = 100; i <= 200; i++)
	{
		if (is_prime(i))
			printf("%d ", i);
	}
	return 0;
} 
  • 判断闰年
#include<stdio.h>

int is_leap_year(int n)
{
	return n % 4 == 0 && n % 100 != 0 || n % 400 == 0;
}

int main()
{
	int year = 0;
	for (year = 1000; year < 2000; year++)
	{
		if (is_leap_year(year))
			printf("%d ", year);
	}
	return 0;
}
  • 查找有序数组中的某个数
#include<stdio.h>

int binary_search(int* arr, int key, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] < key)
			left = mid + 1;
		else if (arr[mid] > key)
			right = mid - 1;
		else
			return mid;
	}
	return -1;
}

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int key = 7;
	int sz = sizeof arr / sizeof arr[0];
	//找到返回下班,找不到返回-1;
	printf("%d\n", binary_search(arr, key, sz));
	return 0;
}
  • 每调用一次函数num加1
void add(int* num)
{
	(*num)++;
}

int main()
{
	int num = 0;
	add(&num);
	printf("%d", num);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值