1 进制转化
1.1 二进制**0B**1.2 十六进制**0X**1.3 二进制和十六进制转换(8421码) 2 指针
2.1 * 和&2.2 内存中分配2.3 指针变量和指向关系2.4 常指针及常量指针const关键字2.5 typedef关键字——函数指针的简化 3 结构体
3.1 c语言的集合数据类型3.2结构体用法
3.2.1 x作为变量3.2.2 x作为数据类型 4 位运算
4.1 六种位运算
4.1.1 按位与(&)4.1.2 按位或(|)4.1.3 按位异或(^)4.1.4 按位取反(~)4.1.5 左移运算(<<)4.1.6 右移运算(>>) 4.2 交换律和结合律4.3 例题 5 单片机的地址和状态
5.1 STM32F103X8-B数据手册5.2 STM32F10XXX
1 进制转化 1.1 二进制0B
逢二进一
1.2 十六进制0X逢十六进一
1.3 二进制和十六进制转换(8421码)1位十六进制数 = 4位二进制数,通过8421码计算
二进制数不够4的倍数时补0
比如101 1100,写成0101 1100
2 指针
指针就是变量,是用来存放地址的变量,存放在指针中的值都被当做地址来处理
地址是唯一标识一块地址空间的
int a = 0; // 定义一个int类型变量a int* point_a; // 定义一个指向 int类型变量 的指针 point_a = &a; //把 变量a 的内存地址 赋值给 point_a //以下为比喻------------- Car aodi = ....; // 有一辆奥迪车,它的颜色是...长...宽......... Car* carNum; // 生产一个车牌 carNum = &aodi; // 把这个车牌挂到车上2.2 内存中分配
指针的值其实是一个内存地址值,而不是具体值。具体的值保存在变量 a 中。
printf("%d", &a); // a 变量的地址, 0x8004 printf("%d", point_a); // 变量 point_a 的值 0x8004 printf("%d", a); // 变量 a 的值 0 printf("%d", *point_a); // 变量 point_a 值被按照int解析后的值 02.3 指针变量和指向关系
用来保存 指针 的变量,就是指针变量。如果指针变量p1保存了变量 num的地址,则就说:p1指向了变量num,也可以说p1指向了num所在的内存块 ,这种指向关系,在图中一般用 箭头表示。
上图中,指针变量p1指向了num所在的内存块 ,即从地址0028FF40开始的4个byte 的内存块。
有时候我们希望定义这样一种变量,它的值不能被改变,在整个作用域中都保持固定。
例如,用一个变量来表示班级的最大人数,或者表示缓冲区的大小。
为了满足这一要求,可以使用const关键字对变量加以限定。
将 const 变量称为常量(Constant)。
常量一旦被创建后其值就不能再改变,所以常量必须在定义的同时赋值(初始化),后面的任何赋值行为都将引发错误。
#include2.5 typedef关键字——函数指针的简化const int a = 20; int b = 30; int y; int *p; const int *p1; int const *p2; int * const p3 = &b; int const * const p4 = &a; // 指向常量的常指针。指针指向的值不能被修改(*),指针变量(指向的内存)也不能被修改(p4) int main(){ p1 = &a; // p = &a; // 报错。原因:普通指针:不能指向常量。 printf("p1: %dn", p1); // 4210688 y = *p1; // 通过指针p1取出a的值赋值给y printf("y: %dn", y); // 20 p1 = &b; // p1指向了b printf("p1: %dn", p1); // 4206608 y = *p1; // 通过指针p1取出b的值赋值给y printf("y: %dn", y); // 30 // *p1 = 50; //报错。原因:常量指针:不能用这个指针修改指针指向的内存的值。 printf("p3: %dn", p3); printf("b初始值: %dn", b); // 30 *p3 = 50; //p3原本指向b,b初始为30。p3为常指针,常指针可以通过指针修改指向的变量的值,也就是修改b的值 printf("常指针修改了b的值,b: %dn", b); // 50 printf("p3: %dn", p3); return 0; }
#include3 结构体 3.1 c语言的集合数据类型 3.2结构体用法 3.2.1 x作为变量 3.2.2 x作为数据类型 4 位运算// typedef char INT8; // INT8 a,b,c; //相当于char a,b,c // typedef struct{ // // }PERSON_S; // PERSON_S p1, p2; //1、直接使用函数指针的定义式来定义函数指针变量 typedef int (*PFUN) (int x); PFUN p1,p2 = cube; //2、定义函数指针数组 PFUN a[2] = {square, cube}; // 等价于:int (* a[2]) (int x) = {square, cube}; // 3、函数的形参含有函数指针(回调函数) int f1(PFUN p, int x){ // 等价于:int f1(int (*PFUN) (int x), int x) return (*p)(x); } // 4、函数的返回值是函数指针 PFUN f2(int x){ // 等价于:int (*f2(int x)) (int x) return a[x]; } // 5、函数的返回值和函数的形参都含有函数指针。 PFUN f3(PFUN p){ // 等价于:int (*f3 (int (*PFUN)(int x))) (int x) return p; } int y; int main(){ int square(int x); int cube(int x); // PFUN = square; // y = (*PFUN)(2); // printf("y=2*2=%dn", y); // PFUN = cube; // y = (*PFUN)(2); // printf("y=2*2*2=%dn", y); y = (*a[0])(2); //4 y = f1(square, 3); //9 p1 = f2(1); y = (*p1)(2); //8 } int square(int x){ return x*x; } int cube(int x){ return x*x*x; }
位运算是将数字以二进制形式进行计算的运算符。
与其他运算符不同,C语言中位运算,顾名思义,是以数值的二进制位为单位进行 *** 作的,包含<<(左移)、>>(右移)、~(按位取反)、&(按位与)、|(按位或)、^(按位异或) 共六种运算符。
C语言的六种位运算:
有0为0,全是1为1。
按位与运算符的作用:
清零
我们可以对某一个数与0进行按位与运算,由于两个位都为1才为1,因此最终全部位都变为0,起到清零的作用
取指定位
如某些存储场景下,“第13位表示xxxx“”,我们需要取出13位,则可以让原数值与数字7进行按位与运算,得到的结果即是原数值的1~3位的值。
判断奇偶
可以发现,数字的奇偶取决于二进制位的最低一位是1还是0,因此只需要与1按位与运算,判断是1是0即可得知奇偶。
有1为1
按位或运算符的作用:
对一个数字的指定位,置为1。
如“某个数字的第七位”表示开关,原先是0,需要改为1的状态,即可以将这个数字与64按位或,即可得到第七位变为1,其余位的值依旧不变。
4.1.3 按位异或(^)相同为0,不同为1
异或运算符的作用
指定位数的翻转
如想对某个数字的低4位进行翻转,则可以将这个数字与15(二进制为00001111)进行按位异或运算,既可以将原数字的低四位进行翻转,即高四位不变,低四位0变1,1变0
与0异或还是原值
大家可以自行实验,一个数字与0进行异或,结果还是原值
交换两个数字
除了之前我们学习交换两个数字需要第三个变量做中介之外,如今可以通过异或运算进行,代码如下:
#include4.1.4 按位取反(~)int swap(int *a,int *b) { if (*a!=*b) { *a=*a^*b; *b=*b^*a; *a=*a^*b; } return 0; } int main() { int a=5; int b=5; swap(&a,&b); printf("a=%d b=%dn",a,b); //a为3,b为5 return 0; }
01互换
对应十进制,左移几位,乘几次2。
左移N位的本质是乘以2的N次方。
对应十进制,右移几位,除以几次2。
右移N位的本质是除以2的N次方。
& | ^满足交换律和结合律
输入5个数,两对相同,找出那个不同的数?
采用位异或(^)运算和他的结合律。
a ^ a = 0; a ^ 0 = a;
#include5 单片机的地址和状态int main(){ int n[5]; printf("输入5个数字:n"); for(int i=0; i<5; i++){ scanf("%d", &n[i]); } int ans = 0; for(int j=0; j<5; j++){ ans = ans ^ n[j]; } printf("落单的数字为:%d", ans); }
软件 = 地址 + 状态 → 硬件
5.1 STM32F103X8-B数据手册储存器图
所有地址的起始地址:0x0000 0000
所有地址容量的最大值:0xFFFF FFFF
29页
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)