C语言 函数 下

2023-11-18

函数的定义:如果函数的定义在main函数之后,函数要在main函数前先进行声明

写一个函数完成两个整数的相加

int Add(int a, int b);//函数的声明

int main()
{
	printf("请您输入a,b的值:");
	int a = 0; 
	int b = 0;
	scanf("%d %d", &a, &b);
	//计算
	//函数的调用(传值调用):
	int c = Add(a, b);
	printf("%d\n", c);
	return 0;
}


int Add(int a, int b) //函数的定义 本身就是种特殊的声明 但是函数的使用总体来说要满足:先声明后使用
{
	int c = a + b;//或:return a+b;
	return c;
}
int Add(int a, int b);//函数的声明,一般放在头文件中

int main()
{
	int x = 0;
	int y = 0;
	printf("请输入两个整数:");
	scanf("%d %d", &x, &y);
	printf("%d\n", Add(x,y));

	return 0;
}


int Add(int a, int b)//函数的定义
{
	return a + b;
}

函数的声明:告诉编译器 函数名 参数 返回类型 但是具体存在与否函数声明决定不了    //int Add(int a,int b);
函数的声明一般出现在函数的使用之前,先声明后使用
函数的声明一般要放在头文件中

函数的定义:是指函数的具体实现,交代函数的功能实现

未来在工程中,代码比较多,函数一般放在.h文件中声明,放在.c文件中实现
分为三个部分:  1.函数的定义   2.函数的声明   3.函数在main函数中使用 函数的调用  
使用时,要包含自己的头文件,#include "add.h",在add.c文件中使用
 
包含头文件时,自己创建的头文件用" "双引号, 标准库中的头文件用< >兼括号,  函数具有外部链接属性

多人协作 分模块 大家分别去写不同函数的功能 分模块去写
三个文件 三个模块 main函数 函数的声明  函数的定义 只需要用头文件就可以 将加法功能编写成一个库文件,将编写的函数头文件提供就可以了
代码保护:项目名称 配置属性 配置类型 静态库(lib)应用 然后对代码进行编译 然后生成解决方案 Debug文件点进去,得到代码
 使用的时候将函数头文件包含 用#pragma comment(lib,"静态库名字")//导入静态库
 #pragma comment (lib,"静态库名字") 导入静态库
 在函数中可以将静态库独立出来

函数递归
函数可以实现递归
程序调用自身的编程技巧,一个过程或者函数在其定义或说明中直接或间接调用自身的一种方法,通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
递归策略只需要少量的程序就可描述出解题过程中所需要的多次重复计算,大大的减少了程序的代码量
递归的主要方式是:把大事化小

递归的两个必要条件:
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续,不能无条件的递归
2.每次递归调用之后越来越接近这个限制条件

接受一个整形值(无符号),按照顺序打印它的每一位

#include <stdio.h>
int main()
{
	//1234
	//1234%10=4
	//1234/10=123
	//123%10=3
	//123/10=12
	//12%10=2
	//12/10=1
	//12%10=1
	int a = 0;
	int n = 0;
	int i = 0;
	printf("请输入需要逆序的数字:");
	scanf("%d", &a);
	printf("请输入该数字的位数:");
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		printf("%d", a % 10);
		a /= 10;

	}
	return 0;
}

经历多次循环 不断调用函数 将取得的余位打印出来 分别进行对10取模 然后一个个进行取模 得到最终答案

void Print(int n)
{//必须有条件
	if (n > 9)//两位数
	{
		Print(n / 10);//要有限制条件,n不断的变小。
		//现不断的调用函数将前几位依次打印出来,最后打印最后一位
		//不仅要进行递推,还要进行回归
	}
	printf("%d ", n % 10);//不断进行调用 不断进行回归 一个个递推继续向下运行 回归进行打印
	return 0;//函数自己反复被调用
}

int main()  
{
	int num = 0;
	scanf("%d", &num);
	Print(num);
  //Print(1234)
  //Print(123)+ 4
  //Print(12) + 3
  //Print(1)  + 2
  //1
	return 0;
}

递归只需要少量的程序代码就可以完成任务 大大减少了程序的代码量
递归:递推+回归

层层递推 函数调用后 层层回归 函数栈帧逐个建立逐个销毁

递归的两个必要条件:
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续,不能无条件的递归
2.每次递归调用之后越来越接近这个限制条件 

void print(int n)
{
    if (n > 9)
    {
        print(n / 10);
    }
    printf("%d ", n % 10);
}

int main()
{
    int n = 0;
    printf("请您输入一个数:\n");
    scanf("%d", &n);
    print(n);
    return 0;
}

函数之所以能实现调用,递归,都是因为函数在每次调用的时候都会在内存中创建一个函数栈帧
函数栈帧:函数调用需要在C语言内存中申请一片空间,这块空间叫做函数栈帧
函数调用开始,栈帧创建,函数调用结束后,栈帧销毁

编写一个函数不允许创建临时变量 求字符串的长度 
strlen函数 包含string头文件 但是要求不创建临时函数
size_t是一种类型,是无符号整形,size_t是为sizeof设计的
size_t类型的数据打印的时候用 %zd 打印

用strlen函数实现

int main()
{
	char arr[] = "abcdadfddffad";
	int len = strlen(arr);//size_t
	   //arr传参传递的是数组首元素的地址 size_t数组的长度类型
	printf("%d\n", len);//%td
  return 0;
}

模拟实现strlen函数

size_t my_strlen(char* str)
{
	size_t count = 0;       //创建临时变量count
	while (*str  != '\0')   //数组的最后是\0 依次判断数组元素是否数清结束
	{                       //strlen统计的是\0之前的字符,遇到\0就停止统计
		count++;            //存放数组中的个数
		str++;              //指针往后走一步 跳过一个字符指向下一个字符
	}
	return count;           //记录数组元素个数
} 

int main()
{
	char arr[] = "abcsjijsij"; 
	size_t len = my_strlen(arr); 
	printf("%zd\n", len);

	return 0;
}
//创建了临时变量count

不用strlen,编写一个函数不允许创建临时变量 求字符串的长度

size_t my_strlen(char* str)//如果不是\0 则它的长度可以用1+my_strlen的长度 1+my_strlen长度 进行递归
{
	if (*str == '\0')      //如果指向\0递归取消 结束
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);  //如果不是\0则进行递归
	}
}

int main()
{
	char arr[] = "abc";
	size_t len = my_strlen(arr);//数组名传递的是首个数组元素的地址
	printf("%zd\n", len);
	return 0;
}

递归和非递归分别实现求第n个斐波那契数

非递归:

#include<stdio.h> 
int main()
{
	int n = 0;
	int a = 1;
	int b = 1;
	int c = 1;
	printf("请您输入您想要查找的斐波那契数:");
	scanf("%d", &n);
	while (n > 2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	printf("%d\n", c);
	return 0;
}

递归:

int fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 1;
	while (n > 2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}

int main()
{
	int a = 0;
	printf("请您输入您想要查找的斐波那契数: ");
	scanf("%d", &a);
	int sum = fib(a);
	printf("%d\n", sum);
	return 0;
}

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言 函数 下 的相关文章

随机推荐

  • VC++ OpenCV+ZBar二维码识别

    利用OpenCV处理图像的优势 结合ZBar提高二维码识别结果 接口定义 include
  • SpringSecurity配置类--常用配置

    SpringSecurity配置类 在学习这门课的时候 实现各种功能时进行了各种配置 我想将各种配置综合讲述一下 首先自定义配置类 需要继承WebSecurityConfigurerAdapter这个类 在这个类里面做了一些默认配置 Con
  • linux grpc,grpc linux下的编译使用-Go语言中文社区

    1 一些工具安装 apt get install build essential autoconf libtool pkg config apt get install libgflags dev libgtest dev apt get
  • [转]IDEA 撤销 merge 操作(详解)

    目录 一 前言 二 解决方案 通过 Git Bash 命令行解决 1 合并过程中未发生冲突 2 合并过程中发生冲突 三 解决方案 通过 IDEA 解决 附带详细的操作图 1 合并过程中未发生冲突 2 合并过程中发生冲突 四 最后 作为一个开
  • 自己制作的 macOS Mojave 10.15.3 iso 文件,亲测可用(附 VMware15 安装 macOS Catalina 图文教程与 macO Catalina.iso 镜像下载地址)

    注 如果需要分享此资源 请注明原作者 不要把别人的东西当做自己的成果 也不要把别人免费分享出来的东西以有偿的方式去分享 自己制作的 macOS Mojave 10 15 3 iso 文件 亲测可用 已在 VMware 15 5 Player
  • AOSP 预置APP安装 以MicroG GmsCore.apk安装为例

    AOSP 预置APP 以MicroG为例 MicroG 无root安装教程 通过源码修改打开签名欺骗 预置不带源码的APP 其他 AOSP 安装谷歌三件套失败 开始寻找代替方案 尝试使用MicroG项目代替谷歌服务 目前情况 已成功安装 所
  • 第十八节 多核异构核间通信–ipcc

    由于MP157 是一款多核异构的芯片 其中既包含的高性能的A7 核及实时性强的M4 内核 那么这两种处理器在工作时 怎么互相协调配合呢 这就涉及到了核间通信的概念了 IPCC inter processor communication co
  • 【医学影像数据处理】2D/3D patch的crop和merge操作汇总

    在做3D分割任务中 多数的方法多采用整体缩放 或裁剪成一个个小的patch操作 这样做的一个主要原因是内存问题 相较于整体缩放 采用裁剪成patch的方法 对于小目标会更加的鲁棒 这也是大多数3D分割任务中常选取的方式 尤其是针对医学影像的
  • spring boot项目同时传递参数和文件的多种方式

    在开发接口中 遇到了需要同时接收参数和文件的情况 可以有多种方式实现文件 参数的接收 这里基于spring boot 3 vue 3 axios 做一个简单的代码演示 1 简单参数 文件参数 参数较少时 比较方便 直接参数接受即可 1 1
  • Mac上亲测好用的BlueStacks蓝叠安卓模拟器

    bluestacks mac是一款基于macOS系统打造的安卓模拟器 其优秀的稳定性 良好的兼容性一直是玩家的模拟器的首选哦 BlueStacks 4 for mac使Mac用户能够在他们的Mac上下载并享受他们喜欢的Android应用程序
  • vs2019运行asp.net framework(c# 基础) 排课系统的完整步骤

    前言 没想过有朝一日还会学net 毕竟java太强了 但因为特殊需要 还是学了一下net 发现她两真的好像呀 源码仓库 https gitee com web paul scheduling system 前期准备 vs2019 需要asp
  • Handler和Controller的区别

    以前一直以为这两个概念貌似是没有太大的区别 调研发现还是有一些区别的 Handler HandlerMapping接口实现从URL映射到请求处理程序bean 支持映射到bean实例和bean names Controller Base Co
  • 2021-08-10基于人脸识别的学生签到系统

    这是这学期web前端开发的大作业 因为要考研时间有限 很多功能只是先把页面做好了 没事实现和数据库的连接 用的数据大多数是在json中存储的 需求分析 一 教师端 功能需求 1登录 数据需求 用户名 密码 邮箱号 2能够管理课程 增加 删除
  • string16类型转string

    std string WChar2Ansi LPCWSTR pwszSrc int nLen WideCharToMultiByte CP ACP 0 pwszSrc 1 NULL 0 NULL NULL if nLen lt 0 retu
  • android 屏幕适配(亲测最兼容方便)

    Android屏幕适配有很多方式 1 设置屏幕固定尺寸适配 例如适配1280x720 只适合少量固定屏幕的设备 2 百分比布局 开发中多了很多代码 3 通过密度值px转dp来适配 方便兼容 基本准确 4 通过修改系统密度值适配 例如抖音适配
  • 【Linux】定时任务crontab/at

    在linux系统中定时任务常用两个命令crontab及at命令 两者区别在于crontab用于设置循环定时任务 即每隔一定时间或固定时间后启动对应任务命令 at用于设置一次性定时任务 在任务完成后定时任务即删除 1 crontab命令 1
  • 【送书活动】借助ChatGPT和Python,轻松实现办公自动化✨

    前言 作者主页 雪碧有白泡泡 个人网站 雪碧的个人网站 推荐专栏 java一站式服务 React从入门到精通 前端炫酷代码分享 从0到英雄 vue成神之路 uniapp 从构建到提升 从0到英雄 vue成神之路 解决算法 一个专栏就够了 架
  • malloc和strcpy,入门的指针面试题

    指针是C和C 编程语言中一个重要的概念 因此在面试以及工作中经常会涉及到指针相关的问题 现在列举几个比较基础问题 一 void getMemory char p p char malloc 100 void test void char s
  • 【使用Excel批量修改文件名称——超详细教程——无需复杂操作;bat,ren指令】

    基本指令 bat concatenate concatenate 该公式用于给新文件名名称添加后缀 ren公式 ren A2 B2 要注意的是ren后边有一个空格 后边有一个空格 此公式用于合并旧文件与新文件名称 操作步骤 首先创建一个文本
  • C语言 函数 下

    函数的定义 如果函数的定义在main函数之后 函数要在main函数前先进行声明 写一个函数完成两个整数的相加 int Add int a int b 函数的声明 int main printf 请您输入a b的值 int a 0 int b