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

news2024/9/19 10:33:54

文章目录

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

参考: 麦子学院-嵌入式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.coloradmin.cn/o/454547.html

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

相关文章

C语言system讲解

‘system’是C语言标准库中的一个函数&#xff0c;它的作用是对计算机系统进行操作&#xff0c;如创建文件夹&#xff0c;打开文件夹&#xff0c;清空屏幕等等&#xff0c;下面介绍一下常用的几个system命令 system函数原型 int system(const char* command); command是字符…

联发科的好日子结束,出货量暴跌,高通稳住阵脚并开始反击

在手机芯片市场连续3年时间顺风顺水之后&#xff0c;联发科终于迎来了高通的反击&#xff0c;特别是骁龙8G2的发布更是导致联发科在手机芯片市场的步步后退&#xff0c;推动了高通的反弹。 一、形势有利于高通 高通此前的骁龙8G1和骁龙888因出现发热问题&#xff0c;因此被誉为…

4. 线性表

4. 线性表 线性表是最基本、最简单、也是最常用的一种数据结构(逻辑结构)。一个线性表是n个具有相同特性的数据元素的有限序列。 前驱元素&#xff1a; 若A元素在B元素的前面&#xff0c;则称A为B的前驱元素 后继元素&#xff1a; 若B元素在A元素的后面&#xff0c;则称B为…

【翻译一下官方文档】之uniapp的界面弹框交互

大致分 3 种 普通提示loading框弹出选项 我个人理解就是大致知道有些什么&#xff0c;有啥功能&#xff0c;用到的时候&#xff0c;直接去用&#xff0c;不会的回来翻看文档 uni.showToast(OBJECT) 参数类型必填说明平台差异说明titleString是提示的内容&#xff0c;长度与…

C++ 多态详解

目录 多态的概念 定义 C直接支持多态条件 举例 回顾继承中遇到的问题 虚函数-虚函数指针-虚函数列表 虚函数 虚函数指针 虚函数列表 虚函数调用流程 虚函数于普通成员函数的区别 多态的概念 定义 多态&#xff1a;相同的行为方式导致了不同的行为结果&#xff0c;同一行…

【翻译一下官方文档】之uniapp的.sync修饰符

先用一个案例引出.sync修饰符 就是这样一个场景 父组件直接修改状态A当然没问题&#xff0c;但是子组件不能直接修改状态A&#xff0c;因为单向数据流限制 单向数据流 uni-app官网 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定&#xff1a;父级 prop 的更新会…

AFP vs SMB vs NFS: 谁是最好的数据传输协议?

目录 SMB: 什么是SMB 协议&#xff1f; NFS: 什么是NFS协议? AFP: 设么是AFP协议&#xff1f; 如何选择合适的传输协议&#xff1f; 场景1: 大型企业 场景2: 小型网站设计公司 场景3&#xff1a; Linux软件开发组 可以在互联网上使用这些协议吗? AFP vs SMB vs NFS …

Docker的安装和镜像容器的基本操作

Docker的安装和镜像容器的基本操作 Docker 概述Docker与虚拟机的区别namespace的六项隔离Docker核心概念 安装 DockerDocker 镜像操作搜索镜像获取镜像镜像加速下载查看镜像信息查看下载的镜像文件信息查看下载到本地的所有镜像根据镜像的唯一标识 ID 号&#xff0c;获取镜像详…

基于struts + spring + hibernate的题库与试卷管理系统源码

3需求分析和设计方案 3.1 题库管理 3.1.1 试题管理需求分析 试题管理是整个系统非常核心的模块&#xff0c;它基于知识点模块、章节模块、课程模块、题型管理模块完成的基础上的。其中核心元素是试题&#xff0c;通过试题将题库中的各模块连接起来。 试题管理分为题库录入和…

MyBatisPlus学习

官网&#xff1a;https://mp.baomidou.com/ MyBatis Plus&#xff0c;简化 MyBatis &#xff01; 1.概述 需要的基础&#xff1a;把我的MyBatis、Spring、SpringMVC就可以学习这个了&#xff01; 为什么要学习它呢&#xff1f;MyBatisPlus可以节省我们大量工作时间&#xff0…

随机模型预测控制(SMPC)——考虑概率约束(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 模型预测控制&#xff08;MPC&#xff09;又称为滚动时域控制和滚动时域控制&#xff0c;是一种强有力的工程应用技术。MPC的价…

springboot +flowable,处理 flowable 的用户和用户组(一)

一.简介 对于flowable是什么以及关于此框架的具体信息可以参看此项目的官方文档&#xff1a;https://www.flowable.org/docs/userguide/index.html Flowable is a light-weight business process engine written in Java.这是官网文档对此框架的完美解释&#xff1a;Flowable…

AIGC技术周报|清华、北邮新研究:让文生图AI更懂你

AIGC通过借鉴现有的、人类创造的内容来快速完成内容创作。ChatGPT、Bard等AI聊天机器人以及DallE 2、Stable Diffusion等文生图模型都属于AIGC的典型案例。「AIGC技术周报」将为你带来最新的paper、博客等前瞻性研究。 OpenAGI&#xff1a;当大模型遇见领域专家 “愿原力与大型…

ctfshow_WEB_web2 wp

前言 写这个是因为。。。我想摆烂&#xff0c;就去从最简单的题开始做了&#xff0c;想着交一道题是一道嘛&#xff0c;总之觉得这样做很适合欺骗安慰自己&#xff08;逃 然后我发现我错了&#xff0c;我第二道题就做了好久还没做出来&#xff0c;甚至最后去点开了hint…… ps…

多数据源事务

使用 DATASOURCE 模式后&#xff0c;可能一个操作涉及到多个数据源。例如说&#xff1a;创建租户时&#xff0c;即需要操作主库&#xff0c;也需要操作租户库。 考虑到多数据的数据一致性&#xff0c;我们会采用事务的方式&#xff0c;而使用 Spring 事务时&#xff0c;会存在…

FTP服务--文件传输协议

FTP服务--文件传输协议 一、FTP服务端口二、FTP服务主动模式与被动模式三、FTP服务配置方法设置匿名用户访问的FTP服务(最大权限)配置文件中常见字段的含义 一、FTP服务端口 FTP服务器默认使用TCP协议的20,21端口与客户端进行通信 20端口&#xff1a;用于建立数据连接&#x…

GDB调试的基本使用、GDB调试多进程

1. 编译时加选项-g&#xff0c;生成具有调试信息的程序 gcc -g test.c -o test 2. 启动GDB &#xff08;1&#xff09;启动GDB&#xff1a; gdb test &#xff08;2&#xff09;设置运行时参数&#xff1a;&#xff08;主函数中可接收运行时参数&#xff09; set args //…

设计模式实现之state模式

状态模式的定义&#xff1a;Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.&#xff08;当一个对象在状态改变时允许其改变行为&#xff0c;这个对象看起来像其改变了其类&#xff09;。 一个对象可以…

KVM Bridge 配置

目录 Bridge方式原理 网桥方式配置步骤 1、编辑修改网络设备脚本文件&#xff0c;增加网桥设备br0 2、编辑修改网络设备脚本文件&#xff0c;修改网卡设备ens33 3、重启宿主机查看配置 虚拟机配置 Bridge方式原理 如上图&#xff0c;网桥的基本原理就是创建一个网桥并将…

IOC使用Spring实现附实例详解

目录 一、相关导读 1. Maven系列专栏文章 2. Mybatis系列专栏文章 3. Spring系列专栏文章 二、前言 Spring简介 Spring体系结构 三、Spring实现IOC 1. 创建Maven工程&#xff0c;引入对应依赖 2. 创建实体类&#xff0c;Dao接口及实现类 3. 编写xml配置文件 4. 测试…