C/C++ 函数的定义 声明 调用的区别

2023-05-16

C语言基础:函数(定义函数、声明函数、调用函数(传值调用 / 引用调用)、函数的参数(形参 / 实参))

1. 函数

函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。

函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

C 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。

1.1 定义函数

返回类型 函数名称( 参数 )
{
   函数体
}

在 C 语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:

返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。
函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
函数体:函数体包含一组定义函数执行任务的语句。

max函数有两个参数 num1 和 num2,会返回这两个数中较大的那个数:

#include <stdio.h>
int main () {
	printf("max(3,4) = %d",max(3,4));
}
/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2) {
	/* 局部变量声明 */
	int result;

	if (num1 > num2)
		result = num1;
	else
		result = num2;

	return result;
}
运行结果: max(3,4)  = 4

1.2 函数声明

函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。

当您在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,您应该在调用函数的文件顶部声明函数。

函数声明包括以下几个部分:

return_type function_name( parameter list );

针对上面定义的函数 max(),以下是函数声明:

int max(int num1, int num2);

在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:

int max(int, int);

1.3 调用函数

在这里插入图片描述
当调用函数时,有两种向函数传递参数的方式:
在这里插入图片描述

1.3.1 传值调用

向函数传递参数的传值调用方法,把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。

默认情况下,C 语言使用传值调用方法来传递参数。一般来说,这意味着函数内的代码不会改变用于调用函数的实际参数。函数 swap() 定义如下:

/* 函数定义 */
void swap(int x, int y)
{
   int temp;

   temp = x; /* 保存 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 temp 赋值给 y */
  
   return;
}

现在,让我们通过传递实际参数来调用函数 swap():

#include <stdio.h>
 
/* 函数声明 */
void swap(int x, int y);
 
int main ()
{
   /* 局部变量定义 */
   int a = 100;
   int b = 200;
   printf("交换前,a 的值: %d\n", a );
   printf("交换前,b 的值: %d\n", b );
   /* 调用函数来交换值 */
   swap(a, b); 
   printf("交换后,a 的值: %d\n", a );
   printf("交换后,b 的值: %d\n", b );
   return 0;
}

/* 函数定义 */
void swap(int x, int y)
{
   int temp;
   temp = x; /* 保存 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 temp 赋值给 y */
  
   return;
}

运行结果为:
在这里插入图片描述

1.3.2 引用调用

通过引用传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

传递指针可以让多个函数访问指针所引用的对象,而不用把对象声明为全局可访问。

/* 函数定义 */
void swap(int *x, int *y)
{
   int temp;
   temp = *x;    /* 保存地址 x 的值 */
   *x = *y;      /* 把 y 赋值给 x */
   *y = temp;    /* 把 temp 赋值给 y */
  
   return;
}

现在,让我们通过引用传值来调用函数 swap():

#include <stdio.h>
/* 函数声明 */
void swap(int *x, int *y);
int main () {
	/* 局部变量定义 */
	int a = 100;
	int b = 200;

	printf("交换前,a 的值: %d\n", a );
	printf("交换前,b 的值: %d\n", b );

	/* 调用函数来交换值
	 * &a 表示指向 a 的指针,即变量 a 的地址
	 * &b 表示指向 b 的指针,即变量 b 的地址
	*/
	swap(&a, &b);
	printf("交换后,a 的值: %d\n", a );
	printf("交换后,b 的值: %d\n", b );
	return 0;
}
/* 函数定义 */
void swap(int *x, int *y) {
	int temp;
	temp = *x;    /* 保存地址 x 的值 */
	*x = *y;      /* 把 y 赋值给 x */
	*y = temp;    /* 把 temp 赋值给 y */

	return;
}

在这里插入图片描述

1.4 函数参数

1.4.1 形参

形参就是定义函数时的那个参数。

1.4.2 实参

实参就是调用函数时传递的那个参数。

1.5函数调用

#include <stdio.h>
#include <stdlib.h>

void fun(int a, int b); /*声明函数原型*/

int main()
{
    int a, b;
    scanf("%d %d", &a, &b);
    fun(a, b); /*函数调用*/
    return 0;
}

void fun(int a, int b){ /*函数定义*/
    int res = a + b;
    printf("res = %d", res);
}

C++

为了支持分离式编译,C++将定义和声明区分开。其中声明规定了变量的类型和名字,定义除此功能外还会申请存储空间并可能为变量赋一个初始值。
extern
如果想声明一个变量而非定义它,就使用关键字extern并且不要显式地初始化变量:

extern int i;      // 声明i而非定义i
extern int i = 1;  // 定义i, 这样做抵消了extern的作用

static
当我们在C/C++用static修饰变量或函数时,主要有三种用途:

局部静态变量
外部静态变量/函数
类内静态数据成员/成员函数

其中第三种只有C++中有,我们后续在面向对象程序设计中再探讨,这里只讨论静态局部/全局变量。

1. 静态局部变量

在局部变量前面加上static说明符就构成静态局部变量,例如:

// 声明局部静态变量
static int a;
static int array[5] = {1, 2, 3, 4, 5};
静态局部变量在函数内定义,但不像自动变量那样当函数被调用时就存在,调用结束就消失,静态变量的生存期为整个源程序
静态变量的生存期虽然为整个源程序,但是作用域与自动变量相同,即只能在定义该变量的函数内使用该变量,退出函数后虽然变量还存在,但不能够使用它
对基本类型的静态局部变量如果在声明时未赋初始值,则系统自动赋0值;而对普通局部变量不赋初始值,那么它的值是不确定的

根据静态局部变量的特点,它的生存期为整个源程序,在离开定义它的函数(作用域)但再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量,虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此最好采用局部静态变量。例如:

#include <iostream>
 
void foo() {
    int j = 0;         // 普通局部变量
    static int k = 0;  // 静态局部变量
    ++j;
    ++k;
    printf("j:%d, k:%d\n", j, k);
}
 
int main(void)
{
    for (int i = 1; i <= 5; i++) {
        foo();
    }
}
 
// 输出:
j:1, k:1
j:1, k:2
j:1, k:3
j:1, k:4
j:1, k:5

2. 静态全局变量(C++废弃,用匿名命名空间替代)

Tips:对于全局变量,不管是否被static修饰,它的存储区域都是在静态存储区,生存期为整个源程序。只不过加上static后限制这个全局变量的作用域只能在定义该变量的源文件内。

全局变量(外部变量)的声明之前加上static就构成了静态的全局变量,全局变量本身就是静态存储变量,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同,这两者的区别在于非静态全局变量的作用域是整个源程序。当一个源程序由多个源程序组成时,非静态的全局变量在各个源文件中都是有效的,而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。

这种在文件中进行静态声明的做法是从C语言继承而来的,在C语言中声明为static的全局变量在其所在的文件外不可见。这种做法已经被C++标准取消了,现在的替代做法是使用匿名命名空间。
匿名命名空间:指关键字namespace后紧跟花括号括起来的一系列声明语句,具有如下特点:

在匿名命名空间内定义的变量具有静态生命周期
匿名空间在某个给定的文件内可以不连续,但是不能跨越多个文件
每个文件定义自己的匿名命名空间,不同文件匿名命名空间中定义的名字对应不同实体
如果在一个头文件中定义了匿名命名空间,则该命名空间内定义的名字在每个包含该头文件的文件中对应不同实体
namespace {
    int i;  // 匿名命名空间内定义的变量具有静态生命周期, 作用域仅限于当前文件
}

3. 总结

static这个说明符在不同地方所起的作用域是不同的,比如把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期,把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。

auto

  1. C++98中auto用法(C++11已废弃)
    C++98 auto用于声明变量为自动变量(拥有自动的生命周期),C++11已经删除了该用法,取而代之的是“变量的自动类型推断方法”。
// c++ 98:
int a = 10;         // 拥有自动生命期
auto int b = 20;    // 拥有自动生命期(C++11编译不过)
static int c = 30;  // 延长了生命期

C++11新标准引入了auto类型说明符,让编译器通过初始值来自动推断变量类型(这意味着通过auto定义的变量必须有初始值)。

// c++ 11:
int a = 10;
auto auto_a = a;  // 自动类型推断为int类型
  1. auto会去除变量的引用语义
    当引用对象作为初始值时,真正参与初始化的是引用对象的值,此时编译器会以引用对象的类型作为auto推算的类型:
int main(void) {
    int i = 10;
    int &ri = i;
    auto auto_i = ri;  // 去除引用语义, 自动推断为int
}

如果希望推断出来的auto类型包含引用语义,我们需要用&明确指出:

int main(void) {
    int i = 10;
    auto &auto_i = i;  // 加上引用语义, 自动推断为int&
}
  1. auto忽略顶层const
    auto一般会忽略掉顶层const,同时底层const会被保留下来:
int main(void) {
    const int ci = 10;    // 常量int
    auto auto_ci = ci;    // auto_ci被推断为int类型
    auto_ci = 20;         // 正确: auto_ci非常量
 
    const int &cr = ci;   // cr是指向常量int的常量引用
    auto auto_cr = cr;    // auto_cr被推断为int类型: 去除了引用语义 + 去除了顶层const
    auto_cr = 20;         // 正确: auto_cr非常量
 
    const int *cp = &ci;  // cp是指向常量int(底层)的常量指针(顶层)
    auto auto_cp = cp;    // auto_cp被推断为const int*类型(指向常量int的指针): 去除了顶层const + 保留底层const
    // *auto_cp = 10;     // 错误: 不能修改auto_cp指向的常量
}

如果希望推断出来的auto类型是一个顶层const,我们需要通过const关键字明确指出:

int main(void) {
    const int ci = 10;          // 常量int
    const auto auto_ci = ci;    // auto_ci被推断为const int类型
    // auto_ci = 20;            // 错误: auto_ci是一个常量, 禁止修改
}

const

有时我们希望定义一个不能被改变值的变量,可以使用关键字const对变量类型加以限定。

1. const对象必须初始化

因为const对象一经创建后其值就不能再改变,所以const对象必须初始化,但是初始值可以是任意复杂的表达式:

const int i = get_size();  // 正确: 运行时初始化
const int j = 42;          // 正确: 编译时初始化
const int k;               // 错误: k是一个未经初始化的常量
  1. 默认情况下const仅在文件内有效
    举个例子,我们在编译时初始化一个const对象:
const int i = 10;

编译器会在编译过程把用到该变量的地方都替换为对应的值。为了执行这个替换,编译器必须知道变量的初始值,如果程序包含多个文件,那么每个用了这个const对象的文件都必须得能访问到它的初始值才行(即每个文件都要定义const对象)。为了避免对同一变量的重复定义,当多个文件中出现同名的const对象时,其实等同于在不同文件中分别定义了独立的变量。

/*
 * 下面是合法的, 不存在变量i重复定义问题
 */
 
// foo.cpp
const int i = 10;
 
// bar.cpp
const int i = 5;

如果想在多个文件之间共享const对象,那么必须在变量的定义之前添加extern关键字:

/*
 * 下面是合法的, main.cpp和foo.cpp中的const int对象是同一个
 */
 
// foo.cpp
extern const int i = 10;
 
// main.cpp
#include <iostream>
 
int main(void) {
    extern int i;
    std::cout << "i:" << i << std::endl;
}
  1. 允许常量引用绑定非常量对象、字面值甚至一般表达式
    一般而言,引用的类型必须与其所引用对象的类型一致,但是有两个例外:

初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用类型即可,允许为一个常量引用绑定非常量的对象、字面值甚至是一个一般表达式(如下)
可以将基类的指针或引用绑定到派生类对象上(后续面向对象章节再探讨)

int i = 10;
 
const int &ri1 = i;      // 合法: 绑定到非常量对象
const int &ri2 = 100;    // 合法: 绑定到字面值
const int &ri3 = 1 + 1;  // 合法: 绑定到一般表达式
  1. 顶层const与底层const
    指针本身是一个对象,因此指针本身是不是常量与指针所指对象是不是常量是两个独立的问题,前者被称为顶层const,后者被称为底层const。
Tips:指针类型既可以是顶层const也可以是底层const,其他类型要么是顶层常量要么是底层常量。

顶层const用于表示任意的对象是常量,包括算数类型、类和指针等,底层const用于表示引用和指针等复合类型的基本类型部分是否是常量。

int i = 10;
 
int *const p1 = &i;        // 顶层const: 不能改变p1的值
const int *p2 = &i;        // 底层const: 不能通过p2改变i的值
const int *const p3 = &i;  // 底层const + 顶层const
 
const int &r1 = i;         // 底层const: 不能通过r1改变i的值
constexpr

C++11引入了常量表达式constexpr的概念,指的是值不会改变并且在编译期间就能得到计算结果的表达式。

const int i = 10;          // 常量表达式
const int j = i + 1;       // 常量表达式
const int k = size();      // 仅当size()是一个constexpr函数时才是常量

表达式, 运行时才能获得具体值就不是常量表达式
在一个复杂系统中,我们很难分辨一个初始值是否是常量表达式,通过constexpr关键字声明一个变量,我们可以让编译器来验证变量的值是否是一个常量表达式。

  1. 字面值是常量表达式
    算术类型、引用和指针都属于字面值类型,自定义类则不属于字面值类型,因此也无法被定义为constexpr。
Tips:尽管指针和引用都能被定义成constexpr,但它们的初始值却受到严格限制。一个constexpr指针的初始值必须是nullptr、0或者是存储于某个固定地址中的对象。
  1. constexpr是对指针的限制
    在constexpr声明中定义了一个指针,限定符constexpr仅对指针有效,与指针所指对象无关:
const int *pi1 = nullptr;      // 底层const: pi1是指向整型常量的普通指针
constexpr int *pi2 = nullptr;  // 顶层const: pi2是指向整型的常量指针

我们也可以让constexpr指针指向常量:

constexpr int i = 10;
constexpr const int *pi = &i;  // 顶层const + 底层const
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++ 函数的定义 声明 调用的区别 的相关文章

  • SiC MOSFET驱动电压的分析及探讨

    SiC设计干货分享 xff08 一 xff09 xff1a SiC MOSFET驱动电压的分析及探讨 随着制备技术的进步 xff0c 在需求的不断拉动下 xff0c 碳化硅 xff08 SiC xff09 器件与模块的成本逐年降低 相关产品
  • EM-500储能网关的AI采集性能实测

    EM 500储能网关的AI采集性能实测 EM 500是致远电子面向工商储能应用推出的高性价比储能网关产品 为满足采集外部传感器数据需要 xff0c EM 500设计内置了多通道高性能AI采集接口 xff0c 本文将对其进行一次实测 EM 5
  • 【IoT开发】UART通信高频测试

    测试所使用芯片 STM32F103RCT6 UART收发的极限频率 xff1a bytes s 1 发送频率 主程序循环发送一字节u8整型 xff0c 记录次数 while 1 t 43 43 if t 61 61 255 t 61 0 p
  • 560V输入、无光隔离反激式转换器

    560V输入 无光隔离反激式转换器 在传统的隔离式高压反激式转换器中 xff0c 使用光耦合器将稳压信息从副边基准电压源电路传输到初级侧 xff0c 从而实现严格的稳压 问题在于 xff0c 光耦合器大大增加了隔离设计的复杂性 xff1a
  • 用于DC-DC转换器的MIL-SPEC COTS EMC输入滤波器

    用于DC DC转换器的MIL SPEC COTS EMC输入滤波器 DC DC转换器的开关动作可能会引起不良的共模和差模噪声 xff0c 在频谱的许多点上创建不可接受的干扰 前端 xff08 或电力线 xff09 滤波器旨在在DC DC转换
  • C语言中调用nop();解决办法

    C语言中调用 nop 解决办法 可在头文件中添加 include lt intrins h gt 或是直接删去 nop intrins h一般用在keilC51单片机编程中 xff0c 一般程序中需要使用到空指令 nop 字符循环移位指令
  • rosrun teleop_twist_keyboard teleop_twist_keyboard.py

    rospack Error package teleop twist keyboard not found 解决方案 xff1a 1 cd catkin ws src xff08 如果没有这个目录先在工作目录下创建工作空间 xff1a mk
  • ubuntu20.04安装ros配置秘钥时出现gpg: keyserver receive failed: Connection timed out

    gpg keyserver receive failed Connection timed out也是从公钥服务器接收失败 xff1a 连接超时 解决方案1 换自己的手机热点 解决方案2 切换网络配置 xff1a 这大多数是网络的问题 xf
  • rosbag的命令使用以及代码编写

    概念 xff1a rosbag是用于录制和回放 ROS 主题的一个工具集 作用 实现了数据的复用 xff0c 方便调试 测试 本质 xff1a rosbag本质也是ros的节点 xff0c 当录制时 xff0c rosbag是一个订阅节点
  • 格式化串漏洞

    格式化字符串漏洞本身并不算缓冲区溢出漏洞 xff0c 这里作为比较典型的一类漏洞进行简单介绍 为了能够将字符串 变量 地址等数据按照指定格式输出 xff0c 通常使用包含格式化控制符的常量字符串作为格式化串 xff0c 然后指定用相应变量来
  • 单链表的遍历

    1 什么是遍历 遍历就是把单链表的各个节点挨个拿出来 xff0c 一个不能少 xff0c 也不能重复 xff0c 追求效率 2 如何遍历单链表 xff08 1 xff09 分析数据结构的本身特点 xff0c 然后根据根据它本身的特点制定相应
  • 单链表之删除节点

    1 删除节点的步骤 xff08 1 xff09 找到要删除的这个节点 xff1a 通过遍历来查找节点 xff0c 从头指针 43 头节点开始 xff0c 顺着链表依次将各个节点拿出来 xff0c 按照一定的方法比对 xff0c 找到我们要删
  • lssek函数的用法及作用

    1 lseek函数的介绍 xff08 1 xff09 文件指针 xff1a 当我们对一个文件读写时 xff0c 一定需要打开这个文件 xff0c 所以我们操作的都是动态文件 xff0c 动态文件在内存中的形态就是流的形式 xff08 2 x
  • ubuntu20.04安装arduino IDE(亲测可用)

    步骤一 xff1a 在官网下载arduino安装包选择相应的版本 下载链接 步骤二 xff1a 解压下载的安装包在相应的目录下执行下面语句 tar xvf 安装包名 步骤三 xff1a 将解压后的安装包移动到 opt目录下 sudo mv
  • px4无人机常识介绍(固件,px4等)

    专业名词解释 aircraft 任何可以飞或者可以携带物品还是搭载旅客的飞行器统称为飞机 航空器 uav 无人驾驶飞机 vehicle 飞行器 airplane plane aero plane 有机翼和一个或多个引擎的飞行器统称为飞机 D
  • 在运行ros的Python文件时报找不到路径

    1 第一行解释器声明 xff0c 可以使用绝对路径定位到 python3 的安装路径 usr bin python3 xff0c 但是不建议 2 建议使用 usr bin env python 但是会抛出异常 usr bin env pyt
  • ros文件架构

    WorkSpace span class token operator span span class token operator span 自定义的工作空间 span class token operator span span cla
  • 用C语言和汇编给寄存器赋值

    1 用汇编 要根据目标CPU的体系 xff0c 用对应的汇编类型编写 ldr r0 61 0X020C4068 CCGR0 ldr r1 61 0XFFFFFFFF str r1 r0 2 用C语言 要知道相关寄存器地址 官方会提供参考手册
  • 商人过河--广度优先搜索--matlab实现

    进行了代码优化 目录 应用背景 xff1a 模型求解 xff1a 模型建立 xff1a 模型实现 xff1a 源代码 xff1a 运行结果 xff1a 附 xff1a 应用背景 xff1a M个商人与N个仆从过河 xff0c 小船一次可载k
  • C++---全局对象、局部对象、静态对象

    1 全局对象 xff0c 程序一开始 xff0c 其构造函数就先被执行 xff08 比程序进入点更早 xff09 xff1b 程序即将结束前其析构函数将被执行 2 局部对象 xff0c 当对象生成时 xff0c 其构造函数被执行 xff1b

随机推荐

  • 2011年B题交通巡警第一问的练习与实现

    题目要求 xff1a 试就某市设置交巡警服务平台的相关情况 xff0c 建立数学模型分析研究下面的问题 xff1a xff08 1 xff09 附件1中的附图1给出了该市中心城区A的交通网络和现有的20个交巡警服务平台的设置情况示意图 xf
  • 利用最大流最小割算法matlab割图

    目录 练习思路 matlab绘图 噪音 坐标编码 邻接矩阵 最大流最小割算法 对最大流最小割算法求解结果转换为图像 源代码 运行实例 TIPS 最近学习了最大流和最小割算法 xff0c 可以把图看成是一些点的集合 xff0c 色彩差值的倒数
  • 关于将一个数分解成四个数平方和的算法matlab

    目录 理论基础 拉格朗日四平方数和定理 高斯恒等式 操作步骤 分解质因数 求解四平方数 应用高斯恒等式 小结 高斯恒等式输出代码 输出结果 运行结果 怎么把一个大数分解成四个小数的平方和呢 xff1f 理论基础 拉格朗日四平方数和定理 每个
  • 寻找较大素数,简易实现RSA密码系统matlab

    目录 RSA密码系统 随机寻找两个较大的素数 欧拉筛的算法函数 寻找随机素数的代码 生成公钥和私钥 加密解密方式 实现代码 运行结果 小结 首先来了解一下什么是RSA算法 RSA密码系统 RSA是被研究得最广泛的公钥算法 xff0c 从提出
  • 关于返回一个矩阵中为0元素个数及位置的matlab自定义函数实现以及用到的matlab基本操作

    目录 练习例题 题目要求 代码呈现 运行结果 基础操作 返回矩阵的行数列数 生成矩阵函数 取整取余函数 自定义函数参数缺省下的默认值以及输入参数为空集下替换为默认值的情况 find函数大观 对于find函数的改善调用 练习例题 题目要求 编
  • 蓝桥杯——单片机学习(3——点亮LED灯)

    注 xff1a 此单片机型号为 STC15F2K60S2 原理 如图 xff0c 发光二极管L1 L8 共阳接法 xff0c VCC为电源正极 xff0c 高电平 已知发光二极管正向导通反向截至 xff0c 要使得二极管发光 xff0c 就
  • 蓝桥杯——单片机学习(5(1)——按键(独立按键))

    注 xff1a 此单片机型号为 STC15F2K60S2 目录标题 独立按键原理按键原理消抖 代码入门代码进阶代码消抖改进 xff08 按一下只执行一次 xff0c 长按也一样 xff09 补充 独立按键 原理 这是一个矩阵按键的电路图 x
  • 最全的蓝桥杯嵌入式备赛集合~

    机缘巧合 xff0c 报了嵌入式的比赛 xff08 我能说是老师逼我的吗 orz xff09 xff0c 由于从来没接触过 xff0c 所以还是先从查找资料开始 下面就是我查找的资料集合 博客 建议篇 64 summerrrrrrc 蓝桥杯
  • 关于STM32编译报错:Error: L6218E: Undefined symbol SystemInit (referred from startup_stm32f10x_md.o).

    今天新建工程发现出现一个错误 Output CG axf Error L6218E Undefined symbol SystemInit referred from startup stm32f10x md o 但我觉得我的操作没有任何问
  • 蓝桥杯嵌入式比赛知识点合集(现在什么都有好吧)

    目录 新建工程LCDsprintf格式输出百分号 输出格式 xff1a Rmemset函数LCD DisplayStringLine函数嘀嗒定时器高亮行高亮一两个字符高亮单个字节高亮使用 多个字节高亮使用 行闪烁使用 LEDdisplay函
  • google 和 firefox 添加用户自定义脚本

    如何在页面中嵌入自己写的Javascript脚本呢 xff1f 下面分别介绍一下在Chrome和Firefox两种浏览器上的操作步骤 xff1a Chrome xff1a 1 打开chrome扩展程序页 chrome extensions
  • JAVA开源解析HTML工具

    好东西收藏一下 原地址 xff1a http www open open com 30 htm NekoHTML NekoHTML是一个简单地HTML扫描器和标签补偿器 tag balancer 使得程序能解析HTML文档并用标准的XML接
  • 虚拟机中ubuntu系统联网问题——以桥接模式解决

    前因后果就不说了 xff0c 这里只记录方法 xff0c 希望未来再遇到这种问题可以及时解决 文章目录 我电脑的配置与环境解决方案 桥接模式打开已经连接的WiFi的属性 xff0c 记录IPv4的相关值打开虚拟网络编辑器 xff0c 设置桥
  • 无人机导航定位技术-复习

    文章目录 无线电导航 要求 精度 陆基导航 定义 塔康导航 TACAN 范围 天线 结构设计 信标方向 伏尔导航 VOR 定义 工作原理 建设要求 拓展 测距器 DME
  • 记录——golang版本更新代码

    环境 Ubuntu20 04 解决方法 方法一 xff1a 将旧版本的go卸载 xff0c 重新安装最新版本的go xff08 我使用且成功的 xff09 sudo apt get remove golang 1 span class to
  • ArcGIS10.6“License许可启动无响应”解决方法

    以下是我尝试过的方法 关闭防火墙 xff08 很必要 xff09 替换 Service txt 及 34 ARCGIS exe 34 文件 xff08 感觉没什么用 xff09 修改服务设置 xff08 很必要 xff09 更改注册表 xf
  • 学好网络编程注意的点

    注 xff1a 总结不完善后续继续总结 对于TCP连接 xff1a 1 服务器端1 xff09 创建套接字create xff1b 2 xff09 绑定端口号bind xff1b 3 xff09 监听连接listen xff1b 4 xff
  • C++中的.和:以及::还有->的区别

    1 A B则A为对象或者结构体 xff1b 2 A gt B则A为指针 xff0c gt 是成员提取 xff0c A gt B是提取A中的成员B xff0c A只能是指向类 结构 联合的指针 xff1b 3 是作用域运算符 xff0c A
  • C++静态库与动态库以及Windows上的创建以及使用

    一 什么是库 库是写好的现有的 xff0c 成熟的 xff0c 可以复用的代码 现实中每个程序都要依赖很多基础的底层库 xff0c 不可能每个人的代码都从零开始 xff0c 因此库的存在意义非同寻常 本质上来说库是一种可执行代码的二进制形式
  • C/C++ 函数的定义 声明 调用的区别

    C语言基础 xff1a 函数 xff08 定义函数 声明函数 调用函数 xff08 传值调用 引用调用 xff09 函数的参数 xff08 形参 实参 xff09 xff09 1 函数 函数是一组一起执行一个任务的语句 每个 C 程序都至少