C/C++|物联网开发入门+项目实战|函数输入与输出|值传递|地址传递|连续空间的传递|嵌入式C语言高级|C语言函数的使用(1)-学习笔记(11)

news/2025/3/15 11:06:40/

文章目录

  • 函数概述
    • 输入参数
      • 示例:
      • 值传递
      • 地址传递
      • 连续空间的传递

参考: 麦子学院-嵌入式C语言高级-C语言函数的使用

函数概述

一堆代码的集合,用一个标签去描述它
复用化,降低冗余度
标签 ------ 函数名
函数和数组都属于内存空间,函数具备3要素:
int *p;
int a[100];
1、函数名(地址)
2、输入参数
3、返回值
在定义函数时,必须将3要素告知编译器。
int fun(int ,int ,char){};
如何用指针保存函数?
char *p;
数组 char(*p)[10];
函数 int (*p)(int,int,char)
定义函数与调用函数的区别
int fun(int a,int b)
{
xxxxx
}
int main()
{
fun(10,2);
}
示例1:函数指针与函数的类型需一致

#include <stdio.h>int main()
{char (*myshow)(const char *,...); //这里必须与函数原型的类型一致,否则报错//c:8:12: warning: assignment from incompatible pointer type [enabled by default]printf("hello world!\n");myshow = printf;myshow("==============\n");return 0;
};
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// 2.c: In function 'main':
// 2.c:9:12: warning: assignment from incompatible pointer type [enabled by default]
// hello world!
// ==============
//

示例2:查看函数的地址

#include <stdio.h>int main()
{int (*myshow)(const char *,...);printf("the printf is %p\n",printf);// printf("hello world!\n");myshow = printf;myshow("==============\n");return 0;
};
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the printf is 00000000004076D0
// ==============

示例3:直接用该地址调用:

#include <stdio.h>int main()
{int (*myshow)(const char *,...);printf("the printf is %p\n",printf);// printf("hello world!\n");myshow =  (int (*)(const char *,...))0x00000000004076C0;myshow("==============\n");return 0;
};
// 定义指针的方式应该相同,且通过地址能够实现调用
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the printf is 00000000004076C0
// ==============

指针完成switch的功能:调用函数的第几项,效率就会非常高。
int (*p[7])(int,int); //函数地址
p[0]=fun1;
p[1]=fun2;
pday; //注册,回调,调用,知道地址和参数就能调用
在这里插入图片描述

输入参数

承上启下的功能
调用者:
只需要标签(要传递的数据) //实参
被调者:
函数的具体实现
函数的返回值 函数名定义(接收的数据){具体实现} //形参
实参传递给形参
传递的形式:
拷贝

示例:

#include <stdio.h>void myswap(int buf) //预分配4个字节
{printf("the buf is %x\n",buf);
}int main()
{int a = 20;myswap(0x123); //逐个复制给接收器return 0;
};
// 如果不给参数,会提示如下错误:
// 2.c: In function 'main':
// 2.c:12:5: error: too few arguments to function 'myswap'
// 2.c:3:6: note: declared here

示例2:

#include <stdio.h>void myswap(char buf) //预分配4个字节
{printf("the buf is %x\n",buf);
}int main()
{int a = 20;myswap(0x1234); //逐个复制给接收器return 0;
};
// 这里明显有溢出,只能存4字节
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// 2.c: In function 'main':
// 2.c:12:5: warning: overflow in implicit constant conversion [-Woverflow]
// the buf is 34

示例3:

#include <stdio.h>void myswap(int buf) //预分配4个字节
{printf("the buf is %x\n",buf);
}int main()
{int a = 20;char *p = "hello wordld!";printf("the p is %x\n",p);myswap(p); //return 0;
};
E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
2.c: In function 'main':
2.c:15:5: warning: passing argument 1 of 'myswap' makes integer from pointer without a cast [enabled by default]
2.c:3:6: note: expected 'int' but argument is of type 'char *'
the p is 40902f
the buf is 40902f

在这里插入图片描述

示例4:

#include <stdio.h>void myswap(int ) //预分配4个字节
{printf("the buf is %x\n",buf);
}int main()
{int a = 20;char *p = "hello wordld!";char b[10];printf("the p is %x\n",p);myswap(b); //逐个复制给接收器return 0;
};
// 2.c: In function 'main':
// 2.c:16:5: warning: passing argument 1 of 'myswap' makes integer from pointer without a cast [enabled by default]
// 2.c:3:6: note: expected 'int' but argument is of type 'char *'
// the p is 40902f
// the buf is 40902f

示例5:

#include <stdio.h>void myswap(int a) //预分配4个字节
{printf("the buf is %x\n",a);
}int main()
{int a = 20;char *p = "hello wordld!";char b[10];printf("the p is %x\n",b);myswap(b); //逐个复制给接收器return 0;
};
// a在函数体内外进行复制,不会冲突,访问效果不一致
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// 2.c: In function 'main':
// 2.c:16:5: warning: passing argument 1 of 'myswap' makes integer from pointer without a cast [enabled by default]
// 2.c:3:6: note: expected 'int' but argument is of type 'char *'
// the p is 64fe10
// the buf is 64fe10

值传递

不会对原有空间进行改变
上层调用者保护自己空间值不被修改的能力,主要用于查看

地址传递

上层,调用者让下层子函数修改自己空间值的方式
类似结构体这样的空间,函数与函数之间调用关系–》连续控件的传递

int a = 10;
fun(&a);
a===?10
示例:

#include <stdio.h>void swap(int *a,int *b) //预分配4个字节
{int c;c = *a;*a = *b;*b = c;
}int main()
{int a = 20;int b = 30;int c;printf("the a is %d,the b is %d\n",a,b);swap(&a,&b);printf("after swap,the a is %d,the b is %d\n",a,b);return 0;
};
// 地址交换
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// the a is 20,the b is 30
// after swap,the a is 30,the b is 20

int a;
scanf(“%d”,a); scanf(“%d”,&a)

连续空间的传递

1、数组(数组名-标签) 用地址传递
实参:
int abc[10];

    fun(abc) //abc是地铁
形参:void fun(int *p) //用地址来描述数组空间编译器也支持以下写法:void fun(int p[10]) //这里的p还是指地址,管理空间大小为10

2、结构体
结构体变量
struct abc{int a;int b;int c;};
struc abc buf;
实参:
fun(buf); //变量拷贝,浪费内存,不建议用
fun(&buf)
形参:
void fun(struct abc a1);
void fun(struct abc *a2); //推荐,节约空间
两种类型:
void fun(char a);
int main()
{
char a = ‘c’;
fun(a);
a == ‘c’; //只复制,不修改
}
示例(编译错误,待查):

#include <stdio.h>void fun(char *p)
{p[1] = '2';
}int main()
{char buf[] = 'hello';fun(buf);return 0;
};
// E:\temp>cd "e:\temp\" && gcc 2.c -o 2 && "e:\temp\"2
// 2.c: In function 'main':
// 2.c:11:18: warning: character constant too long for its type [enabled by default]
// 2.c:11:5: error: invalid initializer

http://www.ppmy.cn/news/52614.html

相关文章

我是如何实现一个简单的阻塞队列的

阻塞队列是一种数据结构&#xff0c;具有线程安全的特性&#xff0c;它可以在多线程环境下使用&#xff0c;实现线程之间的数据传递。在本文中&#xff0c;我们将介绍如何使用Java语言实现一个简单的阻塞队列&#xff0c;包括详细的代码流程和解析。 实现流程 定义一个阻塞队…

ChatGPT写小论文

ChatGPT写小论文 只是个人对写小论文心得?从知乎,知网自己总结的,有问题,可以留个言我改一下 文章目录 ChatGPT写小论文-1.写论文模仿实战(狗头)0.论文组成1.好论文前提:2.标题3.摘要4.关键词5.概述6.实验数据、公式或者设计7.结论&#xff0c;思考8.参考文献 0.模仿1.喂大纲…

JVM,关于JVM基础的知识,你确定不了解一下吗?

目录 一.JVM的概念 什么是JVM&#xff1f; 二.JVM的运行流程 1.class文件如何被JVM加载并运行 2.JVM运行时数据包括哪些区域&#xff08;M&#xff09; 三.类加载的过程&#xff08;M&#xff09; 四.双亲委派模型 1.双亲委派模型分析 2.JAVA中有哪些类加载器&#xf…

Python selenium 模块使用find_element_by_id无效

一、发生异常: 二、原因 查询安装selenium的版本是4.5.0 这个版本不支持页面对象的定位find_element_by_id方法&#xff0c;以前版本支持这些进行元素定位&#xff1a; find_element_by_id find_element_by_name find_element_by_xpath find_element_by_link_text find_elem…

Stm32开发环境从0搭建(Clion作为开发软件)

环境安装 1. 下载CLion开发软件和安装 https://www.jetbrains.com/zh-cn/clion/2. 安装msys2开发环境 一直下一步 参考文档 安装OpenOCD工具(烧录下载工具) 将压缩包解压到环境安装目录下: 安装Arm-Gcc编译环境 将此目录拷贝到安装目录&#xff0c;并解压 配置环境变量 …

Go | 一分钟掌握Go | 3 - 学习路线

作者&#xff1a;Mars酱 声明&#xff1a;本文章由Mars酱原创&#xff0c;部分内容来源于网络&#xff0c;如有疑问请联系本人。 转载&#xff1a;欢迎转载&#xff0c;转载前先请联系我&#xff01; 简介 既然有了好的工具&#xff0c;Go SDK也安装好了&#xff0c;那么我们需…

Rocket 框架基础

Rocket v0.5 DOC Rocket是Rust的一个web框架&#xff0c;它使编写快速、安全的web应用程序变得简单&#xff0c;而不会牺牲灵活性、可用性或类型安全性。 类型安全 从请求到响应&#xff0c;Rocket确保您的类型有意义。样板免费 把时间花在编写真正重要的代码上&#xff0c;让…

python统计图像连通域

文章目录 数组统计函数连通域标记连通域统计 数组统计函数 ndimage提供一系列函数&#xff0c;可以计算标注后的数组的相关特征&#xff0c;比如最值、均值、均方根等。 下列函数&#xff0c;如果未作其他说明&#xff0c;那么就有3个参数&#xff0c;分别是(input, labelsNo…