为什么功率放大电路在模电中经常提到?
- 模拟信号:它是连续变化的电信号,它在时间上和幅度上都是连续的,能够代表信息的连续变化。
- 大多数物理量为模拟信号,如:温度、压力、流量…
非电物理量通过传感器变换成电信号。 - 模拟电路:对模拟信号进行处理的电路。最基本的处理是对
信号的放大
,有功能和性能各异的放大电路,其他模拟电路多以放大电路
为基础。 - 只有将模拟信号放大到足够大,才能够进行数字化处理;而只有将处理好的数字信号转换为模拟信号并进行功率放大,才能驱动某些负载。
上拉电阻和下拉电阻长什么样?有什么用?
上拉电阻:用于确保在没有外部输入信号或者信号浮动时,输入端口有一个确定的电压状态,通常是高电平(逻辑1或+Vcc)。可以防止不确定的状态引发错误的信号读取值,增加了电路的稳定性。
下图中:按键没有按下:端口读取为高电平。
当按键按下: 端口读取为低电平。
R2为上拉电阻。
R1是保护电路所用的,一方面是保护单片机GPIO,若GPIO不小心被配置成了输出,按下按键可能会损坏GPIO,而串接电阻R1后,即使出现这种情况,也不会损坏GPIO,另一方面可以按键消抖。
下拉电阻:确保在没有外部信号输入或信号浮动的情况下,输入端保持在一个确定的低电平(逻辑0或GND)状态。
按键没有按下:端口读取为低电平
当按键按下: 端口读取为高电平
图中,R2为下拉电阻 。
定义和声明
(A) int i;
(B) extern int i;
什么是定义?所谓的定义就是(编译器)创建一个对象,为这个对象分配一块 内存并给它取上一个名字,这个名字就是我们经常所说的变扯名或对象名。
什么是声明::告诉编译器,这个名字巳经匹配到一块内存上了。声明可以出现多次。告诉编译器,这个名字已被预定了,别的地方再也不能用它来 作为变量名或对象名。
上述举例中:(A) 是定义;(B) 是声明
定义和声明最重要的区别:定义创建了对象并为这个对象分配了内存,而声明没有分配内存。
static关键字(******非常重要)
static用来控制变量的存储方式和可见性
第 1 个作用:修饰变量
static 关键字修饰的变量,
1.在全局作用域下声明称为静态全局变量,
静态全局变量的作用域仅限于定义它的文件内部。这意味着,从变量定义处开始,直到文件结尾处,该变量都可以被访问和使用。
静态全局变量在其他文件中是不可见的,即使使用 extern 声明也不能在其他文件中直接使用。这是因为 extern 声明是告诉编译器该变量是在其他文件中定义的,而静态全局变量的作用域仅限于当前文件,因此在其他文件中无法访问它。
extern 是用来在另一个文件中声明一个全局变量或函数
静态局部变量:在函数体里面定义的,就只能在这个函数里用了,同一个文档中的其他函数也用不了。由于被 static修饰的变量总是存在内存的静态区, 所以即使这个函数运行结束,这个静态变量的值也不会被销毁,函数下次使用时仍然能用到这个值
1)用static修饰局部变量:使其变为静态存储方式(静态数据区),那么这个局部变量在函数执行完成之后不会被释放,而是继续保留在内存中。
2)用static修饰全局变量:使其只在本文件内部有效,而其他文件不可连接或引用该变量。
3)用static修饰函数:对函数的连接方式产生影响,使得函数只在本文件内部有效,对其他文件是不可见的(这一点在大工程中很重要很重要,避免很多麻烦,很常见)。这样的函数又叫作静态函数。使用静态函数的好处是,不用担心与其他文件的同名函数产生干扰,另外也是对函数本身的一种保护机制。
static 修饰全局变量和局部变量的应用:
#include <stdio.h> /* 函数声明 */ void func1(void);
static int count=10; /* 全局变量 - static 是默认的 */
int main(){while (count--) { func1(); }return 0;
}
void func1(void)
{ /* 'thingy' 是 'func1' 的局部变量 - 只初始化一次 * 每次调用函数 'func1' 'thingy' 值不会被重置。 */static int thingy=5; thingy++;printf(" thingy 为 %d , count 为 %d\n", thingy, count);
}
count 作为全局变量可以在函数内使用,thingy 使用 static 修饰后,不会在每次调用时重置。
static 修饰的静态局部变量只执行初始化一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。
thingy 为 6 , count 为 9thingy 为 7 , count 为 8thingy 为 8 , count 为 7thingy 为 9 , count 为 6thingy 为 10 , count 为 5thingy 为 11 , count 为 4thingy 为 12 , count 为 3thingy 为 13 , count 为 2thingy 为 14 , count 为 1thingy 为 15 , count 为 0
第2 个作用:修饰函数->静态函数
是指对函数的作用域仅局限于本文件(所以 又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,静态函数的只能在本文件中调用,不能被其他文件调用。不用担心自已定义的函数是否会与其他文件中的函数同名。
静态全局变量有以下特点:
(1)静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量;
(2)未经初始化的静态全局变量会被程序自动初始化为0(在函数体内声明的自动变量的值是随机的,除非它被显式初始化,而在函数体外被声明的自动变量也会被初始化为 0);
(3)静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的。优点:静态全局变量不能被其它文件所用;其它文件中可以定义相同名字的变量,不会发生冲突。
全局变量和全局静态变量的区别
- 全局变量默认是有外部链接性的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过 extern 全局变量名的声明,就可以使用全局变量。
- 全局静态变量是显式用 static 修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用 extern 声明也不能使用。
const关键字(******重要)
const意味着"只读"。
1)用const修饰常量:定义时就初始化,以后不能更改。
2)用const修饰形参:func(const int a){};该形参在函数里不能改变。
3)用const修饰类成员函数:该函数对成员变量只能进行只读操作,就是const类成员函数是不能修改成员变量的数值的。
被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前两个的作用是一样,a是一个常整型数。
第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。
第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。
最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
sizeof关键字
int i=0;
(A) sizeof(int); (B) sizeof(i); (C) sizeof int; (D) sizeof i
其中ABD的结果都为4 而C会编译报错,为什么?
因为sizeof是关键字 它不是一个函数,sizeof int表示什么啊? int前面加一个关键字? 类型扩展?明显不正确。
sizeof 在计算变量所占空间大小时,括号可以省略,而计算数据类型(int 、short、 long等)大小时不能省略。
sizeof<(i+ +)与 sizof(i) 的结果一样,所以没有必要且不允许写这样的代码。
sizeof(int) * p 表示什么意思?
sizeof(int)
表示 int
类型在当前系统中所占用的字节数,通常是 4 个字节(32位系统)或 8 个字节(64位系统)。而 p
则是一个指针变量(可能指向某种类型的数据),sizeof(int) * p
表示将指针 p
所指向的数据类型的大小,即 sizeof(int)
)乘以 p
的值。
这种操作可能是不明智的,因为乘以一个指针通常并不符合正常的编程逻辑,可能会导致不确定的结果或错误。
32位系统下:
int * p = NULL;
sizeof(p) 的值是多少? sizeof( * p) 呢?
假设 int
类型占 4 字节。
-
int * p = NULL;
p
是指向int
类型的指针,初始化为NULL
,表示空指针。sizeof(p)
的值是指针类型本身的大小,通常为 4 字节。
-
sizeof(*p)
*p
表示指针p
所指向的内容,但由于p
是空指针,解引用空指针是未定义行为,因此无法得出确切的大小
int a[100];
sizeof (a) 的值是多少? sizeof(a[100]) 呢? sizeof(&a)呢? sizeof(&a[0])呢?
-
int a[100];
a
是一个包含 100 个int
类型元素的数组。sizeof(a)
的值是整个数组占用的内存空间大小,即 100 * sizeof(int),为 400 字节。
-
sizeof(a[100])
a[100]
表示数组a
的第 101 个元素,由于数组索引从 0 开始,因此超出了数组的范围。- 访问超出数组范围的元素是未定义行为,所以无法准确计算
sizeof(a[100])
。
-
sizeof(&a)
&a
表示数组a
的地址,即指向整个数组的指针。sizeof(&a)
的值是指向数组的指针的大小,通常为 4 字节。
-
sizeof(&a[0])
&a[0]
表示数组a
的第一个元素a[0]
的地址。sizeof(&a[0])
的值是指向数组元素的指针的大小,通常为 4 字节。