当前位置: 首页 > news >正文

【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;
}

相关文章:

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

C语言的高级编程【内存&#xff0c;指针】 基本知识变量gcc size工具 内存分区指针相关定义和赋值指针加法函数指针多级指针数组指针传参 基本知识 变量 变量解释全局变量出现在代码块{}之外的变量就是全局变量局部变量一般情况下&#xff0c;代码块{}内部定义的变量就是自动…...

Python ❀ 使用代码实现API接口调用详解

文章目录 1. 工具准备1.1. requests代码包1.2. BurpSuite抓包工具 2. 操作过程2.1. 一个简单的请求2.1.1. Burp获取响应2.1.2. 转发获取响应 2.2. 构造GET类型URL参数2.3. 构造请求头部2.4. 构造POST类型payload数据2.4.1. urlencoded格式2.4.2. json格式 本文主要讲解常用API接…...

关于KT6368A双模蓝牙芯片的BLE在ios的lightblue大数量数据测试

测试简介 关于KT6368A双模蓝牙芯片的BLE在ios的lightblue app大数量数据测试 测试环境&#xff1a;iphone7 。KT6368A双模程序96B6 App&#xff1a;lightblue ios端 可以打开log日志查看通讯流程 测试数据&#xff1a;长度是1224个字节&#xff0c;单次直接发给KT6368A&a…...

云边协同的 RTC 如何助力即构全球实时互动业务实践

作者&#xff1a;即构科技 由 51 CTO 主办的“WOT 全球技术创新大会 2023深圳站”于 11 月 24 日 - 25 日召开&#xff0c;即构科技后台技术总监肖潇以“边缘容器在全球音视频场景的探索与实践”为主题进行分享。 边缘计算作为中心云计算的补充&#xff0c;通过边缘容器架构和…...

使用python连接elasticsearch

有一个困惑了好久的问题&#xff0c;那就是从python里面连接elasticsearch总是报错。大致长这样 一开始我是看网上把es的安全功能关闭&#xff0c;也就是下面的内容&#xff0c;这个要进入到es的docker中去改config/elasticsearch.yml配置文件&#xff0c;但是这样改了以后kib…...

使用elasticsearchdump迁移elasticsearch数据实战

目录 1.安装nodejs 2.安装elasticsearchdump 3.迁移 4.核对数据 5.注意事项 1.安装nodejs https://ascendking.blog.csdn.net/article/details/135509838 2.安装elasticsearchdump npm install elasticdump -g 3.迁移 elasticdump --inputhttp://用户:密码源ES地址/源…...

指向未来: 量子纠缠的本质是一个指针

指向未来: 量子纠缠的本质是一个指针 概述基本概念理解量子纠缠PythonJavaC 理解波粒二象性PythonJavaC 理解量子隧穿理解宇宙常量PythonJavaC 概述 量子纠缠 (Quantum Entanglement) 是量子系统重两个或多个粒子间的一种特殊连接, 这种连接使得即使相隔很远, 这些粒子的状态也…...

Zookeeper启动报错常见问题以及常用zk命令

Zk常规启动的命令如下 sh bin/zkServer.sh start 启动过程如果存在失败&#xff0c;是没办法直接看出什么问题&#xff0c;只会报出来 Starting zookeeper … FAILED TO START 可以用如下命令启动&#xff0c;便于查看zk启动过程中的详细错误 sh bin/zkServer.sh start-for…...

【数据结构 】哈夫曼编译码器

数据结构-----哈夫曼编译码器 题目题目描述基本要求算法分析 代码实现初始化编码解码打印代码打印哈夫曼树 总结 题目 题目描述 利用哈夫曼编码进行信息通信可大大提高信道利用率&#xff0c;缩短信息传输时间&#xff0c;降低传输成本。 要求&#xff1a;在发送端通过一个编…...

大屏项目:react中实现3d效果的环形图包括指引线

参考链接3d环形图 3d效果的环形图 项目需求实现方式指引线&#xff08;线的样式字体颜色&#xff09; 项目需求 需要在大屏上实现一个3d的环形图&#xff0c;并且自带指引线&#xff0c;指引线的颜色和每段数据的颜色一样&#xff0c;文本内容变成白色&#xff0c;数字内容变…...

【STM32】STM32学习笔记-FlyMCU串口下载和STLINK Utility(30)

00. 目录 文章目录 00. 目录01. 串口简介02. 串口连接电路图03. FlyMCU软件下载程序04. 串口下载原理05. FlyMCU软件其它操作06. STLINK Utility软件07. 软件下载08. 附录 01. 串口简介 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式&#xff0c;因为它简…...

oracle rac 12.2.0.1CPU使用率100%

oracle rac 12.2.0.1 CPU使用率100% 查看是集群的java进程"oracle.ops.opsctl.OPSCTLDriver config database"占用cpu 根据进程号查找父进程,发现是/oracle/GRID/122/perl/bin/perl /oracle/GRID/122/tfa/gcmproddb01/tfa_home/bin/tfactl.pl rediscover -mode full …...

LeetCode、2542. 最大子序列的分数【中等,排序+小顶堆】

文章目录 前言LeetCode、2542. 最大子序列的分数【中等&#xff0c;排序小顶堆】题目及类型思路及代码实现 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领…...

Linux_Docker图形化工具Portainer如何安装并结合内网穿透实现远程访问

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 本文主要介绍如何本地安装Portainer并结合内网穿透工具实现任意浏览器远程访问管理界面。Portainer 是一个轻量级…...

【Spring Boot 3】【Redis】集成Jedis

【Spring Boot 3】【Redis】集成Jedis 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费…...

C++设计模式(李建忠)笔记3

C设计模式&#xff08;李建忠&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 参考链接 Youtube: C设计模式 Gtihub源码与PPT&#xff1a;https://github.com/ZachL1/Bilibili-plus 豆瓣: 设计模式–可复用面向对象软件的基础 文章目录 C设计模…...

计算机考研408的准备

计算机考研408的准备 一&#xff1a;专硕和学硕 计算机的学硕叫做计算机科学与技术&#xff0c;而计算机的专硕叫计算机技术。这么区分的意义就在于我们的就业形势和科研形式。 二&#xff1a;就业形势 由于本科的严重扩招以及课程设置的问题&#xff0c;相当大量的人在毕业…...

2.【Linux】(进程的状态||深入理解fork||底层剖析||task_struct||进程优先级||并行和并发||详解环境变量)

一.进程 1.进程调度 Linux把所有进程通过双向链表的方式连接起来组成任务队列&#xff0c;操作系统和cpu通过选择一个task_struct执行其代码来调度进程。 2.进程的状态 1.运行态&#xff1a;pcb结构体在运行或在运行队列中排队。 2.阻塞态&#xff1a;等待非cpu资源就绪&am…...

【管理篇 / 升级】❀ 13. FortiOS 7.4固件升级新规则 ❀ FortiGate 防火墙

【简介】飞塔防火墙的固件升级一直是所有厂家中最好的。只要有注册官方帐号&#xff0c;有注册设备&#xff0c;并且只要有一台设备在服务期内&#xff0c;即可下载所有型号的所有版本的固件。即使其它设备服务期已过&#xff0c;也可以通过固件文件手动升级&#xff0c;避免防…...

【前端】vue.js从入门到项目实战笔记

文章目录 第三章3.1 插值绑定&#xff08;{{}}&#xff0c; v-html&#xff09;3.1.1 文本插值3.1.2 HTML插值 3.2 属性绑定 v-bind3.2.1 指令v-bind3.2.3 类名和样式绑定 【前端目录贴】 第三章 3.1 插值绑定&#xff08;{{}}&#xff0c; v-html&#xff09; 文本插值中的代…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...