# 基础
## 关键字
~~~
typeof
int a = 5;
typeof(int *) var = &a;
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 数据类型变量
~~~
char 1
unsigned char 1
signed char 1
int 4
unsigned int 4
short 2
unsigned short 2
long 4/8
unsigned long 4/8
long long 8
float 4
double 8
long double 16
double a = 10;
void fuction(void);
void *ptr = malloc(12);
85 /* 十进制 */
0213 /* 八进制 */
0x4b /* 十六进制 */
30 /* 整数 */
30u /* 无符号整数 */
30l /* 长整数 */
30ul /* 无符号长整数 */
//定义常量
#defined a 100
const int a = 100;
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 存储类
~~~
auto
register
static
extern
volatile
变量自动auto 函数自动auto
auto int a; == int a;
register int a; //每次取值从内存去 编译器不要优化
static int a; //静态变量 生命周期全局
static void fun(); //限制函数名称作用域再本文件别的文件不能引用 避免命名空间污染
extern int a; //变量a引用
extern void fun(); //引用别的文件的函数
volatile 防止编译器优化掉操作变量的语句
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 数组
~~~
//一维数组
int array[4] = {1, 2, 3, 4}
int array[] = {1, 2, 3, 4};
int a = array[0]
//二维数组
int array[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
int val = array[2][3];
int people[30] = {[0 ... 29] = 1};
//数组传参
1.
void fun(int *array)
{
}
2.
void fun(int array[4])
{
}
3.
void fun(int array[])
{
}
常用1和3
//传递二维数组
int array[4][3] = {0};
void fun(int array[][3])
void fun(int (* p)[3]); //数组指针 指向数组
fun(array);
数组相同于指针
一维数组
int array[5];
*(array + 1) == *(&array[0] + sizeof(array)) //*(&array[0] + 5)
二维数组
int array[4][5];
*(array + 1) == *(&array[0] + sizeof(array)) //*(&array[0] + 20)
三维
int array[3][4][5];
*(array + 1) == *(&array[0] + sizeof(array)) //*(&array[0] + 60)
//指针+1内存增加指针指向数据类型长度
//函数返回数组
int * fun()
{
static int array[10];
return array;
}
//指向数组指针
int array[4] = {1, 2, 3, 4}
int *ptr = array;
int array[4][4]
int *ptr = array;
int (*p)[4] = array;
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 枚举
~~~
enum DAY {
MON = 1,
TUE
};
enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 指针
~~~
int *p; //一级指针
int **p; //二级指针
int (*p)[4]; //数组指针 就是 指针指向数组 数组存储大小是4个单元
int *p[4]; //指针数组 4个指向int的指针 int a = 10; p[0] = &a;
int (*p)(int, int); //函数指针 指向函数
int fun(int a, int b);
p = fun;
p(1, 2);//执行
typedef int (*fun_ptr)(int, int);
fun_ptr p = fun; //别名定义
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 字符串
~~~
数组最后一个字节存储 '\0'
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str[] = "hello" //自动添加 '\0'
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 结构体
~~~
//定义
1.
struct Books {
char title[10];
char author[10];
} book;
2.
struct Books book;
3.
typedef struct {
char title[10];
char author[10];
} Books;
Books book;
//初始化
Books book = {"c", "my"};
Books book = {.title = "c", .author = "my"}; //C风格
Books book = {title : "c", author : "my"}; //C++风格
结构体大小
1,每个结构体成员的起始地址为该成员大小的整数倍,即int型成员的其实地址只能为0、4、8等
2,结构体的大小为其中最大成员大小的整数倍
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 共用体
~~~
共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式
union Data
{
int i;
float f;
char str[20];
};
int main( )
{
union Data data;
printf( "Memory size occupied by data : %d\n", sizeof(data));
return 0;
}
//20
//大小为最大成员大小
big-endian和little-endian格式。在小端模式中,低位字节放在低地址,高位字节放在高地址;在大端模式中,低位字节放在高地址,高位字节放在低地址。
//大小端测试
#include<stdio.h>
union var{
char c;
int i;
};
int main(){
union var data;
data.c = 0x04;
printf("%x\n",data.i);
if(data.i == 0x04) {
printf("小端");
} else {
printf("大端");
}
}
REVERSED
#if defined(REVERSED)
std::cout<< ("大端");
#else
std::cout<<("小端");
#endif
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 变参数函数
~~~
double average(int num,...)
{
va_list valist;
double sum = 0.0;
int i;
/* 为 num 个参数初始化 valist */
va_start(valist, num);
/* 访问所有赋给 valist 的参数 */
for (i = 0; i < num; i++)
{
sum += va_arg(valist, int);
}
/* 清理为 valist 保留的内存 */
va_end(valist);
return sum/num;
}
int main()
{
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 预处理器
~~~
字符串常量化运算符(#)和标记粘贴运算符(##)
#define Conn(x, y) x##y //连接字符
#define ToString(x) #x //转化为字符串
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
int main(void)
{
message_for(Carole, Debra);
return 0;
}
参数宏 #define square(x) ((x) * (x))
#define eprintf(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#ifdef DEF == #if define(DEF)
#else
#endif
#ifndef DEF
#endif
指令 描述
#define 定义宏
#include 包含一个源代码文件
#undef 取消已定义的宏
#ifdef 如果宏已经定义,则返回真
#ifndef 如果宏没有定义,则返回真
#if 如果给定条件为真,则编译下面代码
#else #if 的替代方案
#elif 如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个 #if……#else 条件编译块
#error 当遇到标准错误时,输出错误消息
#pragma 使用标准化方法,向编译器发布特殊的命令到编译器中
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 内存管理
~~~
void *calloc(int num, int size); //分配并初始化为 size
void free(void * address); //释放内存
void *malloc(int num) //分配内存
void *realloc(void *address, int newsize); //扩展大小
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 位域
~~~
struct bs
{
unsigned a:4;
unsigned :0;
unsigned b:4;
unsigned c:4;
}
0填充对其
整个结构体的总大小为最宽基本类型成员大小的整数倍
位域变量类型:int unsigned int signed int
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 字节对齐方式
~~~
#pragma pack(1)//单字节对齐
typedef struct{
uint32 ID;
uint32 Num;
uint32 Type;
uint32 lat;
uint32 lng;
uint32 alt;
uint32 speed;
}Waypoint;//Payload_Data
#pragma pack(pop)
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 大小端
~~~
//方法1
int a = 1;
if(*(char *)(&a) == 1) {
//小端
} else {
//大端
}
//方法2
union Endian
{
int a;
char b;
}
Endian endian;
endian.a = 1;
if(endian.b == 1) {
//小端
} else {
//大段
}
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## extern C
~~~
#ifdef __cplusplus //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的
extern "C"{
#endif
/*…*/
#ifdef __cplusplus
}
#endif
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)