【C/C++】C语言的高级编程(内存分区,指针)

C语言的高级编程【内存,指针】

  • 基本知识
        • 变量
        • gcc size工具
  • 内存分区
  • 指针相关
        • 定义和赋值
        • 指针加法
        • 函数指针
        • 多级指针
        • 数组
        • 指针传参

基本知识

变量
变量解释
全局变量出现在代码块{}之外的变量就是全局变量
局部变量一般情况下,代码块{}内部定义的变量就是自动变量,也可使用auto显示定义。
静态变量是指内存位置在程序执行期间一直不改变的变量,用关键字static修饰。代码块内部的静态变量只能被这个代码块内部访问,代码块外部的静态变量只能被定义这个变量的文件访问。
  • C语言中函数默认都是全局的,可以使用static关键字将函数声明为静态函数(只能被定义这个函数的文件访问的函数)
gcc size工具
$ size maintext       data        bss        dec        hex    filename1275        552          8       1835        72b    main

.text 代码段,用来存放代码,一般是只读的区域;
.data数据段,用来存放全局初始化变量,常量,以及全局或局部静态变量,只初始化一次;
.bss BSS段,用来存放全局未初化数据,用0初始化;

内存分区

我看了几篇文章,有的是5种,有的是4种,把 【data】和 【bss】 同意称为静态区,它们的区别是否初始化

内存区域存放作用
text 段字符串常量和函数体的二进制代码通常可共享,只读
data段已初始化全局变量、静态变量通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
bss段未初始化全局变量、静态变量通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS段属于静态内存分配。(注意:即使是赋值为0也是未初始化!)
Stackmalloc内存分配用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。
Heap局部变量、在函数调用时的形参和返回值为最近被调用的函数分配自动变量和临时变量的存储空间
//main.cpp 
int a = 0;     //a在全局已初始化数据区.data
char *p1;        //p1在.bss(未初始化全局变量)
main() 
{int b;            //b在栈区 .stackchar 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);
} 
  • FreeRTOS

使用 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
  • 指针指向的内容被非法访问,字符串常量不能配访问(text 段)。
#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 !
}
  • const 修饰的指针变量不能改变
#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);
}
指针加法
  • 指针的加法运算,实际上加的是一个地址单位,单位大小可以 sizeof(p[0])
int *p = xxx 【0x12】p+10x12+1*sizeof(*p))

p++ 地址更新;
p[n] 取地址的值
p+n 地址加

  • 下面程序ab两个值的地址是挨着的,且b的地址为低地址
#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+1printf("the p2+1 is %x\n",p2[1]);// 11 
}
函数指针
  • oled 菜单实例
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个指针的数组,该指针是指向一个字符串的

比如几个字符串分布在内存各个区域,可以用指针数组把各个字符串地址用指针数组存起来,那么这些字符串就又联系了

  • main 传参
$ ./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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

车载音频EMI的产生及典型音频功放AW836XX的解决方案

之前针对 eCall的文章中有提到D类音频功放需要关注EMI问题&#xff08;点击文章回看《车载eCall系统音频应用解决方案》&#xff09;&#xff0c;在此展开此问题并寻求解决方案。 1. EMI定义与分类 电磁干扰&#xff08;Electromagnetic Interference&#xff0c;EMI&#xff…

基于STM32的HX711示值放大器接口与驱动程序设计

将HX711示值放大器接口与STM32微控制器进行连接和驱动需要一定的硬件连接和软件编程。在这篇文章中&#xff0c;我们将介绍如何设计基于STM32的HX711示值放大器接口与驱动程序&#xff0c;并提供相应的代码示例。 1. 硬件连接 首先&#xff0c;我们需要将HX711示值放大器与STM…

openlayers [二] 初始化map 以及map的一些参数

文章目录 map 参数效果图代码分析 map 参数 controls 地图的控件 pixelRatio 设备上物理像素与设备无关像素&#xff08;dip&#xff09;之间的比率。 interactions 地图的互动 keyboardEventTarget 监听键盘事件的元素。这决定了KeyboardPan和 KeyboardZoom互动的触发时间。例…

残差网络 ResNet

目录 1.1 ResNet 2.代码实现 1.1 ResNet 如上图函数的大小代表函数的复杂程度&#xff0c;星星代表最优解&#xff0c;可见加了更多层之后的预测比小模型的预测离真实最优解更远了&#xff0c; ResNet做的事情就是使得模型加深一定会使效果变好而不是变差。 2.代码实现 impo…

SpringMVC-05

Spring MVC拦截器是在请求到达处理器前或返回客户端前执行的组件&#xff0c;它可以用于拦截和处理请求&#xff0c;实现一些通用的功能。 Spring MVC拦截器可以实现的功能包括&#xff1a; 登录验证&#xff1a;拦截所有请求&#xff0c;检查用户是否已登录&#xff0c;未登录…

网页设计(九)JavaScript基础应用

一、网页中文字的字号选择性改变 单击前初始状态页面 单击“中”链接后页面 文字素材&#xff1a;   JavaScript是一种能让你的网页更加生动活泼的程式语言&#xff0c;也是目前网页中设计中最容易学又最方便的语言。你可以利用JavaScript轻易的做出亲切的欢迎讯息、漂亮的…

web前端第二次

第一题&#xff1a; <!DOCTYPE html> <html> <head><title>计算奇数和</title> </head> <body><label for"input">请输入一个正整数&#xff1a;</label><input type"number" id"input&qu…

影响CSGO搬砖饰品价格上涨和下跌的原因有哪些

到底哪些情况下CSGO饰品价格会涨&#xff0c;哪些情况会跌&#xff0c;下面是一个混迹steam平台多年的老油条&#xff0c;一点个人见解&#xff0c;不喜吻喷。 首先&#xff0c;CSGO饰品的交易是从市场进行的&#xff0c;市场终究是市场&#xff0c;是自由买卖的&#xff0c;必…

VMware Vsphere 日志:用户 dcui@127.0.01已以vMware-client/6.5.0 的身份登录

一、事件截图&#xff1a; 二、解决办法 原因&#xff1a; 三、解决办法 1.开启锁定模式 2.操作 1、从清单中选择您的 ESXi 主机&#xff0c;然后转至管理 > 设置 > 安全配置文件&#xff0c;然后单击锁定模式的编辑按钮 2、在打开的锁定模式窗口中&#xff0c;选中启…

【Python】P4 异常处理

Python 异常处理 Python 中对于异常的处理主要通过 try-except、finally 和 raise 语句实现。 try-except 语句&#xff1a; 尝试执行一段代码&#xff0c;如果该代码块引发了异常&#xff0c;那么将跳过 try 代码块中剩余的代码&#xff0c;转而执行相应的 except 子句。 …

云服务器 云服务器概述-产品简介-文档中心-腾讯云

腾讯云服务器入门教程包括云服务器CPU内存带宽配置选择&#xff0c;选择云服务器CVM或轻量应用服务器&#xff0c;云服务器创建后重置密码、远程连接、搭建程序环境等&#xff0c;腾讯云服务器网txyfwq.com分享从0到1腾讯云服务器入门教程&#xff1a; 腾讯云服务器入门教程 …

C++中的引用及指针变量

目录 1.1 C中的引用 1.2 C中的指针变量&#xff08;pointer&#xff09; 1.1 C中的引用 C中的引用&#xff08;reference&#xff09;是一种特殊的变量&#xff0c;它是某个已存在变量的另一个名字。引用变量与指针变量类似&#xff0c;但引用变量必须在声明时进行初始化&…

CSDN 年度总结|知识改变命运,学习成就未来

欢迎来到英杰社区&#xff1a; https://bbs.csdn.net/topics/617804998 欢迎来到阿Q社区&#xff1a; https://bbs.csdn.net/topics/617897397 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff…

Python操作PDF的全面指南

引言&#xff1a; 在现代数字化时代&#xff0c;PDF&#xff08;Portable Document Format&#xff09;已成为一种常见的文档格式。无论是在工作中还是在学习中&#xff0c;我们经常需要处理和操作PDF文件。幸运的是&#xff0c;Python提供了许多强大的库和工具&#xff0c;可以…

「许战海矩阵战略洞察」吉香居给调味品企业带来的战略启示

引言&#xff1a;吉香居通过实施份额化战略和打造形象产品&#xff0c;在调味品行业中取得了成功。但品牌结构需要调整&#xff0c;需要将子品牌整合到吉香居主品牌下&#xff0c;共同提升品牌势能。此外&#xff0c;企业需保持主品牌竞争战略&#xff0c;以实现长期稳定的高速…

transfomer中正余弦位置编码的源码实现

简介 Transformer模型抛弃了RNN、CNN作为序列学习的基本模型。循环神经网络本身就是一种顺序结构&#xff0c;天生就包含了词在序列中的位置信息。当抛弃循环神经网络结构&#xff0c;完全采用Attention取而代之&#xff0c;这些词序信息就会丢失&#xff0c;模型就没有办法知…

进阶Docker4:网桥模式、主机模式与自定义网络

目录 网络相关 子网掩码 网关 规则 docke网络配置 bridge模式 host模式 创建自定义网络(自定义IP) 网络相关 IP 子网掩码 网关 DNS 端口号 子网掩码 互联网是由许多小型网络构成的&#xff0c;每个网络上都有许多主机&#xff0c;这样便构成了一个有层次的结构。 IP 地…

python实现屏幕颜色获取

为了实时监听鼠标移动并输出鼠标当前位置的颜色值&#xff0c;你可以结合使用pyautogui和pynput库。pynput库可以用来监听鼠标事件&#xff0c;而pyautogui则可以用来获取鼠标当前位置的屏幕颜色。 首先&#xff0c;你需要安装这两个库&#xff08;如果尚未安装&#xff09;&a…

FreeBSD上安装mysql数据库

安装前提 1、使用pkg安装mysql有个前提FreeBSD版本12.2及以上。 2、内存最好是8GB及以上 安装 $ pkg search mysql …… mysql80-client-8.0.35 Multithreaded SQL database (client) mysql80-server-8.0.35 Multithreaded SQL database (server) mysql81…