C语言学习笔记---函数篇章

news/2024/5/9 1:49:39/文章来源:https://blog.csdn.net/m0_69455439/article/details/131998581

C语言程序设计笔记---009

  • C语言函数
    • 1、C语言中函数的分类
      • 1.1、库函数
        • 1.1.1、库函数例程
        • **strcpy拷贝函数例程**
        • **memset内存函数例程**
      • 1.2、自定义函数
        • **自定义函数例程1 --- 找出两个整数中的最大值**
        • **自定义函数例程2 ---- 交换两个整数的值**
        • **自定义函数例程2 --- 易错点 --- 作用域超出范围**
    • 2、函数的参数
      • 2.1、实际参数(实参)
      • 2.1、形式参数(形参)
        • **函数的参数例程 --- 两个整数中的最大值**
    • 3、函数的调用
      • 3.1、传值调用
      • 3.2、传址调用
        • **函数的调用例程1 --- 打印100~200的素数**
        • **函数的调用例程2 --- 函数判断是否为闰年**
        • **函数的调用例程3 --- 二分查找**
        • **函数的调用例程4**
    • 4、函数的嵌套调用和链式访问
      • 4.1、函数嵌套调用
        • 函数嵌套调用例程1
        • 函数嵌套调用例程2
      • 4.2、函数链式访问
        • 链式访问例程1
        • 链式访问例程2
    • 5、结束语

C语言函数

前言:
数学中常见到的函数,在C语言中也可以实现同样的功能

子程序

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

C语言标准规定函数的组成部分:
(1)、函数的功能 ---- 如:求字符串长度
(2)、函数名 -------- 如:strlen
(3)、函数参数 ------ 如:const char* str
组成:int strlen(const char* str);

1、C语言中函数的分类

1.1、库函数

库函数:是C语言标准中约定好的,由编译器的厂商提供实现。
通常封装一些经常频繁使用的功能,提升代码移植性和程序的执行效率
如:printf、scanf…

C语言中常见的库函数

(1)、IO函数(输入输出函数)
(2)、字符串操作函数
(3)、字符操作函数
(4)、内存操作函数
(5)、时间/日期函数
(6)、数学函数
(7)、其他库函数
补充:一组或功能一类的都存入同一头文件中声明,如:stdio.h

1.1.1、库函数例程

pow次方函数例程
double pow(double base,double exponent);
参数:base ---- 基础值
参数:exponent — 阶乘

#include <stdio.h>
#include <math.h>//pow次方函数所需头文件int main()
{int n = 0;n = (int)pow(2, 5);printf("%d\n",n);return 0;
}

strcpy拷贝函数例程

char* strcpy(char* destination,const char* source)
参数:destination ----- 目标值
参数:source ---- 源值

#include <stdio.h>
#include <string.h>//strcpy次方函数所需头文件int main()
{//char arr1[20] = {0};char arr1[20] = "xxxxxxxxxxxxxxxx";//方便监视'\0'char arr2[] = "hello bit ";strcpy(arr1,arr2);//拷贝检测到'\0'结束,多余xxx不打印printf("%s\n", strcpy(arr1, arr2));//返回值就是destination//printf("%s\n", arr1);return 0;
}

memset内存函数例程

void* memset(void* ptr,int value,size_t num);
//将value的数据,以num个数量(字节),存放在被ptr指向的空间地址里
参数:ptr ---- 设置指向的空间的值,单位字节
参数:value ---- 将要被设置的值
参数:num ---- 被指向空间的值的数量

#include <stdio.h>
#include <string.h.>int main()
{char arr[] = "hello bit";memset(arr, 'c', 5);printf("%s\n",arr);return 0;
}

1.2、自定义函数

用户自己定义执行需要的功能的函数,自定义函数
与库函数一样,有函数名、参数、返回值类型

格式

ret_tpye fun_name(paral,*)
{statement;//函数体
}
//ret_tpye ---- 返回值类型
//fun_name ---- 函数名
//paral ------- 函数参数

自定义函数例程1 — 找出两个整数中的最大值

说明:写一个函数可以找出两个整数中的最大值

#include <stdio.h>int get_max(int a, int b)
{return a > b ? a : b;
}
int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int max = get_max(a,b);printf("%d\n",max);return 0;
}

自定义函数例程2 ---- 交换两个整数的值

说明:写一个函数可以交换两个整数的值

#include <stdio.h>
void exchange(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);printf("交换前:%d,%d\n",a,b);exchange(&a,&b);printf("交换后:%d,%d\n",a,b);return 0;
}

自定义函数例程2 — 易错点 — 作用域超出范围

说明:a,b传入函数为局部变量 ,传出来会失败,作用域超出范围

#include <stdio.h>
void exchange(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);printf("交换前:%d,%d\n", a, b);//3,5exchange(a, b);//传的实际参数 --- 实参//函数调用的时候,将实参传递给形参//形参本质是实参的临时拷贝//对形参的修改,不会改变实参printf("交换后:%d,%d\n", a, b);//3,5 --- 结果没达到效果,局部变量return 0;
}

2、函数的参数

2.1、实际参数(实参)

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

2.1、形式参数(形参)

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

函数的参数例程 — 两个整数中的最大值

说明
写一个函数可以找出两个整数中的最大值 — 链式访问应用。

#include <stdio.h>
int get_max(int a, int b)
{return a > b ? a : b;
}
int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int max = get_max(a, b);printf("%d\n", max);get_max(3,5);get_max(a,8+2);get_max(a, get_max(3, 4));//函数的参数可以作为另一个函数的参数return 0;
}

小结
形参实例化之后相当于实参的一份临时拷贝;
实参可以是:常量、变量、表达式、函数等。

3、函数的调用

3.1、传值调用

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

3.2、传址调用

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

函数的调用例程1 — 打印100~200的素数

说明
写一个函数打印100~200的素数
常规写法

#include <stdio.h>
int main()
{int i = 0;for (i = 100; i <= 200; i++){int j = 0;for (j = 2; j < i; j++){if (i % j == 0)printf("%d ", i);}}return 0;
}

函数写法:以及sqrt开平方函数的应用

#include <stdio.h>
#include <math.h>//调用sqrt需调用的头文件int is_prime(int n)
{//拿2~sprt(n)之间的数试除int j = 0;//for (j = 2; j < n; j++)//{//	if (n % j == 0)//		return 0;//能被除1和本身以外的数除,所以不是素数//}//优化for (j = 2; j <=sqrt(n); j++)//sqrt开平方效率更高{if (n % j == 0)return 0;//能被除1和本身以外的数除,所以不是素数}return 1;//是素数
}
int main()
{int i = 0;int count = 0;for (i = 101; i <= 200; i+=2)//优化{if (is_prime(i)){count++;printf("%d ",i);}}printf("\ncount = %d",count);return 0;
}

补充
C语言中有一个布尔类型 — 由C99中引入
_Bool 布尔类型的变量只有两种取值,true / false (真/假)

布尔写法

#include <stdio.h>
#include <math.h>//调用sqrt需调用的头文件
#include <stdbool.h>//调用布尔类型需调用的头文件bool is_prime(int n)//bool布尔类型
{int j = 0;//优化//拿2~sprt(n)之间的数试除for (j = 2; j <=sqrt(n); j++){if (n % j == 0)return false;//能被除1和本身以外的数除,所以不是素数}return true;//是素数
}
int main()
{int i = 0;int count = 0;for (i = 101; i <= 200; i+=2)//优化{if (is_prime(i)){count++;printf("%d ",i);}}printf("\ncount = %d",count);return 0;
}

函数的调用例程2 — 函数判断是否为闰年

说明:
写一个函数判断是否为闰年,打印1000~2000年之间的闰年 — 用闰年判断函数

#include <stdio.h>
#include <stdbool.h>
//判断闰年函数
//bool is_leap_year(int y)
//{
//	//能被4整除但不能被100整除的数,或能被400整除的数
//	if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
//		return true;
//	else
//		return false;
//}
//判断闰年函数 ---- 优化
bool is_leap_year(int y)
{//能被4整除但不能被100整除的数,或能被400整除的数return (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0));
}int main()
{int y = 0;int count = 0;for (y = 1000; y <= 2000; y++){//判断y是否为闰年if (is_leap_year(y))//真,则执行{count++;printf("%d ",y);}}printf("\ncount = %d",count);return 0;
}

函数的调用例程3 — 二分查找

说明:
写一个函数实现一个整型的有序数组的二分查找

#include <stdio.h>//找到了,就返回下标
//找不到,返回-1
int binary_search(int arr[],int k,int sz)
{int left = 0;int right = sz - 1;while (left <= right){int mid = (left + right) / 2;if (arr[mid] < k)left = mid + 1;else if (arr[mid] > k)right = mid - 1;else{return mid;}}return EOF;
}int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int k = 0;scanf("%d",&k);//要查找的值int sz = sizeof(arr)/sizeof(arr[0]);int ret = binary_search(arr,k,sz);if (ret == -1){printf("找不到!\n");}else{printf("找到了,下标是: %d",ret);}return 0;
}

注意
使用int mid = (left+right)/2;//有时是会出错的,不兼容大额数字

举例说明:溢出

#include <stdio.h>
int main()
{int num1 = 2147483646;int num2 = 2147483644;int avg = (num1 + num2) / 2;//-3 -----   溢出最大值了printf("%d\n",avg);return 0;
}

所以优化:a+(b-a)/2;

#include <stdio.h>
int main()
{int num1 = 2147483646;int num2 = 2147483644;int avg = num1 + (num2 - num1) / 2;//2147483645printf("%d\n", avg);return 0;
}

函数的调用例程3 ------ 优化a+(b-a)/2

#include <stdio.h>//找到了,就返回下标
//找不到,返回-1
int binary_search(int arr[],int k,int sz)
{int left = 0;int right = sz - 1;while (left <= right){//int mid = (left + right) / 2;int mid = left + (right - left) / 2;if (arr[mid] < k)left = mid + 1;else if (arr[mid] > k)right = mid - 1;else{return mid;}}return EOF;
}int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int k = 0;scanf("%d",&k);//要查找的值int sz = sizeof(arr)/sizeof(arr[0]);int ret = binary_search(arr,k,sz);if (ret == -1){printf("找不到!\n");}else{printf("找到了,下标是: %d",ret);}return 0;
}

函数的调用例程4

说明
写一个函数,当调用这个函数使得num的值,+1
写法一

#include <stdio.h>
void Add(int* p)
{*p += 1;
}int main()
{int num = 0;scanf("%d",&num);printf("加1前:%d\n", num);Add(&num);printf("加1后:%d\n",num);return 0;
}

写法二

#include <stdio.h>
int  Add(int n)
{n += 1;return n;
}
int main()
{int num = 0;scanf("%d", &num);printf("加1前:%d\n", num);int ret = Add(num);printf("加1后:%d\n", ret);return 0;
}

4、函数的嵌套调用和链式访问

4.1、函数嵌套调用

函数和函数之间可以根据实际的需求进行组合的,也就是相互调用
注意:函数可以嵌套调用,不可以嵌套定义

函数嵌套调用例程1

#include <stdio.h>
void test2()
{printf("可嵌套调用,不可嵌套定义\n");
}void test()
{test2();
}
int main()
{test();return 0;
}

函数嵌套调用例程2

#include <stdio.h>
void test()
{int test2()//不可嵌套定义{return 0;}
}
int main()
{test();return 0;
}

4.2、函数链式访问

一个函数的返回值,作为另一个函数的参数

链式访问例程1

#include <stdio.h>
int main()
{int len = strlen("abc");printf("%d\n",len);//一个函数的返回值,作为另一个函数的参数printf("%d\n", strlen("abc"));char arr1[20] = { 0 };char arr2[] = "abc";printf("%d\n",strlen(strcpy(arr1,arr2)));return 0;
}

链式访问例程2

补充
printf()的返回值 ------ 字符的个数
int printf(const char* format, …)

#include <stdio.h>
int main()
{int num = 123456;printf("%d",printf("%d",printf("%d",num)));//123456//printf("%d", printf("%d", 6));//1234566//printf("%d", 1);//12345666//123456661return 0;
}
#include <stdio.h>
int main()
{printf("%d",printf("%d",printf("43")));//4321return 0;
}

5、结束语

学习好函数,对于思维能力是非常有用的,能够帮助程序员在编写程序时,使用恰当能够大大提高程序的模块化特性,有利于扩展和维护。
因此,编写程序时应该充分发挥函数的作用,并合理地搭配其他语句和特性使用,以便更好地保证程序的正确性、可靠性以及严谨性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_337370.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【小梦C嘎嘎——启航篇】类和对象(上篇)

【小梦C嘎嘎——启航篇】类和对象&#xff08;上篇&#xff09;&#x1f60e; 前言&#x1f64c;什么是面向过程&#xff1f;什么是面向对象&#xff1f;什么是类和对象类中的访问权限属性类的大小计算this 指针构造函数析构函数 总结撒花&#x1f49e; &#x1f60e;博客昵称&…

this is incompatible with sql_mode=only_full_group_by

查看配置 select global.sql_mode 在sql命令行中输入select sql_mode 能够看到sql_mode配置,如果有ONLY_FULL_GROUP_BY&#xff0c;则需要修改 在mysql5.7.5后&#xff0c;ONLY_FULL_GROUP_BY是默认选项&#xff0c;所以就会导致group by的问题 set sql_mode‘复制去掉ONLY_F…

大数据-Spark批处理实用广播Broadcast构建一个全局缓存Cache

1、broadcast广播 在Spark中&#xff0c;broadcast是一种优化技术&#xff0c;它可以将一个只读变量缓存到每个节点上&#xff0c;以便在执行任务时使用。这样可以避免在每个任务中重复传输数据。 2、构建缓存 import org.apache.spark.sql.SparkSession import org.apache.s…

WIZnet W5500-EVB-Pico 静态IP配置教程(二)

W5500是一款高性价比的 以太网芯片&#xff0c;其全球独一无二的全硬件TCP、IP协议栈专利技术&#xff0c;解决了嵌入式以太网的接入问题&#xff0c;简单易用&#xff0c;安全稳定&#xff0c;是物联网设备的首选解决方案。WIZnet提供完善的配套资料以及实时周到的技术支持服务…

解决mysqld服务启动失败

原因如下&#xff1a; 1、进程占用 首先查看下mysql进程: ps -aux | grep mysql有进程号占用了&#xff0c;kill 这个进程号 再重启服务 2、所有者和所属组为mysql 查看/usr/local/MySQL/data/mysqld.pid所有者和所属组是否为mysql 原来是权限有问题&#xff0c…

TPlink云路由器界面端口映射设置方法?快解析内网穿透能实现吗?

有很多网友在问&#xff1a;TPlink路由器端口映射怎么设置&#xff1f;因为不懂端口映射的原理&#xff0c;所以无从下手&#xff0c;下面小编就给大家分享TPlink云路由器界面端口映射设置方法&#xff0c;帮助大家快速入门TP路由器端口映射设置方法。 1.登录路由器管理界面&a…

MySQL中锁的简介——表级锁-元数据锁、意向锁

1.元数据锁 查看元数据锁 select object_type,object_scheme,object_name,lock_type,lock_duration from perfomance_scheme.metadata_locks;2.意向锁 线程A开启事务后在执行update更新语句时候&#xff0c;会给数据加上行锁&#xff0c;加上行锁以后&#xff0c;会对整张表加…

回归预测 | MATLAB实现WOA-ELM鲸鱼算法优化极限学习机多输入单输出回归预测

回归预测 | MATLAB实现WOA-ELM鲸鱼算法优化极限学习机多输入单输出回归预测 目录 回归预测 | MATLAB实现WOA-ELM鲸鱼算法优化极限学习机多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现WOA-ELM鲸鱼算法优化极限学习机多输入回归预测&#…

35.图片幻灯片

图片幻灯片 html部分 <div class"carousel"><div class"image-container"><img src"./static/20180529205331_yhGyf.jpeg" alt"" srcset""><img src"./static/20190214214253_hsjqw.webp"…

【已解决】电脑连上网线但无法上网

文章目录 案例情况解决方案必要的解决方法简要概括详细步骤1、打开控制面板2、打开更改适配器设置3、 找Internet协议版本44、修改配置 可能有用的解决方法 问题解决原理Internet 协议版本 4&#xff08;TCP/IPv4&#xff09;确保IP地址和DNS服务器设置为自动获取 案例情况 网…

基于正交滤波器组的语音DPCM编解码算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...........................................................g0zeros(1,lenH); g1zeros(1,l…

基于51单片机和proteus的加热洗手器系统设计

此系统是基于51单片机和proteus的仿真设计&#xff0c;功能如下&#xff1a; 1. 检测到人手后开启出水及加热。 2. LED指示加热出水及系统运行状态。 功能框图如下&#xff1a; Proteus仿真界面如下&#xff1a; 下面就各个模块逐一介绍&#xff0c; 模拟人手检测模块 通过…

MongoDB的安装(详细教程)

文章目录 前言一、概述二、下载三、安装与启动四、连接1. Shell 命令连接1. Compass-图形化界面客户端 前言 MongoDB 是一个基于分布式文件存储的数据库&#xff0c;主要用于为 web 应用提供可扩展的高性能数据存储解决方案。 以下内容是如何在 windows 下安装 MongoDB 的教程…

github Recv failure: Connection reset by peer

Recv failure: Connection reset by peer 背景处理ping一下github网页访问一下github项目git配置git ssh配置再次尝试拉取 疑惑点待研究参考 背景 晚上敲着代码准备提交&#xff0c;执行git pull&#xff0c;报错Recv failure: Connection reset by peer。看着这报错我陷入了沉…

EMO:重新思考高效的基于注意力的移动块模型

文章目录 摘要1、介绍2、方法论:归纳法和演绎法2.1、通用效率模型标准2.2、元移动块2.3、微设计:倒置残余移动块2.4、面向密集预测的EMO宏观设计 3、实验3.1、图像分类3.2、下游任务3.3、额外的消融和解释分析 4、相关工作5、结束语及未来工作 摘要 论文链接&#xff1a;https…

Linux安装MySQL 8.1.0

MySQL是一个流行的开源关系型数据库管理系统&#xff0c;本教程将向您展示如何在Linux系统上安装MySQL 8.1.0版本。请按照以下步骤进行操作&#xff1a; 1. 下载MySQL安装包 首先&#xff0c;从MySQL官方网站或镜像站点下载MySQL 8.1.0的压缩包mysql-8.1.0-linux-glibc2.28-x…

机器学习:提取问题答案

模型BERT 任务&#xff1a;提取问题和答案 问题的起始位置和结束位置。 数据集 数据集 DRCDODSQA 先分词&#xff0c;然后tokenize 文章长度是不同的&#xff0c;bert的token的长度有限制&#xff0c;一般是512&#xff0c; self-attention的计算量是 O ( n 2 ) O(n^2) O(n…

vo 2 输出helloworld

vo 2 输出helloworld 目录概述需求&#xff1a; 设计思路实现思路分析1.code 拓展实现性能参数测试&#xff1a; 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better r…

NoSQL-Redis集群

NoSQL-Redis集群 一、集群&#xff1a;1.单点Redis带来的问题&#xff1a;2.解决&#xff1a;3.集群的介绍&#xff1a;4.集群的优势&#xff1a;5.集群的实现方式&#xff1a; 二、集群的模式&#xff1a;1.类型&#xff1a;2.主从复制&#xff1a; 三、搭建主从复制&#xff…

[个人笔记] vCenter设置时区和NTP同步

VMware虚拟化 - 运维篇 第三章 vCenter设置时区和NTP同步 VMware虚拟化 - 运维篇系列文章回顾vCenter设置时区和NTP同步&#xff08;附加&#xff09;ESXi设置alias参考链接 系列文章回顾 第一章 vCenter给虚机添加RDM磁盘 第二章 vCenter回收活跃虚拟机的剩余可用空间 vCente…