嵌入式科普(16)c语言函数参数的传递方式

news2024/11/19 16:36:11

目录

一、概述

二、C函数参数

2.1 一张图讲清

2.2 按数据类型分类:

2.2.1 基本数据类型参数:

2.2.2 数组参数:

2.2.3 结构体参数:

2.2.4 指针参数:

2.2.5 函数指针参数:

2.3 按传递方式分类:

2.3.1 值传递:

2.3.2 指针传递(或引用传递):

三、例程

3.1 值传递-副本的地址不同

3.2 结构体的传递效率

3.3 数组参数


嵌入式科普(16)c语言函数参数的传递方式

一、概述

  • c语言函数参数分类简介

  • 为【八、e2studio VS STM32CubeIDE之const修饰库函数形参】做铺垫

二、C函数参数

2.1 一张图讲清

图片

2.2 按数据类型分类:

2.2.1 基本数据类型参数:

int、char、float、double 等基本数据类型可以直接作为函数的参数。
特点:参数是通过值传递的,即函数接收到的是参数值的一个副本,对参数值的修改不会影响到原变量。

2.2.2 数组参数:

在C语言中,数组作为函数参数时通常会退化为指向数组首元素的指针。
特点:传递的是地址,而不是数组本身,因此在函数内部可以修改数组元素的值。通常还需要传递数组的大小作为另一个参数。

2.2.3 结构体参数:

结构体可以作为整体作为函数的参数。
特点:如果结构体较大,按值传递会导致较大的性能开销,因此通常选择传递结构体的指针。

2.2.4 指针参数:

指针本身可以作为函数的参数,用于传递变量的地址。
特点:通过指针参数,函数可以访问和修改原变量的值。

2.2.5 函数指针参数:

函数指针也可以作为函数的参数,用于实现回调函数等高级功能。
特点:允许将函数作为参数传递给另一个函数,增加了程序的灵活性和模块化。

2.3 按传递方式分类:

2.3.1 值传递:

默认情况下,C语言中的函数参数是通过值传递的。
特点:函数接收到的是参数值的一个副本,对参数值的修改不会影响到原变量。

2.3.2 指针传递(或引用传递):

通过传递指针或引用,函数可以访问和修改原变量的值。
特点:提高了函数的灵活性,但也需要额外注意内存管理和指针操作的正确性。

三、例程

3.1 值传递-副本的地址不同

#include <stdio.h>  
  
// 这是一个函数,它接收一个整数作为参数(值传递)  
void printValueAndAddress(int value) {  
    printf("Inside function:\n");  
    printf("Value: %d\n", value);  
    printf("Address of value (local variable): %p\n", (void*)&value);  
}  
  
int main() {  
    int a = 5;  
    printf("Before function call:\n");  
    printf("Value: %d\n", a);  
    printf("Address of a: %p\n", (void*)&a);  
      
    printValueAndAddress(a); // 传递的是a的副本  
      
    printf("After function call:\n");  
    printf("Value: %d\n", a);  
    printf("Address of a: %p\n", (void*)&a);  
      
    return 0;  
}
Before function call:  
Value: 5  
Address of a: 0x20001000  
Inside function:  
Value: 5  
Address of value (local variable): 0x20000ffc  
After function call:  
Value: 5  
Address of a: 0x20001000

3.2 结构体的传递效率

#include <stdio.h>  
#include <time.h>  
  
typedef struct {  
    int data[1000];  
} LargeStruct;  
  
// 这是一个函数,它接收指向结构体的指针(指针传递)  
void modifyStructByPointer(LargeStruct *structPtr) {  
    for (int i = 0; i < 1000; ++i) {  
        structPtr->data[i] = i;  
    }  
}  
  
// 这是一个函数,它接收结构体的副本(值传递)  
void modifyStructByValue(LargeStruct structVal) {  
    for (int i = 0; i < 1000; ++i) {  
        structVal.data[i] = i;  
    }  
    // 注意:由于是值传递,这里的修改不会影响main中的原始结构体  
}  
  
int main() {  
    clock_t start, end;  
    double cpu_time_used;  
      
    LargeStruct myStruct;  
      
    // 使用指针传递修改结构体  
    start = clock();  
    modifyStructByPointer(&myStruct);  
    end = clock();  
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;  
    printf("Time taken by pointer: %f seconds\n", cpu_time_used);  
      
    // 使用值传递(虽然这里的修改没有意义,但仅为了对比时间)  
    start = clock();  
    modifyStructByValue(myStruct); // 注意:这里的修改不会影响myStruct  
    end = clock();  
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;  
    printf("Time taken by value: %f seconds\n", cpu_time_used);  
      
    return 0;  
}

3.3 数组参数

#include <stdio.h>  
  
// 函数声明中使用了数组类型,但实际上接收的是指向数组首元素的指针  
void printArray(int myArray[], int length) {  
    for (int i = 0; i < length; i++) {  
        printf("%d ", myArray[i]);  
    }  
    printf("\n");  
}  
  
int main() {  
    int myArray[] = {1, 2, 3, 4, 5};  
    int length = sizeof(myArray) / sizeof(myArray[0]); // 计算数组长度  
      
    // 调用函数,传递数组和长度  
    printArray(myArray, length);  
      
    return 0;  
}

图片

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

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

相关文章

嵌入式数据库概念和基本命令的使用

文章目录 前言一、sqlite数据库概念二、sqlite数据库命令分类和使用1.命令分类1. 系统命令&#xff1a;2. SQLite 命令&#xff1a; 2.系统命令的使用3.sqlite命令的使用 三、sqlite C语言函数的使用和编程方法总结 前言 本篇文章将为大家讲解嵌入式数据库的使用&#xff0c;嵌…

0510Goods的Maven项目

0510Goods的Maven项目包-CSDN博客 数据库字段 商品主页 修改页面 点击商品主页更改信息&#xff0c; 跳转到修改页面&#xff0c; 并保留初始信息。 商品类别最多选取三项&#xff0c;最少选取一项 添加界面 商品类别最多选取三项&#xff0c;最少选取一项

知乎广告推广投放流程以及价格?

知乎作为一个拥有庞大高质量用户群体的知识分享平台&#xff0c;成为了众多品牌不可忽视的广告投放渠道。知乎不仅汇聚了各行各业的专业人士&#xff0c;其独特的社区氛围也为品牌提供了精准触达目标受众的机会。知乎广告推广的投放流程、费用标准&#xff0c;云衔科技提供的专…

如何使用恢复模式修复Mac启动问题?这里提供详细步骤

如果你的Mac无法启动,不要惊慌,Mac有一个隐藏的恢复模式,你可以使用它来诊断和修复任何问题,或者在需要时完全重新安装macOS。以下是如何使用它。 如何在Mac上启动到恢复模式 你需要做的第一件事是启动到恢复模式。尽管操作说明会因你使用的Mac电脑而异,但幸运的是,启动…

15-ps命令

常用选项 aux axjf a&#xff1a;显示一个终端所有的进程u&#xff1a;显示进程的归属用户及内存使用情况x&#xff1a;显示没有关联控制终端j&#xff1a;显示进程归属的进程组idf&#xff1a;以ASCII码的形式显示出进程的层次关系 ps aux其中| more是只显示一部分内容&…

RT-DETR改进教程|加入SCNet中的SCConv[CVPR2020]自校准卷积模块!

⭐⭐ RT-DETR改进专栏|包含主干、模块、注意力机制、检测头等前沿创新 ⭐⭐ 一、 论文介绍 论文链接&#xff1a;http://mftp.mmcheng.net/Papers/20cvprSCNet.pdf 代码链接&#xff1a;https://gitcode.com/MCG-NKU/SCNet/ 文章摘要&#xff1a; CNN的最新进展主要致力于设计更…

一个完美的自动化测试框架应该怎么写?

一、什么是自动化测试框架&#xff1f; 自动化测试框架是为自动化测试用例或者脚本提供执行环境而搭建的基础设施。自动化测试框架有助于有效地开发、执行和报告自动化测试用例。 优点&#xff1a; 代码复用 提高测试效率 更高的测试覆盖率 维护成本低 更早发现和记录bug …

八年前端开发之路中遇到的一些实用技巧分享——代码思路及通用场景

在开发中比较有用的代码思路 1. 链式编程2. 高阶函数应用-(添加数据并提供删除方法)3. 利用Promise链切入&#xff08;延迟执行&#xff09;4. 通过中间层来解决问题&#xff08;装饰者模式&#xff09;5. 单例模式 1. 链式编程 所谓链式编程即是函数调用后返回对象本身 let …

LangChain 核心模块学习、Model I/O部分、llms代码介绍

LangChain 核心模块学习&#xff1a;Model I/O input 提示词 output 大模型输出的结果 Model I/O 是 LangChain 为开发者提供的一套面向 LLM 的标准化模型接口&#xff0c;包括模型输入&#xff08;Prompts&#xff09;、模型输出&#xff08;Output Parsers&#xff09;和模型…

Linux-线程

目录 1. 线程概念 2. 线程vs进程 3. 线程的优缺点 4. 线程创建 4.1 pthread_create 4.2 pthread_self 5. 线程终止 5.1 return 5.2 pthread_exit 5.3 pthread_cancel 6. 线程等待 7. 线程分离 1. 线程概念 线程&#xff1a;轻量级进程&#xff0c;在进程内部执行&a…

【Linux】自动化编译工具——make/makefile(超细图例详解!!)

目录 一、前言 二、make / Makefile背景介绍 &#x1f95d;Makefile是干什么的&#xff1f; &#x1f347;make又是什么&#xff1f; 三、demo实现【见见猪跑&#x1f416;】 四、依赖关系与依赖方法 1、概念理清 2、感性理解【父与子&#x1f468;】 3、深层理解【程序…

什么是Unreal Engine游戏引擎?它有什么优势?

大家好&#xff0c;我是咕噜土豆&#xff0c;很高兴又和大家见面了。在游戏开发行业中&#xff0c;选择合适的游戏引擎是非常重要的。其中&#xff0c;Unreal Engine作为一款功能强大的游戏引擎&#xff0c;在业界非常受欢迎。今天我带大家简单的了解一下。 什么是Unreal Engi…

python中的数据可视化:极坐标散点图

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 python中的数据可视化&#xff1a; 极坐标散点图 [太阳]选择题 关于以下代码输出结果的说法中正确的是? import matplotlib.pyplot as plt import numpy as np n 150 r 2 * np.r…

揭秘奇葩环境问题:IDEA与Maven版本兼容性解析

1.问题描述 最近在实现通过Java爬虫获取网页源码&#xff0c;然后紧接着将源码转换为图片上传到OSS服务器&#xff0c;其中探索了很多办法&#xff0c;但是在实现过程中遇到一个奇葩问题&#xff0c;就是我无论下载任何Maven依赖&#xff0c;都无法正常下载&#xff0c;简直是…

鸿蒙原生应用数量激增20倍,鸿蒙生态“一路狂奔”!

过去几个月&#xff0c;在各地政府和千行百业伙伴的全面支持下&#xff0c;鸿蒙生态建设正在以前所未有的速度和规模蓬勃发展。 鸿蒙生态跑出“加速度”&#xff0c;再迎里程碑进展 从1月华为宣布首批200多家应用厂商加速开发鸿蒙原生应用以来&#xff0c;到3月底已有超4000款…

DeepSort / Sort 区别

推荐两篇博文,详细介绍了deepsort的流程及代码大致讲解: https://blog.csdn.net/qq_48764574/article/details/138816891 https://zhuanlan.zhihu.com/p/196622890 DeepSort与Sort区别: 1、Sort 算法利用卡尔曼滤波算法预测检测框在下一帧的状态,将该状态与下一帧的检测结…

【C++】内联函数、auto、范围for

文章目录 1.内联函数2.auto关键字2.1auto简介2.2auto的注意事项2.3auto不能推导的场景 3.基于范围的for循环(C11)4.指针空值nullptr(C11) 1.内联函数 概念&#xff1a; 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函…

哈希算法在区块链中的应用

哈希算法是区块链技术的核心组件之一&#xff0c;它确保了区块链数据的不可篡改性和安全性。在本文中&#xff0c;我们将探讨哈希算法的基本原理&#xff0c;以及它在区块链中的具体应用。 哈希算法的基本原理 哈希算法是一种数学函数&#xff0c;它接收输入&#xff08;或“消…

STL——deque容器【双端动态数组】

deque容器的基本概念&#xff1a; 功能&#xff1a;双端数组&#xff0c;可以对头端进行插入删除操作 deque与vector的区别&#xff1a; vector队友头部的插入删除效率低&#xff0c;数据量越大&#xff0c;效率越低deque相对而言&#xff0c;对头部的插入删除速度会比vecto…

银行业数据运营场景下的数据埋点方案

1、引言 随着金融科技的快速发展&#xff0c;银行业的数据运营变得日益重要。数据埋点作为数据收集的重要手段&#xff0c;对于银行业务的精细化运营、风险管理和产品迭代等方面起着至关重要的作用。本方案将针对银行业数据运营场景&#xff0c;设计一套完整的数据埋点方案&am…