C 语言学习五:函数与程序结构

函数与程序结构

  • 函数的声明与定义
    • 函数的声明
    • 函数的定义
    • 函数重载
    • 内联函数
    • 递归函数
    • 构造函数
    • lambda 函数
  • 函数的参数
    • 形参和实参
    • 值传递和引用传递
    • 默认参数
  • 函数的返回
    • 返回多个值
    • 返回引用
    • 返回指针
    • 返回对象
  • 头文件
  • 内部函数和外部函数
    • 内部函数
    • 外部函数

函数的声明与定义

函数的声明

  1. 使用函数之前,需要提供函数的声明。声明告诉编译器有一个函数存在,但不提供具体的实现
  2. 通常在头文件(.h)中进行函数声明,以便在多个文件中共享函数接口
  3. 函数声明包括函数的返回类型、函数名、参数列表(参数类型和参数名),但不包括函数体
    // 函数声明
    int add(int a, int b);
    

函数的定义

就是cpp里的函数的具体实现

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

函数重载

C++允许在同一作用域中声明多个具有相同名称但参数列表不同的函数

// 函数重载
int add(int a, int b);
double add(double a, double b);

内联函数

  • 什么是内联函数?——参考文章
  • 使用场景:
    内联函数通常用于需要频繁调用、函数体较小且性能敏感的情况。它是一种编译器的优化手段,可以提高程序的执行效率。内联函数的使用场景包括但不限于:
    小型函数体: 内联函数适用于函数体较小的情况,因为内联函数会将函数体的代码插入到每次调用的地方,如果函数体较大,内联可能会导致代码膨胀,影响性能。
    频繁调用的函数: 内联函数适用于频繁调用的函数,因为函数调用本身会有一些开销,内联可以减少这种开销。
    性能敏感的代码: 内联函数适用于对性能要求较高的代码段,因为它可以减少函数调用的开销,提高执行速度。
  • 内联函数是在编译时期处理的,而不是在预处理时期。在编译时,编译器会根据函数的声明和定义,在每次调用的地方插入函数体的代码,而不是像普通函数一样生成一个独立的函数调用。这样可以减少函数调用的开销,但也会增加代码的体积。因此,内联函数的使用需要谨慎,最好在性能分析的基础上进行决策。

递归函数

递归函数是调用自身的函数。递归函数需要有一个终止条件,否则将无限循环

// 递归函数
int factorial(int n) {if (n <= 1) {return 1;}return n * factorial(n - 1);
}

构造函数

  • 语法:类名(){}
  1. 构造函数,没有返回值也不写void
  2. 函数名称与类名相同
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次

lambda 函数

[capture](parameters) -> return_type {// 函数体
}
  • capture:捕获列表,用于在 lambda 函数中引用外部变量。捕获列表可以为空,也可以包含变量名、变量列表,或者通过引用捕获。
    parameters:参数列表,与普通函数的参数列表相似,但可以为空。
    -> return_type:返回类型声明,可以省略,编译器会自动推导返回类型。
    {}:函数体
#include <iostream>
int main() {// Lambda 表达式,将两个数相加auto add = [](int a, int b) -> int {	//auto 用于自动推导变量的类型return a + b;};// 使用 Lambda 函数int result = add(3, 4);std::cout << "The sum is: " << result << std::endl;return 0;
}

函数的参数

形参和实参

  • 形参
    1. 形参是函数定义中声明的变量,用于接收调用该函数时传递的实参
    2. 形参在函数定义的括号内声明,它们是函数体内的局部变量,只在函数内部可见
    3. 形参的作用是充当函数内部的占位符,用于处理传递给函数的实际数据
    void exampleFunction(int parameter1, float parameter2) {// function body
    }
    
  • 实参
    1. 实参是函数调用时传递给函数的具体数值或变量
    2. 实参与形参一一对应,按顺序传递给函数。实参的值被赋给对应位置的形参
    3. 实参可以是常量、变量、表达式等
    int main() {int a = 10;float b = 3.14;// 调用函数并传递实参exampleFunction(a, b);return 0;
    }
    

值传递和引用传递

  1. 值传递是指将实参的值复制给形参,在函数内部对形参的修改不影响实参
  2. 引用传递是通过传递实参的引用,使函数能够直接操作实参的值
    #include <stdio.h>
    void byReference(int& x) {x = x * 2;
    }
    void byValue(int x) {x = x * 2;
    }
    int main(int argc, char** argv)
    {int a=2,b=2;byValue(a);byReference(b);printf("a=%d\n", a);printf("b=%d\n", b);
    }
    //结果为a=2;b=4
    

默认参数

默认参数是在函数声明中为形参设置默认值,如果调用函数时没有提供对应实参,将使用默认值

// 函数声明,其中 b 的默认值为 10
void exampleFunction(int a, int b = 10);
// 函数定义
void exampleFunction(int a, int b) {// 函数体
}

函数的返回

返回多个值

可以使用结构体、数组或类等方式实现函数返回多个值的效果

struct Point {int x, y;
};
Point getCoordinates() {Point p;p.x = 10;p.y = 20;return p;
}

返回引用

#include <stdio.h>
int x = 5;
int& getVariable() {return x;
}
int main(int argc, char** argv)
{getVariable() = 10;printf("x的值为:%d\n", x); // x 现在的值是 10return 0;
}

返回指针

函数可以返回指针,通常用于返回动态分配的内存

int* createInt() {		//返回一个指向整数的指针 (int*)int* ptr = new int;	//使用 new 运算符在堆上动态分配了一个新的整数。这个新分配的内存的地址被存储在指针变量 ptr 中*ptr = 42;	//设置了这个内存位置的值return ptr;//return *ptr;如果这样写就是返回int型
}

返回对象

通常用于实现链式调用(也叫流式接口)
在 C++ 中,& 符号用于声明引用

#include <iostream>
struct MathOperations {int value;MathOperations& add(int x) {value += x;return *this;}MathOperations& multiply(int x) {value *= x;return *this;}
};
int main() {MathOperations result{5};   //value 成员初始化为 5result.add(3).multiply(2);std::cout << "Result: " << result.value << std::endl;  // 输出:Result: 16return 0;
}
  • return this与return *this区别
    参考文章
    return *this返回的是当前对象的克隆或者本身(若返回类型为A, 则是克隆, 若返回类型为A&, 则是本身 )。return this返回当前对象的地址(指向当前对象的指针)

头文件

  • 头文件保护
    头文件保护(也称为 include guard 或防卫式声明)是一种防止头文件被多次包含的机制。通过#ifndef、#define、#endif 来实现
    // 头文件保护示例
    #ifndef EXAMPLE_H
    #define EXAMPLE_H// 头文件内容
    #endif
    
  • 内联函数
    通常直接放在头文件中,以便在编译时进行函数体的替换,提高性能
    // 内联函数示例
    #ifndef EXAMPLE_H
    #define EXAMPLE_Hinline int add(int a, int b) {return a + b;
    }
    #endif
    

内部函数和外部函数

内部函数

  • 内部函数是在另一个函数内部定义的函数
    内部函数的作用域限定在外部函数中,无法在外部函数以外的地方调用
    内部函数通常用于封装和隐藏实现细节
void outerFunction() {// 内部函数void innerFunction() {// 内部函数的实现}// 调用内部函数innerFunction();
}

外部函数

  • 默认情况下,函数(除了静态函数和内部函数)具有外部链接性,可以在其他文件中调用
  • 外部函数的声明通常放在头文件中,以便在多文件项目中共享函数接口。

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

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

相关文章

VMware虚拟机安装macOS

VMware虚拟机安装macOS 文章目录 VMware虚拟机安装macOS先看效果一、准备工作①&#xff1a;镜像资源下载②&#xff1a;虚拟机③&#xff1a;安装macOS所必要的插件 二、开始安装①&#xff1a;创建新的虚拟机②&#xff1a;自定义硬件③&#xff1a;开启虚拟机 先看效果 一、…

新东方财报解读:新一轮增长逻辑或蕴于电商业务?

从财报表现来看&#xff0c;教育市场的元气在持续提升。 近日&#xff0c;新东方、好未来等上市公司陆续公布了2023年9-11月的业绩表现。其中&#xff0c;好未来实现营收3.7亿美元&#xff0c;同比增长60.5%&#xff1b;归母净亏损2394.6万美元&#xff0c;亏幅同比收窄53.6%。…

Linux命令之 vim 详解

所有的 Unix Like 系统都会内建 vi 文书编辑器&#xff0c;其他的文书编辑器则不一定会存在。 但是目前我们使用比较多的是 vim 编辑器。 vim 具有程序编辑的能力&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。 安装vim编辑器 yum install vi…

Redis常见数据类型[上]

目录 前言&#xff1a; 基本全局命令 KEYS EXISTS DEL EXPIRE TTL TYPE 数据结构和内部编码 内部编码&#xff1a; 单线程架构 引出单线程模型&#xff1a; 为什么单线程还这么快&#xff1f; String字符串 字符串数据类型&#xff1a; 常见命令&#xff1a; S…

sql题之使用划分会话的方式解决统计间隔连续登录问题

现有各用户的登录记录表&#xff08;login_events&#xff09;如下&#xff0c;表中每行数据表达的信息是一个用户何时登录了平台。 user_idlogin_datetime1002021-12-01 19:00:001002021-12-01 19:30:001002021-12-02 21:01:00 现要求统计各用户最长的连续登录天数&#xff0…

嵌入式学习第十五天!(内存管理、链表)

1. 内存管理&#xff1a; 1. malloc void *malloc(size_t size); 功能&#xff1a;申请堆区空间 参数&#xff1a;size&#xff1a;申请堆区空间的大小 返回值&#xff1a;返回获得的空间的首地址&#xff0c;失败返回NULL 2. free void free(void *ptr); 功能&#xff1a;释…

volatile 关键字的用法说明

volatile字面翻译为不稳定的&#xff0c;易变的。 一般编译器优化时&#xff0c;如果一个数据已经读取进寄存器&#xff0c;后续会优先从寄存器中取值来减少访问存储时间&#xff0c;但如果此数值会随时变动&#xff0c;结果就会出现错误 以下测试 #include <stdio.h> i…

信效度检验2(SPSS

目录 1.效度介绍&#xff1a;2.效度检验&#xff1a;小结&#xff1a; 1.效度介绍&#xff1a; 用于研究题项设计是否合适 2.效度检验&#xff1a; 点击 降维->因子 把涉及到因变量的问题放入即可&#xff1a; 勾选&#xff1a; 得到输出结果&#xff1a; KMO值 0.7…

C语言实战三:图书管理系统

这个图书管理系统包括了添加、查找、删除、编辑、显示和保存书籍信息的功能。书籍信息被保存在一个文本文件中&#xff0c;在程序启动时从文件中加载&#xff0c;退出程序时保存到文件中。用户可以通过命令行界面操作图书管理系统&#xff0c;并进行相应的功能操作。 一、代码…

pg数据库替换指定ip

pg数据库替换指定ip 配菜单是部署机ip发生变化&#xff0c;记录一下处理方法,先根据源ip查询出主键id&#xff0c;在将源ip替换成目标ip updatesys_menu sethref replace(href, 10.116.63.4, 10.116.58.23) whereid in(select*fromsys_menuwherehref like %10.116.58.23% )

信息学奥赛一本通1931:【05NOIP普及组】校门外的树

1931&#xff1a;【05NOIP普及组】校门外的树 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 9210 通过数: 6928 【题目描述】 某校大门外长度为L的马路上有一排树&#xff0c;每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴&#xff0c;马路的一…

24校招,快手测试开发工程师二面

前言 大家好&#xff0c;我是chowley&#xff0c;今天回顾一下&#xff0c;之前参加快手的校招面试 全程没有测试方向问题&#xff0c;一直拷打编程语言特性和数据底层结构 时间&#xff1a;50min 平台&#xff1a;轻雀&#xff08;请勿切屏&#xff09; 过程 自我介绍用…

如何使用wireshark解析二进制文件

目录 目录 1.将已有的packet raw data按照下面格式写入文本文件中 a. Raw IP packet b. Ethernet packet 2.用wiershark导入hex文件 3.设置对应的packet类型 a. Raw IP packet b. Ethernet packet 1.将已有的packet raw data按照下面格式写入文本文件中 a. Raw IP pac…

汽车燃油泵数据分析:全球市场的年复合增长率将达到10%左右

燃油泵是汽车配件行业的专业术语。是电喷汽车燃油喷射系统的基本组成之一&#xff0c;位于车辆油箱内部&#xff0c;燃油泵在启动和发动机运转时工作&#xff0c;如果发动机停止而点火开关仍处于ON时&#xff0c;HFM-SFI控制模块关闭燃油泵的电源&#xff0c;以避免意外点火。 …

OpenCV与机器学习:使用opencv实现KNN

使用opencv实现KNN 前言OpenCV实现KNN生成随机数据使用matplotlib绘制数据OpenCV用于KNN训练生成新数据并观察预测 前言 KNN算法&#xff0c;即K-Nearest Neighbor&#xff0c;是一种简单的机器学习算法。它的基本思想是&#xff1a;如果一个样本在特征空间中的K个最相似&…

标注数据集 --labelimg

前言&#xff1a;我们想要训练自己的数据集时&#xff0c;通常需要自己标注数据集。无论是标注成yolo可识别的txt格式还是voc数据集的xml格式。使用labelimg标注都是一个不错的选择。 下面我们就从创建环境&#xff0c;使用labelimg进行标注两个方面来说明。 1.创建labelimg环境…

ADI 配合 USRP 使用的相控阵天线 cn0566

相控阵天线 在这里插入图片描述

Python实战:爬取微博,获取南京地铁每日客流数据

在这篇文章中&#xff0c;我们将使用 Python 进行网络爬虫&#xff0c;爬取微博上的南京地铁每日客流数据。 一、分析网页 在“南京地铁”微博主页搜索“昨日客流”关键词&#xff0c;搜索到每天发布的昨日客流数据。 “南京地铁”微博主页地址https://weibo.com/u/26382762…

基于视觉的移载协作机器人机床上下料末端纠偏算法

摘 要 针对复合机器人在机床上下料中的定位方法,本文主要关注识别机床卡盘和末端作业面的定位。首先分 析了复合机器人在机床上下料过程中的工作原理及其基本结构,包括 AGV (自动导引车)和协作机器人 的功能及特点。然后,详细阐述了如何使用视觉系统和纠偏算法来…

京东采销急眼,隔空喊话“针对”拼多多,焦虑之下为哪般?

农历新年将至&#xff0c;无论是线下各大商超还是线上电商平台&#xff0c;皆为年终大促而“忙的不亦乐乎”&#xff0c;尤其是近期发生的京东采销人员在直播间向拼多多喊话&#xff0c;“恳请拼多多停止屏蔽&#xff0c;恳请拼多多直接比价”&#xff0c;更是将年底这场朴实无…