《嵌入式C语言笔记(十七):进制转换、结构体与位运算精要》
1.进制转换算法
#include <string.h>
void reversArray(char *s)
{int len = strlen(s);int i;for(i = 0;i < len / 2;++i){char t = s[i];s[i] = s[len - i - 1];s[len - i - 1] = t;}
}void dtoh(unsigned int n, int num)
{char s[100];char *p;p = s;while(n > 0){int t = n % 16;if(t >= 10){*p = t + 55;}else{*p = t + '0';}n /= 16;++p;}*p = 0;reversArray(s);puts(s);
}int main(void)
{int n = 1234;dtoh(n,8);return 0;}
2.结构体深度解析
定义与初始化
struct Student {int id; // 整型成员char name[20]; // 字符数组float score; // 浮点成员 struct Date { // 嵌套结构体int year;} ;
};
// 初始化方式
struct Student s1 = {1, "Li", 95.5f, {2000}}; // 完全初始化
struct Student s2 = {.id=2, .score=88}; // 指定成员初始化
访问与操作
操作类型 | 语法 | 示例 |
---|---|---|
直接访问 | 结构体变量.成员 | s1.id = 1001; |
指针访问 | 指针->成员 | struct Student *p = &s1; p->score = 90; |
数组成员操作 | strcpy() | strcpy(s1.name, "Wang"); |
内存对齐规则
- 基准对齐:结构体按最大成员类型长度对齐(如含
double
则8字节对齐) - 成员偏移:地址需满足
offset % sizeof(member) == 0
- 总大小:结构体大小为对齐值的整数倍
struct Example { // 64位系统示例char c; // 1字节(偏移0)int i; // 4字节(偏移4,填充3字节)short s; // 2字节(偏移8)
}; // 总大小16字节(填充6字节)
3.共同体(union)特性
所有成员共享同一内存空间,大小为最大成员尺寸。典型应用包括:
union Converter {int number;char bytes[4]; // 检测大小端存储
};
conv.number = 0x12345678;
// 小端模式下conv.bytes[0] == 0x78
4.枚举与类型重定义
枚举(enum)
enum Week { SUN, MON, TUE, WED=10, THU }; // SUN=0, THU=11
enum Week day = TUE; // 整型常量
类型重定义(typedef)
typedef unsigned char uint8_t; // 基本类型简化
typedef struct Student Student; // 结构体简写
typedef void (*FuncPtr)(int); // 函数指针类型
FuncPtr callback; // 声明回调函数
5.位运算实战技巧
运算符 | 功能 | 示例 | 应用场景 |
---|---|---|---|
& | 位与 | reg &= ~(1<<3); | 清零寄存器第3位 |
| | 位或 | reg |= (1<<5); | 置位第5位 |
^ | 位异或 | reg ^= (1<<2); | 翻转第2位 |
<< | 左移 | data << 4 | 数值放大16倍 |
注意:浮点数不可直接位运算,寄存器操作需使用无符号整型。
6.代码实现
//共用体
#include<string.h>
struct Student
{int id;char name[20];float score;
};void printfStudent(struct Student *p)
{printf("%d,%s,%f\n", p->id, p->name, p->score);
}void printfStudents(struct Student *p, int len)
{int i;for(i = 0;i < len;++i){printfStudent(p + i);}
}void swap(struct Student *a, struct Student *b)
{struct Student t = *a;*a = *b;*b = t;
}void reverseStudent(struct Student *a, int len)
{int i;for(i = 0;i < len / 2;++i){swap(a + i, a + i + len - 1);}
}int scorecmp(struct Student *p1, struct Student *p2)
{if(p1->score > p2 ->score){return 1;}else if(p1->score == p2->score){return 0;}else{return -1;}
}int namecmp(struct Student *p1, struct Student *p2)
{return strcmp(p1 -> name, p2 -> name);
}void sortStudent(struct Student *a, int len,int (*pfn)(struct Student *, struct Student *))
{int i,j;for(i = 0;i < len - 1;++i){for(j = i + 1;j < len;++j){if(pfn(a + i, a +j) > 0){swap(a + i, a + j);}}}}void sortStudentByName(struct Student *a,int len)
{int i,j;for(i = 0;i < len - 1;++i){for(j = i + 1;j < len;++j){if(strcmp(a[i].name,a[j].name) > 0){swap(a + i, a + j);}}}
}void sortStudentByScore(struct Student *a,int len)
{int i,j;for(i = 0;i < len - 1;++i){for(j = i + 1;j < len;++j){if(a[i].score > a[j].score){swap(a + i,a + j);}}}
}int main(void)
{struct Student s[3] = {{1, "wang", 54},{2, "li", 564},{5, "uy", 97},};int len = sizeof(s) / sizeof(*s);//printfStudents(s + 2, 1);//reverseStudent(s, len);//printfStudents(s, len);//sortStudentByName(s, len);//sortStudentByScore(s, len);//sortStudent(s, len, scorecmp);//sortStudent(s, len, namecmp);printfStudents(s, len);return 0;
}
//共用体union Demo
{int i;char c;
};int main(void)
{union Demo i;i.i = 1;if(i.c == 1){printf("xiao\n");}return 0;
}