C语言之函数设计(1)

目录

没有返回值的函数

通用性

不含形参的函数

函数返回值的初始化

作用域

 文件作用域

声明和定义

函数原型声明

头文件和文件包含指令


 

在上节中我们简单的学习了函数的创建方法(函数定义)与函数的使用方法(函数调用),现在我们来学习更为专业的函数创建方法等知识。


没有返回值的函数

在前面的循环结构中我们学习了用*来显示出等腰三角形的程序,下面我们把显示出*的部分作为一个单独的函数,通过调用这个函数显示出直角在左下方的三角形。

#include<stdio.h>/*连续显示出多个n*/
void put_stars(int n)
{while(n-- > 0)putchar('*');
}int main()
{int i, len;printf("生成一个直角在左下方的等腰直角三角形。\n");printf("短边:");scanf("%d", &len);for(i = 1; i <= len; i++){put_stars(i);putchar('\n');}return 0;
}

在put_stars函数中只是用来显示n个*,并没有需要返回的值。这种没有返回值的函数类型,要声明为void

 void就是“空”的意思,在C语言中无论有没有返回的值都同样称为函数,而在其他编程语言中会定义为其他非函数的概念,例如子程序(fortran)或过程(Pascal)。

 这里我们使用put_stars函数把二重循环简化为一重循环,从而提高程序的可读性。


通用性

我们这次来编写一个显示出直角在右下方的等腰三角形的程序。

#include<stdio.h>/*连续显示出多个ch*/
void put_chars(int ch, int n)
{while(n-- > 0)putchar(ch);
}int main()
{int i, len;printf("生成一个直角在左下方的等腰直角三角形。\n");printf("短边:");scanf("%d", &len);for(i = 1; i <= len; i++){put_chars(' ', len - i); //显示出len-i个空格put_chars('*', i);//紧接着显示出i个*putchar('\n');}return 0;
}

让我们来解释下:

本程序需要连续显示出多个空白字符,因此需要创建出put_chars来代替函数put_stars。

put_chars可以连续显示出n个通过形参传递来的字符。

前面我们学习过字符常量是int型的,这里还存在显示字符的char型,我们以后会学习到

 函数put_chars和只能显示*的函数put_stars相比较更具有通用的优势。

putchar(ch);
put_chars(' ', len - i); put_chars('*', i);

ch就是put_chars用来传递字符的,既可以传递空白字符又可以传递*,相信这样单独拉出来解释大家有更加明白的认识。


不含形参的函数

我们用下面一段程序来引出不含形参的参数,大家可以先看程序中的特别的代码试着分析它的作用然后再阅读解析。

#include<stdio.h>
//返回输入的正整数
//关于这个函数的名字不必纠结,学的后面我们就能熟练起适当的函数名了
int scan_pint(void)
{int tmp;do{printf("请输入一个整数:");scanf("%d", &tmp);if(tmp <= 0)puts("\a请不要输入非负正整数。");}while(tmp <= 0);return tmp;
}
/*返回正整数倒转后的值*/
int rev_int(int num)
{int tmp = 0;if(num > 0){do{tmp = tmp * 10 + num % 10;num /= 10;}while(num > 0);}return tmp;
}
int main()
{int nx = scan_pint();//不赋予实参printf("该整数倒转后的值是%d。\n", rev_int(nx));return 0;
}

其中有几段代码是不是有点特殊呢?让我们来看看吧!

int scan_pint(void)

函数scan_pint读取从键盘输入的正整数并返回。该函数不接受形参,为了加以说明在小括号中加入void。

int nx = scan_pint()

调用方也没有必要赋予实参,所以函数调用运算符()是空的,其实在到目前为止我们学习的main函数也可以写为int main(void)


函数返回值的初始化

int nx = scan_pint();

注意main函数中声明变量nx的部分,该变量得初始值是函数scan_pint()的表达式,变量逆向使用函数scan_pint()的返回值进行初始化。

但是该初始化方法只适用于拥有自动存储期的对象,不适合拥有静态存储期的对象。


作用域

函数scan_pint和函数rev_int都包含一个拥有相同的标识符(名称)的变量tmp,但它们是各自不同的变量。

就是说scan_pint中的变量tmp是函数scan_pint特有的变量,对rev_int也是一样。

赋给变量的标识符,它的名称有一个通用的范围就是作用域

在程序块中声明变量的名称,只在该程序块中通用,在其他区域无效,简单来说就是从变量声明的位置开始,到该声明的程序块中的大括号 } 为止这一区间内通用,这样的作用域称为块作用域(block scope)。


 文件作用域

还是老样子,我们用程序来引出,大家可以先观察程序中某一语句的特别之处猜想它们的用法:

/*计算最高分*/
#include<stdio.h>#define NUMBER 5//学生人数int tensu[NUMBER];//数组定义:创建数组实体的声明(定义)int top(void);//函数top的函数原型声明int main()
{extern int tensu[];//数组的声明(可以省略)int i;printf("请输入%d名学生的分数。\n", NUMBER);for(i = 0; i < NUMBER; i++){printf("%d:", i+1);scanf("%d", &tensu[i]);}printf("最高分=%d\n", top());return 0;
}
/*返回数组tensu的最大值(函数top的函数定义)*/
int top(void)
{extern int tensu[];//数组的声明(可以省略)int i;int max = tensu[0];for(i = 1; i < NUMBER; i++){if(tensu[i] > max)max = tensu[i];}return max;
}

在函数程序块中声明的变量等标识符是该程序块中特有的部分,而像数组tensu[ ]这样,在函数外声明的变量标识符,其位置从声明的位置开始到程序的结束都是通用的。

int tensu[NUMBER];//数组定义:创建数组实体的声明(定义)

这样的作用域称为文件作用域


声明和定义

像上面的一个语句,创建了一个元素为5、元素类型为int的数组tensu。这样创建变量实体的声明称为定义(definition)声明

extern int tensu[];//数组的声明(可以省略)

像这样使用了extern的声明表示“使用的是在某处创建的tensu”,这里并没有真正创建出变量的实体,因此称为非定义声明

由于数组tensu是在函数外定义的,所以只需要在main函数或top函数中明确声明要使用它就可以放心使用了。

由于数组tensu被赋予了文件作用域,因此在main函数和top函数中无需特意声明,就可以使用它。


函数原型声明

和人一样,编译器在读取数据时也是从头到尾按照顺序进行读取的,因为top函数的函数定义在main函数之后,所以在想要调用top函数,就需要让编译器知道你的想法。

int top(void);//函数top的函数原型声明

像这样明确记述了函数的返回类型,形参类型和个数的声明称为函数原型声明

该语句要以“;”结尾

 函数原型声明只声明了函数的返回值和形参等相关类型,并没有定义函数的实体。

函数定义和函数原型声明的不同之处如下所示:

函数top的函数定义——定义声明(有实体)

函数top的函数原型声明——非定义声明(没有实体)

 如果top函数的需求(返回值类型,形参等)发生了改变那么函数定义和函数原型声明两部分都必须进行修改,不能只改动其中一个!

如果把函数top的函数定义写在main函数之前,就不用特意使用函数原型声明了,我们推荐把main函数放在程序最后的位置。


头文件和文件包含指令

 

通过函数原型声明,可以指定函数的参数以及返回值的类型等信息,这样就可以放心的使用函数了。

库函数printf或putchar等的函数原型声明都包含在<stdio.h>中,因此必须要使用以下固定的指令:

#include<stdio.h>

通过#include指令,就可以把<stdio.h>中的全部内容都读取到程序中。

包含库函数的函数原型声明的<stdio.h>称为头文件,而取得头文件的#include称为文件包含指令

例如,putchar的函数原型声明在头文件<stdio.h>中的声明格式如下:

	int putchar(int _ _ c);

编译器不同,形参的名称也可能不同。

在函数原型声明的时可以不指定形参的名称,也可以这样进行声明:

	int putchar(int);

我们先学习到这里,之后我们会学习函数的通用性——可以处理任意数组、处理不同元素个数的数组等更加精细的内容。9c6f7383a47e4123af437d548952d129.jpeg

 

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

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

相关文章

现代雷达车载应用——第2章 汽车雷达系统原理 2.2节 汽车雷达架构

经典著作&#xff0c;值得一读&#xff0c;英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 2.2 汽车雷达架构 从顶层来看&#xff0c;基本的汽车雷达由发射器&#xff0c;接收器和天线组成。图2.2给出了一种简化的单通道连续波雷达结构[2]。这…

Doris集群搭建——2.0.1.1版本

目录 一、启动Doris 二、配置并分发doris安装包和环境变量 1.分发doris安装包 2.解压安装包 3.分发环境变量 4.修改对应的配置文件 (1)修改be的配置 (2)修改fe的配置 三、be的扩容与缩容 (一)be扩容 1.添加be节点 3.另外两个节点启动be 4.重新查看be节点状态 (二…

数据可视化?这些平台能处

图表在各行各业都起到举重若轻的作用&#xff0c;无论是项目汇报、业绩分析&#xff0c;亦或是数据挖掘、统计分析&#xff0c;良好的可视化可以为我们的阐述起到画龙点睛的效果。在一篇文章中&#xff0c;如果只有密密麻麻的文字堆积&#xff0c;无论是谁恐怕都无法长期保持注…

如何预防最新的.locked、.locked1勒索病毒感染您的计算机?

尊敬的读者&#xff1a; 近期&#xff0c;网络安全领域迎来一股新潮——.locked、.locked1勒索病毒的威胁&#xff0c;其先进的加密技术令人生畏。本文将深入剖析.locked、.locked1勒索病毒的阴谋&#xff0c;提供特色数据恢复策略&#xff0c;并揭示锁定恶劣行径的先锋预防手…

RK3568平台(网络篇)添加网络交换芯片RTL8306M

一.硬件原理图 分析&#xff1a; 该交换芯片支持I2C、SPI、mdio通信&#xff0c;但是看ast1520的uboot代码采用的是mdio去通信phy芯片的&#xff0c;所以暂时也先采用mdio的方式&#xff0c;需要配置相应的引脚才可以配置成mdio通信模式&#xff0c;具体的配置硬件工程师解决。…

使用netcore编写对比excel差异

一、新建项目Vlook项目 using MiniExcelLibs; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data; using System.IO;namespace Vlook {internal class Program{static void Main(string[] args){var dir App…

L1-046:整除光棍

题目描述 这里所谓的“光棍”&#xff0c;并不是指单身汪啦~ 说的是全部由1组成的数字&#xff0c;比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如&#xff0c;111111就可以被13整除。 现在&#xff0c;你的程序要读入一个整数x&#xff0c;这个…

通义千问关于网络模块的专业知识能力正确率测试

闲着无聊&#xff0c;就用问答区的一个问题&#xff0c;去考验了通义千问&#xff0c;结果优点出乎意料。 我们来看一下具体的问题&#xff0c;这里&#xff0c;我准备了三个问题&#xff1a; 第一个问题&#xff1a;11.192.0.x 注意&#xff0c;这里我并没有增加任何的辅助提…

关于文件操作---C语言

引言 关于文件&#xff0c;想必大家或多或少都会有些了解&#xff0c;文件可以帮我们储存数据&#xff0c;不同格式的文件可以储存不同类型的数据&#xff0c;也可以将文件中的数据用不同的方式打开。电脑中的文件&#xff0c;是放在硬盘上的。在我们编写代码并运行的时候&…

金蝶云星空表单插件获取复选框的值

文章目录 金蝶云星空表单插件获取复选框的值 金蝶云星空表单插件获取复选框的值 object getPur this.View.Model.GetValue("F_XHWT_IsPur", rowIndexV);bool isSerial !Convert.ToBoolean(itemClose["F_XHWT_IsPur"] "");取得值可以直接转换成…

Datawhale聪明办法学Python(task3变量与函数)

一、课程基本结构 课程开源地址&#xff1a;课程简介 - 聪明办法学 Python 第二版 章节结构&#xff1a; Chapter 0 安装 Installation Chapter 1 启航 Getting Started Chapter 2 数据类型和操作 Data Types and Operators Chapter 3 变量与函数 Variables and Functions Ch…

Cortex-M4内核结构

Cortex-M4内核结构 1. 内核Core 2. 三阶流水线 3. 内核工作模式 4. 总结 Cortex-M4内核结构 Cortex-M4处理器是ARMv7-M架构的一种实现&#xff0c;它是一种32位精简指令集(Reduced Instruction Set Computing, RISC)的处理器&#xff0c;有一个三阶的指令流水线&#xff0c;依…

飞天使-docker知识点4-harbor

文章目录 Harbor安装完成harbor 官方建议方式之后查看 images配置docker 使用harbor 仓库上传下载镜像docker 镜像结合harbor 运行 Harbor Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器&#xff0c;由 vmware 开源&#xff0c;其通过添加一些企业必需的功…

C++初阶-list类的模拟实现

list类的模拟实现 一、基本框架1.1 节点类1.2 迭代器类1.3 list类 二、构造函数和析构函数2.1 构造函数2.2 析构函数 三、operator的重载和拷贝构造3.1 operator的重载3.2 拷贝构造 四、迭代器的实现4.1 迭代器类中的各种操作4.1 list类中的迭代器 五、list的增容和删除5.1 尾插…

Visual Studio 2022封装C代码为x64和x86平台动态库

1.引言 本文介绍如何使用Visual Studio 2022将C语言函数封装成x64和x86平台上使用的动态链接库(dll文件)并生成对应的静态链接库(lib文件)&#xff0c;以及如何在C程序中调用生成的dll。 程序下载&#xff1a; 2.示例C语言程序 假设需要开发一个动态链接库&#xff0c;实现复…

for-each循环优先于传统的for循环

在大多数情况下&#xff0c;使用 for-each 循环&#xff08;也称为增强型 for 循环&#xff09;比传统的 for 循环更加简洁和方便。它提供了一种更直观的方式来遍历集合或数组中的元素。以下是一个例子&#xff0c;展示了 for-each 循环优于传统 for 循环的情况&#xff1a; i…

AI智能配音助手微信小程序前后端源码支持多种声音场景选择

大家好今天给大家带来一款配音小程序 &#xff0c;这款小程序支持多种不同声音和场景的选择更人性化&#xff0c; 比如说支持各地区的方言,英文,童声呀等等、 另外也支持男声女声的选择,反正就是模板那些非常的多 当然啦音量,语调,语速那些都是可以DIY跳转的哟,所以说这一款小程…

python每日学11:xpath的使用与调试

背景&#xff1a;最近在使用selenium 模拟浏览器作一些常规操作&#xff0c;在使用selenium的过程中接触到的一种定位方法&#xff0c;叫xpath, 这里说一下使用心得。 首先&#xff0c;我觉得如果只是简单使用的话是不用详细了解具体的语法规则的。 一、xpath怎么用&#xff1…

树莓派(Raspberry Pi)4B密码忘记了,怎么办?

树莓派长时间不用&#xff0c;导致密码忘记了&#xff0c;这可咋整&#xff1f; 第1步&#xff1a;取出SD卡 将树莓派关机&#xff0c;移除sd卡&#xff0c;使用读卡器&#xff0c;插入到你的电脑。 第2步&#xff1a;编辑 cmdline.txt 在PC上打开SD卡根目录&#xff0c;启动…

【星环云课堂大数据实验】kafka消息发布与订阅

文章目录 一、Kafka概述二、实验环境三、实验准备四、实验目的五、实验步骤5.1、创建Kafka Topic5.2、Kafka消息发布5.3、Kafka消息订阅 六、实验感悟 一、Kafka概述 Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;由Scala和Java编写。该项目的目标是为处理实…