变量 | 解释 |
---|---|
全局变量 | 出现在代码块{}之外的变量就是全局变量 |
局部变量 | 一般情况下,代码块{}内部定义的变量就是自动变量,也可使用auto显示定义。 |
静态变量 | 是指内存位置在程序执行期间一直不改变的变量,用关键字static修饰。代码块内部的静态变量只能被这个代码块内部访问,代码块外部的静态变量只能被定义这个变量的文件访问。 |
$ size main
text data bss dec hex filename
1275 552 8 1835 72b main
.text 代码段,用来存放代码,一般是只读的区域;
.data数据段,用来存放全局初始化变量,常量,以及全局或局部静态变量,只初始化一次;
.bss BSS段,用来存放全局未初化数据,用0初始化;
我看了几篇文章,有的是5种,有的是4种,把 【data】和 【bss】 同意称为静态区,它们的区别是否初始化
内存区域 | 存放 | 作用 |
---|---|---|
text 段 | 字符串常量和函数体的二进制代码 | 通常可共享,只读 |
data段 | 已初始化全局变量、静态变量 | 通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。 |
bss段 | 未初始化全局变量、静态变量 | 通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS段属于静态内存分配。(注意:即使是赋值为0也是未初始化!) |
Stack | malloc内存分配 | 用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。 |
Heap | 局部变量、在函数调用时的形参和返回值 | 为最近被调用的函数分配自动变量和临时变量的存储空间 |
//main.cpp
int a = 0; //a在全局已初始化数据区.data
char *p1; //p1在.bss(未初始化全局变量)
main()
{
int b; //b在栈区 .stack
char s[] = "abc"; //s为数组变量,存储在栈区,.heap
//"abc"为字符串常量,存储在已初始化数据区
char *p1,p2; //p1,p2在栈区
char *p3 = "123456"; //123456\0在已初始化数据区,p3在栈区
static int c =0; //C为全局(静态)数据,存在于已初始化数据区
//另外,静态数据会自动初始化
p1 = (char *)malloc(10);//分配得来的10个字节的区域在堆区
p2 = (char *)malloc(20);//分配得来的20个字节的区域在堆区
//注意p1,p2是局部变量,所以存储在栈中,10Byte空间在堆中;
free(p1);
free(p2);
}
使用 uxTaskGetStackHighWaterMark() API 函数来查看实际使用了多少栈,如果分配的栈比需要的多,则可以减少栈大小,并且可以使用栈溢出检测特性来确定栈是否太小。
printf(" the min free stack size is %d \r\n",(int32_t)uxTaskGetStackHighWaterMark(NULL));
int a; //一个整形数
int *a //一个指向整型数的指针
int **a //一个指向指针的指针,它指向的指针是指向一个整型数
int a[10] //一个有10个整型数的数组
int *a[10] //一个有10个指针的数组,该指针是指向一个整型数的
int (*a)[10] //一个指向有10个整型数数组的指针
//一个指向函数的指针,该函数有一个整形参数并返回一个整形数
int * fun(int a);
//一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整形数
int (*fun[10])(int a)
const char *p | 通常修饰常用的字符串,字符串内容不变 |
---|---|
char * const P | 通常修饰硬件资源,地址不变 |
const char *const p | 通常修饰地址不可变且内容不可变的ROM |
#include <stdio.h>
int main()
{
char *p = "Hello World !";
printf("the one is %p\n",*p); // p为指针,那么*p就为p的地址
*p = 'a'; // 无法修改常量(程序编译通过,运行段错误)
printf("the %x\n",p);
}
#include <stdio.h>
int main()
{
char buff[] = {"Hello World !"};
char *p1 = buff;
*p1 = 'a';
printf("the %s\n",p1); // 输出aello World !
}
#include <stdio.h>
int main()
{
const char *p = "Hello World !";
char buff[] = {"Hello World !"};
char *p1 = buff;
printf("the one is %x\n",*p1);
*p = 'a';
printf("the %s\n",p1);
}
int *p = xxx 【0x12】
p+1 【0x12+1*sizeof(*p))】
p++ 地址更新;
p[n] 取地址的值
p+n 地址加
#include <stdio.h>
int main()
{
int a = 0x123456789; // 大小越界
int b = 0x99991199;
int *p1 = &b;
char *p2 = (char *)&b;
printf("the p1+1 is %x,%x,%x\n",*(p1+1),p1[100],*p1+1);
// 输出 a 越界访问值 b+1
printf("the p2+1 is %x\n",p2[1]);
// 11
}
typedef struct
{
uint8_t Cur_Index; // 当前索引项
uint8_t previous; // 上一页
uint8_t next; // 下一页
uint8_t enter; // 确认
uint8_t back; // 返回
void (*current_operation)(uint8_t, uint8_t); // 当前索引执行的函数(界面)
} Main_Menu;
// 各界面的索引值
enum
{
Main_Page = 0,
Menu_Rate = 1,
Menu_Pig = 2,
Menu_Sys = 3,
Menu_Net = 4,
Menu_Inact = 5,
};
static void (*current_operation_func)(uint8_t, uint8_t); // 定义一个函数指针
// 菜单索引表
const volatile static Main_Menu table[24] =
{
{Main_Page, Main_Page, Main_Page, Main_Page, Menu_Rate, main_page}, // 主界面
{Menu_Rate, Menu_Rate, Menu_Pig, _Local_rate, Main_Page, menu_rate_page}, // 本地比例
{Menu_Pig, Menu_Rate, Menu_Sys, _Pig_Info_lin1, Main_Page, menu_pig_info_page}, // 猪只信息
{Menu_Sys, Menu_Pig, Menu_Net, _Device_Info, Main_Page, menu_sys_info_page}, // 系统信息
{Menu_Net, Menu_Sys, Menu_Inact, _Net_Info, Main_Page, menu_net_info_page} // 网络信息
};
/*
函数功能:刷新界面
参数:无
返回值:无
*/
void menu_ui_refresh(uint8_t key_val)
{
if (key_val != 0) // 只有按键按下才刷屏
{
last_index = func_index; // 更新上一界面索引值
switch (key_val)
{
case KEY_UP:
func_index = table[func_index].previous; // 更新索引值
break;
case KEY_DOWN:
func_index = table[func_index].next; // 更新索引值
break;
case KEY_INTER:
func_index = table[func_index].enter; // 更新索引值
break;
case KEY_BACK_MENU:
func_index = table[func_index].back; // 更新索引值
break;
default:
break;
}
}
current_operation_func = table[func_index].current_operation;
(*current_operation_func)(last_index, key_val); // 执行当前索引对应的函数
}
char **a[10] //一个有10个指针的数组,该指针是指向一个字符串的
比如几个字符串分布在内存各个区域,可以用指针数组把各个字符串地址用指针数组存起来,那么这些字符串就又联系了
$ ./build 1 2 3 4
#include <stdio.h>
int main(int argc,char **argv)
{
int i = 0;
while(argv[i] != NULL){
printf("the argv[%x] is %s\n",i,argv[i]);
i++;
}
return 0;
}
定义 | 用处 |
---|---|
char buf[10] | 字符串,结束以/0结束 |
unsigned char buf[10] | 传感器数据 |
c
#include <stdio.h>
void print(int *p, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d\n", *(p + i));
}
}
int main()
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int *p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
// 一级指针p,传给函数
print(p, sz);
return 0;
}