初阶C语言-函数(上)

这篇具有很好参考价值的文章主要介绍了初阶C语言-函数(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

“追光的人,终会光芒万丈!” 今天我们一起来学习一下函数的相关知识点。

1.函数是什么?

数学中我们常见函数的概念,在数学中,函数通常是解决自变量与因变量之间关系的问题。那么,在C语言中,函数是做什么的呢?维基百科中对函数的定义为:子程序

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

2.C语言中函数的分类

  1. 库函数
  2. 自定义函数

2.1库函数

为什么会有库函数呢?

1.我们在学习C语言编程的时候,总是在一个代码编写完成后迫不及待的想知道结果,想把这个结果打印在我们的屏幕上,这个时候我们就会频繁的使用一个功能:将信息按照一定格式打印到屏幕上(printf
2.在编程的过程中,我们会频繁的做一些字符串的拷贝工作(strcpy
3.在编程的过程中我们也会计算,比如计算n的k次方(pow

像上述我们描述的基本功能,它们不是业务性的代码。我们在开发的过程中每一个程序员都可以用到,为了支持可移植性和提高程序的效率,所有C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。

需要注意的是库函数不是C语言提供的,是C语言标准中约定好,由编译器的厂商提供实现。

下面给出示例:

在C语言的标准中,对于strlen函数做出以下规定:
1.函数的功能-求字符串的长度
2.函数名-strlen
3.参数- const char*str
4.返回类型- size_t
以上规定是C语言规定好的,具体的函数实现是由不同的厂商实现的。

那么,库函数到底有哪些呢?我们可以去查看该网站:库函数查找的链接
初阶C语言-函数(上),c语言,开发语言
简单的总结,C语言中常用的库函数都有:

  1. IO函数(标准输入输出头文件#include <stdio.h>
  2. 字符串操作函数(strlen、strcpy等函数的头文件为#include <string.h>
  3. 内存操作函数(头文件为#include <malloc.h>
  4. 时间/日期函数(头文件为#include <time.h>
  5. 数学函数(头文件为#include <math.h>
  6. 其他库函数

具体的函数及用法,大家可以查阅上面的网站学习。这里,我们给大家简单介绍几种库函数及其使用。

1.pow函数(头文件为#include <math.h>
通过查阅网站我们可以了解到该函数的使用方法:
初阶C语言-函数(上),c语言,开发语言
接下来,让我们一起来试着用一下这个函数吧!

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <math.h>
int main()
{
	int ret = (int)pow(3, 5);//由于pow函数是float型,所以可以强制类型转化为int型
	printf("%d", ret);
	return 0;
}

这里,我们建议大家把pow的返回类型强转为int型,因为我们给出的样例输入是整型,不强转的话会给出警告。
初阶C语言-函数(上),c语言,开发语言

初阶C语言-函数(上),c语言,开发语言
2.strcpy函数(头文件为#incude <string.h>
同样的,我们可以先查找网站,看看该函数的相关用法。
初阶C语言-函数(上),c语言,开发语言

//strcpy函数
#include <stdio.h>
int main()
{
	char arr1[20] = "xxxxxxxxxxxxxxxxxxxx";
	char arr2[] = "Hello C World!";
	strcpy(arr1, arr2);
 printf("%s\n", arr1);
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
不难发现strcpy函数就是起到的一个复制的作用,那么字符串的结束标志是否被一同复制过去呢?这里,我们可以调试运行着看一下。
初阶C语言-函数(上),c语言,开发语言
注:我们可以发现strcpy函数会将'\0'一同复制过去!

3.memset函数(头文件为#incude <string.h>
初阶C语言-函数(上),c语言,开发语言

//memset函数
#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "Hello C World!";
	memset(arr, 'x', 5);
	printf("%s\n", arr);
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
注:使用库函数必须要包含#include对应的头文件

2.2自定义函数

如果库函数能解决所有的问题,那么还需要程序员干嘛呢?所以,更多的时候还是需要用到自定义函数。自定义函数和库函数一样,有函数名、返回类型和函数参数。但是不一样的是这些是我们自己来设计的,给了程序员很大的发挥空间。

//函数的组成:
ret_type fun_name(paral,*)
{
    statement;//语句项
}
//ret_type-返回类型
//fun_name-函数名
//paral-函数参数

下面我们举一个例子,写一个函数可以找出两个整数中的最大值。

//写出一个函数求两个数的最大值
#include <stdio.h>
int get_max(int x, int y)
{
	if (x > y)
		return x;
	else
		return y;
}
int main()
{
	int num1 = 0;
	int num2 = 0;
	scanf("%d%d", &num1, &num2);
	int max = get_max(num1, num2);
	printf("%d\n", max);
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
我们再举一个例子,写一个函数可以交换两个整型变量的内容。

#define _CRT_SECURE_NO_WARNINGS 1
//写一个函数可以交换两个整型变量的内容
#include <stdio.h>
void swap(int x, int y)//形式参数
{
	int t;
	t = x;
	x = y;
	y = t;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d", &a, &b);
	printf("交换前:%d %d\n", a, b);
	swap(a, b);//实际参数
	//函数调用时将实参传给形参,形参其实是实参的一份临时拷贝
	//对形参的修改不会改变实参
	printf("交换后:%d %d\n", a, b);
	return 0;
}

通过前面所学,我们知道了交换两个变量的值需要用到中间变量t,那么这样写出来的代码是否正确呢?
初阶C语言-函数(上),c语言,开发语言
我们可以发现两个整型变量的内容并没有发生交换,遇到问题的时候,我们试着自己调试着发现问题!
初阶C语言-函数(上),c语言,开发语言
通过调试,我们发现,形参和实参的地址不一样,因此对形参的修改不会改变实参,这时候考虑到地址,我们应该就想到了前面提及的指针,那我们再把代码修改一下来实现我们希望的功能。

#include <stdio.h>
void swap2(int *x, int *y)
{
	int t;
	t = *x;//t = a
	*x = *y;//a = b
	*y = t;//b = t
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d", &a, &b);
	printf("交换前:%d %d\n", a, b);
	swap2(&a, &b);//实际参数
	printf("交换后:%d %d\n", a, b);
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
初阶C语言-函数(上),c语言,开发语言

3.函数的参数

3.1实际参数(实参)

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

int max(int x, int y)
{
	if (x > y)
		return x;
	else
		return y;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d", &a, &b);
	max(3, 6);//实参是常量
	max(a, 6);//实参是变量
	max(b, max(a, 4));//实参是函数
	max(a, 3 + 5);//实参是表达式
	return 0;
}

3.2形式参数(形参)

形式参数是指函数名后括号中的变量,因为 形式参数只有在函数被调用的过程中,才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

#include <stdio.h>
void swap1(int x, int y)
{
	int tep = 0;
	tep = x;
	x = y;
	y = tep;
}
void swap2(int* p1, int* p2)
{
	int tep = 0;
	tep = *p1;
	*p1 = *p2;
	*p2 = tep;
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	swap1(num1, num2);
	printf("swap1:%d %d\n", num1, num2);
	swap2(&num1, &num2);
	printf("swap2:%d %d\n", num1, num2);
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
初阶C语言-函数(上),c语言,开发语言
初阶C语言-函数(上),c语言,开发语言

这里我们可以看到swap1函数在调用的时候,x、y拥有自己的空间,同时拥有了和实参一模一样的内容。所以,我们可以简单认为:形参实例化之后相当于实参的一份临时拷贝

4.函数的调用

4.1传值调用

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

4.2传址调用

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

4.3练习

1.写一个函数可以判断一个数是不是素数。

//写一个函数可以判断一个数是不是素数(打印100~200之间的素数)
#include <stdio.h>
#include <math.h>
int is_prime(int x)
{
	int j = 0;
	for (j = 2; j <= sqrt(x); j++)
	{
		if (x % j == 0)
			return 0;
	}
	return 1;
}
int main()
{
	int i = 0;
	for (i = 100; i <= 200; i++)
	{
		if (is_prime(i))
			printf("%d ", i);
	}
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
这里,我们给大家介绍一下布尔类型(bool),bool类型的变量只有两种取值,true和false.因此,我们也可以用bool类型来写这段程序。

#include <stdio.h>
#include <math.h>
#include <stdbool.h>//bool类型需要添加该头文件
//C语言中有一个bool类型,它的取值只有两种取值true和false
bool is_prime(int x)
{
	int j = 0;
	for (j = 2; j <= sqrt(x); j++)
	{
		if (x % j == 0)
			return false;
	}
	return true;
}
int main()
{
	int i = 0;
	for (i = 100; i <= 200; i++)
	{
		if (is_prime(i))
			printf("%d ", i);
	}
	return 0;
}

初阶C语言-函数(上),c语言,开发语言

2.写一个函数判断一年是不是闰年。

//写一个函数判断一年是不是闰年。(打印1000~2000之间的闰年)
#include <stdio.h>
#include <stdbool.h>//bool类型的头文件
bool is_leap_year(int x)
{
	if (x % 4 == 0 && x % 100 != 0 || x % 400 == 0)
		return true;
	else
		return false;
}
int main()
{
	int y = 0;
	for (y = 1000; y <= 2000; y++)
	{
		if(is_leap_year(y))
			printf("%d ",y);
	}
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
3.写一个函数,实现一个整型有序数组的二分查找。

//写一个函数,实现一个整型有序数组的二分查找。
//找到了返回下标,找不到返回-1
int binary_search(int arr[], int n, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] > n)
			right = mid - 1;
		else if (arr[mid] < n)
			left = mid + 1;
		else
			return mid;
	}
	return -1;
}
#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int n = 0;
	scanf("%d", &n);
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_search(arr,n,sz);
	if (ret == -1)
	{
		printf("找不到!\n");
	}
	else
		printf("找到了,下标是%d", ret);
	return 0;
}

初阶C语言-函数(上),c语言,开发语言
初阶C语言-函数(上),c语言,开发语言
但是,上述代码依然存在着弊端,int mid = (left + right) / 2;针对于left和right数值较小的情况,一旦它们的数值大到一定的时候,会出现溢出的情况。那么,我们该如何求两个数的平均值呢?下面给出图示,我们发现,只需要将b比a多的那部分的一半加到a上就是两者的平均值了,那么代码该如何改进呢?
初阶C语言-函数(上),c语言,开发语言

int binary_search(int arr[], int n, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;//更改的地方,目的为了防止数值太大溢出
		if (arr[mid] > n)
			right = mid - 1;
		else if (arr[mid] < n)
			left = mid + 1;
		else
			return mid;
	}
	return -1;
}
#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int n = 0;
	scanf("%d", &n);
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_search(arr, n, sz);
	if (ret == -1)
	{
		printf("找不到!\n");
	}
	else
		printf("找到了,下标是%d", ret);
	return 0;
}

我们可以发现这样写出来的程序运行结果与刚刚是一样的!
初阶C语言-函数(上),c语言,开发语言
初阶C语言-函数(上),c语言,开发语言
4.写一个函数,每调用一次这个函数,就会将num的值增加1。

//写一个函数,每调用一次这个函数,就会将num的值增加1。
#include <stdio.h>
void add(int *a)
{
	*a = *a + 1;
}
int main()
{
	int num = 0;
	add(&num);
	printf("%d\n", num);
	add(&num);
	printf("%d\n", num);
	add(&num);
	printf("%d\n", num);
	return 0;
}

初阶C语言-函数(上),c语言,开发语言

好啦,关于函数的知识点就先讲到这里,后期会继续更新,欢迎大家持续关注、点赞和评论!文章来源地址https://www.toymoban.com/news/detail-616308.html

到了这里,关于初阶C语言-函数(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 『C语言初阶』第四章-函数

    🔥 博客主页 : 小羊失眠啦. 🔖 系列专栏 : C语言 🌥️ 每日语录 : 世上无难事,只怕有心人。 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 各位小伙伴们,时隔多日,小羊今天又来和大家一起学习C语言新的知识:函数,好的,废话不多说,咱们直接进入主题! 通常大家第一眼

    2024年02月14日
    浏览(29)
  • 初阶C语言——特别详细地介绍函数

     💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        从标题也能看出来,我们有要进行 超详细

    2024年02月14日
    浏览(35)
  • 【初阶C语言3】特别详细地介绍函数以及在初阶中重要的算法——递归

     💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        从标题也能看出来,我们有要进行 超详细

    2024年02月08日
    浏览(47)
  • 【初阶C语言】学会使用库函数getchar和putchar

    目录 一、getchar函数 1.作用: 2.认识函数 3.运用 二、putchar函数 1.作用 2.定义 3.运用 三、getchar与putchar的运用 四、getchar的应用 1.作用:       该函数的作用是 接收一个字符 ,然后把该字符 转化对应的ASCII值 2.认识函数  参数类型:括号里面的void意思是 不接受参数 ,就是括

    2024年02月15日
    浏览(41)
  • 【初阶C语言】关于scanf函数的超详细介绍和多组输入

    感谢各位可以光临娥子的作品   我们学习一个函数,要围绕三个点 :1.函数是什么  2.函数的用法   3.注意的细节 认识一个 函数,我们需要了解他的功能、返回值、接收的参数三个方面 函数原型  (1)功能介绍          scanf函数是一个输入函数 ,所以接收的参数类型需

    2024年02月08日
    浏览(54)
  • 以太坊智能合约开发:Solidity语言中的构造函数

    Solidity语言中关于构造函数的定义: 构造函数是使用 constructor 声明的一个可选函数; 构造函数只在合约部署时调用一次,并用于初始化合约的状态变量; 如果没有显式定义的构造函数,则由编译器创建默认构造函数。 构造函数声明语法如下: 其中: ** constructor :

    2024年02月01日
    浏览(52)
  • 【C++初阶】构造函数和析构函数

    📖 默认成员函数 用户没有显式实现,编译器会自动生成的成员函数,称为默认成员函数。 构造函数 :完成对象的初始化工作。 析构函数 :完成对象空间的清理工作。 拷贝构造 :使用同类对象初始化创建对象。 赋值重载 :把一个对象赋值给另外一个对象(该对象已存在

    2024年02月17日
    浏览(51)
  • 【C++初阶】:内联函数

    在c语言中,如果一个函数较短并且会被重复使用,那么我们就可以把该函数换成一个宏函数。 贴个小知识,宏函数有许多的坑也是面试官喜欢考的点,如果对行函数不太了解可以看看这篇关于宏的部分传送门 宏函数的优点:不会建立栈帧,提高使用效率。 宏函数的缺点:复

    2023年04月25日
    浏览(33)
  • 【C++初阶】类和对象——构造函数&&析构函数&&拷贝构造函数

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++系列专栏: C++头疼记 ========================================================================= 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性 析构函数 概念 析构函数特性 拷贝构

    2024年02月06日
    浏览(57)
  • 【C++】初阶 --- 内联函数(inline)

    🥰 用C语言先来实现普通的Add函数看一下 👇 转到反汇编来看一下: 可以看到,编译器为了实现一个简单的相加函数,Add函数体内需要执行的汇编指令要很多,而且为了调用函数还要执行指令跳转 (并且要在栈区上为函数开辟栈帧空间) ,如果 Add函数被重复大量地使用,则会

    2024年02月14日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包