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

并非从0开始的c++之旅 day2

并非从0开始的c++之旅 day2

  • 一、变量
    • 1、 变量名的本质
  • 二、程序的内存分区模型
    • 1、内存分区
      • 运行之前
      • 运行之后
  • 三、栈区注意事项
  • 四、堆区
    • 1、堆区使用
    • 2、堆区注意事项
  • 五、全局变量静态变量
    • 1、静态变量
    • 2、全局变量
  • 六、常量
    • 1、全局const常量
    • 2、局部const常量
  • 七、字符串常量

一、变量

既能读又能写的内存对象,成为变量;
若一旦初始化后不能修改的对象则称为常量。

1、 变量名的本质

变量名的本质:一段连续内存空间的别名
程序通过变量来申请和命名内存空间 int a = 0;
通过变量名访问内存空间
不是向变量名读写数据,而是向变量所代表的内存空间中读写数据;

变量修改方式:直接修改、间接修改

void test01() {int a = 10;///1、直接修改a = 20;//2、间接修改int* p = &a;//*p 解引用*p = 200;printf("a = %d\n", a);
}```自定义数据类型练习```c
struct Person {char a;int b;char c;int d;
};void test02()
{struct Person p1 = { 'a',10,'b',20 };//直接修改d属性p1.d = 100;printf("%d\n", p1.d);//间接修改d属性struct Person* p = &p1;p->d = 200;printf("%d\n", p1.d);
}

这种间接修改太简单了,我们还要学一种

若使指针p加一,p指针会跳过一个结构体的字节数
其中char类型占1个字节,int类型占4个字节,a占用0~3,b从4开始,系统用内存对齐的方式让a也占用了虽然他不使用但是在b之前的字节

结果使用以下代码验证

printf("%d\n", p);
printf("%d\n", p+1);

可得两值差16,同理我们可以用这种方式修改变量

	char* p = &p1;printf("%d\n", *(int*)(p + 12));printf("%d\n", *(int*)((int*)p + 3));

将p指针类型改为char *型,这时增加p指针的值会使其会一个一个往前走,在输出时,因为我们需要的是4个字节的int类型的内容,故需要做强制类型转换,将其转换为int *类型
同理如上面的第三行代码

二、程序的内存分区模型

1、内存分区

运行之前

可以简单先分为代码区和数据区
程序执行过程:

1)预处理:宏定义展开、头文件展开、条件编译,这里并不会检查语法
2)编译:检查语法,将预处理后文件编译生成汇编文件
3)汇编:将汇编文件生成目标文件(二进制文件)
4)链接:将目标文件链接为可执行程序

当我们编译完成生成可执行文件之后,我们可以通过linux下size命令可以查看一个可执行文件基本情况:
执行size命令后,系统会给出一下几个数据:

text 代码区
data 静态数据/全局初始化数据区
bss 未初始化初始化数据区
dec 文件十进制总和
hex 文件十六进制总和
filename 文件名

通过以上数据可知,在没有运行程序前,也就是说程序没有加载到内存前,可执行程序内部已经分好了3段信息,分别为代码区、数据区和未初始化数据区3个部分(有些人直接把data和bss合起来叫做静态区或全局区)

  • 代码区:存放CPU执行的机器指令。通常代码区是可共享的(即另外的执行程序可以调用它),使其可共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。代码区通常是只读的,使其只读的原因是防止程序意外地修改了他的指令。另外,代码区还规划了局部变量的相关信息
  • 全局初始化数据区\静态数据区:该区包含了在程序中明确被初始化的全局变量、已经初始化的静态变量(包括全局静态变量和t)和常量数据(如字符串常量)
  • 未初始化数据区(又叫bss区):存入的是全局未初始化变量和未初始化静态变量。未初始化数据区的数据在程序开始执行之前被内核初始化为0或空(NULL)

运行之后

相比运行之前,多出了栈区和堆区

  • 栈区(stack):栈是一种先进后出的内存结构,由编译器自动分配释放,存放函数的参数值、返回值、局部变量等。在程序运行过程中实时加载和释放,因此,局部变量的生存周期为申请到释放该段栈空间
  • 堆区(heap):堆是一个大容器,它的容量要远远大于栈,但没有栈那样先进后出的顺序。用于动态内存分配。堆在内存中位于BSS区和栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。

栈区:先进后出,编译器管理数据开辟,释放,容量有限,不要将大量数据开辟到栈区
堆区:容量远远大于栈区,程序员手动开辟数据,手动释放数据

三、栈区注意事项

int* fun() {int a = 10;//栈上创建的变量return &a;
}void test01() {int* p = fun();//结果依然不重要,因为上面的a早已被释放,再去操作这块数据属于非法操作printf("%d\n", *p);printf("%d\n", *p);
}

栈上的数据在执行完方法就释放了,第一次printf能打出正确结果其实是因为编译器认为你可能会处理错了数据,故保留一次,第二次打印时结果才是正常的,已经是一个随机数了。

char* GetString() {char str[] = "hello world";return str;
}void test02() {char* p = NULL;p = GetString();printf("p = %s\n", p);
}

上述代码中,将p打印后的结果为字符型乱码,因为str是指向字符串的指针,但字符串在函数运行结束后自动释放了,故他指向的地址已经为乱码,打印出来也为乱码

这里的hello world原本在常量区,无法修改,被复制了一份到栈区

两段代码告诉我们,栈上的数据出了函数体后就不要再使用了 ,也即不要返回局部变量的地址,局部变量在函数体执行完毕后会被释放,再次操作就是非法操作,结果未知!

四、堆区

1、堆区使用

int* getSpace() {int * p = malloc(sizeof(int) * 5);if (p == NULL)return NULL;for (int i = 0; i < 5; i++) {p[i] = 100 + i;}return p;
}void test01() {int* p = getSpace();for (int i = 0; i < 5; i++)printf("%d\n", p[i]);//释放数据free(p);p = NULL;
}

使用malloc创建的空间在堆区,printf多少次结果都一样,创建后如果没有使用就是垃圾,需要free
防止free后的指针仍指向原来那块已经被释放的空间,称为野指针,我们需要把它设成NULL

2、堆区注意事项

void allocateSpace(char* p) {char* temp = malloc(100);memset(temp, 0, 100);strcpy(temp, "hello world");p = temp;}void test02() {char* p = NULL;allocateSpace(p);printf("p = %s\n", p);
}

打印出来的结果为NULL,因为test中的p和函数的参数p属于同级指针,test的p为NULL时,同级指针无法改变他的值,若要改需要更高级的二级指针。
修改为以下代码

void allocateSpace2(char** p) {char* temp = malloc(100);memset(temp, 0, 100);strcpy(temp, "hello world");*p = temp;}void test03() {char* p2 = NULL;allocateSpace2(&p2);printf("p2 = %s\n", p2);
}

p一开始为NULL,参数p的值为传入p的地址,temp为堆区开辟的地址,解参数p后赋值temp,也就是将temp所含的地址赋予p,这样p就能直接指向temp所指向的堆

如果给主调函数中,一个空指针分配内存,在被调函数中利用同级指针是分配失败的
解决方式:利用高级指针修饰低级指针

五、全局变量静态变量

1、静态变量

生命周期在程序运行结束时死亡
在程序运行前就分配内存
默认属于内部链接属性,在当前文件中使用

static int a = 10;//全局作用域void test01() {static int b = 19;//局部作用域
}

默认内部链接属性,在文件外是访问不到的,如在同一个项目的另一个类中就访问不到这里的a

2、全局变量

默认在c语言下,全局变量前加了关键字 extern
属于外部链接属性

	extern int g_b;g_b = 100;

若在其他类中写了一个全局变量,想在main函数中引用,需要有第一行这个代码
这个代码就是告诉编译器,其他文件中有这么一个变量,链接时要去其他文件中寻找
但是要是找不到这个全局变量,就会报错,报错为1个无法解析的外部命令,该报错是在链接阶段报的

六、常量

1、全局const常量

//const 修饰的常量
const int a = 10;//全局const常量void test01() {//直接修改失败//a = 100;//间接修改int* p = &a;*p = 100;printf("%d\n", a);
}

如果直接修改,则a会有红线,显示语法错误
如果间接修改,vs2019会报错,显示写入访问权限冲突
全局const常量放在常量区中,受到常量区的保护

2、局部const常量

void test02() {const int b = 10;//直接修改失败//b = 100;//间接修改int* p = &a;*p = 100;printf("%d\n", b);
}

直接修改依然语法不行
间接修改正常运行,因为局部常量放在栈区,我们称之为伪常量
伪常量不可以初始化数组

七、字符串常量

void test03() {char* p1 = "hello world";char* p2 = "hello world";char* p3 = "hello world";printf("%d\n", p1);printf("%d\n", p2);printf("%d\n", p3);printf("%d\n", &"hello world");
}

由上述代码结果可知,用字符串指针指向字符串常量,得到的地址都是一样的,可知字符串常量是可以共享的

void test04() {char* p1 = "hello world";p1[0] = "w";printf("%d\n", p1);
}

运行后会报错,字符串常量是不能修改的,虽然ANSIC中规定是不定义的,但vs是不能修改的
vs会把多个相同的字符串常量看成一个

相关文章:

并非从0开始的c++之旅 day2

并非从0开始的c之旅 day2一、变量1、 变量名的本质二、程序的内存分区模型1、内存分区运行之前运行之后三、栈区注意事项四、堆区1、堆区使用2、堆区注意事项五、全局变量静态变量1、静态变量2、全局变量六、常量1、全局const常量2、局部const常量七、字符串常量一、变量 既能…...

Linux进阶(Shell编程学习一)

由于shell脚本在java项目运维方面极其重要&#xff0c;比如服务的启动脚本&#xff0c;日志的分割脚本&#xff0c;文件的管理脚本大多都是shell脚本去实现的。所以作为java开发者懂linux的基本命令&#xff0c;会基本的shell编程是必要的。 Shell 是一个用 C 语言编写的程序&…...

sql 优化

sql 优化1. mysql 基础架构1.1 mysql 的组成2. mysql 存储引擎2.1MyISAM2.2 InnoDB2.3 MyISAM 和 InnoDB 的对比3. mysql 索引3.1 Hash 索引3.2 B-Tree 索引3.3 BTree 索引3.4 R-Tree 索引3.5 Full-Text 索引4. sql 优化4.1 避免 select *4.2 避免在where子句中使用or来连接条件…...

第7篇:Java的学习路径

目录 1、Java学习主要内容概览 1.1 Java基础 1.2 数据库技术 1.3 动态网页技术 1.4中间件技术...

对抗生成网络GAN系列——Spectral Normalization原理详解及源码解析

&#x1f34a;作者简介&#xff1a;秃头小苏&#xff0c;致力于用最通俗的语言描述问题 &#x1f34a;专栏推荐&#xff1a;深度学习网络原理与实战 &#x1f34a;近期目标&#xff1a;写好专栏的每一篇文章 &#x1f34a;支持小苏&#xff1a;点赞&#x1f44d;&#x1f3fc;、…...

Solon2 开发之插件,一、插件

Solon Plugin 是框架的核心接口&#xff0c;简称“插件”。其本质是一个“生命周期”接口。它可让一个组件类参与程序的生命周期过程&#xff08;这块看下&#xff1a;《应用启动过程与完整生命周期》&#xff09;&#xff1a; FunctionalInterface public interface Plugin {…...

使用nvm管理node

nvm介紹 node的版本管理器&#xff0c;可以方便地安装&切换不同版本的node 我们在工作中&#xff0c;可以会有老版本的node的项目需要维护&#xff0c;也可能有新版本的node的项目需要开发&#xff0c;如果只有一个node版本的话将会很麻烦&#xff0c;nvm可以解决我们的难点…...

Linux

第一章 Linux 1.1 计算机硬件软件体系 冯诺依曼 (数学家,计算机之父) 冯诺依曼体系 计算机的指令和数据都是二进制存储,并且存放到一起程序和指令都是顺序执行的计算机硬件由输入,输出,存储,运算器与控制器组成 输入设备 比如:键盘,鼠标等. 输出设备 打印机输出&#xff0…...

GB28181-2022注册注销基本要求、注册重定向解读和技术实现

规范解读GB28181-2022注册、注销基本要求相对GB28181-2016版本&#xff0c;做了一定的调整&#xff0c;新调整的部分如下&#xff1a;——更改了注册和注销基本要求&#xff08;见 9.1.1&#xff0c;2016 年版的 9.1.1&#xff09;。1.增加对NAT模式网络传输要求&#xff0c;宜…...

2023年二建报考条件是什么?考试考什么?来考网

2023年二建报考条件是什么&#xff1f;考试考什么&#xff1f;来考网 2023年二建报考条件是什么&#xff1f;考试考什么&#xff1f;来考网 二建报考条件&#xff1a; 1、中专及以上学历 2、工程或工程经济类专业 3、从事施工管理工作满2年 二建考试科目&#xff1a; 《建设工…...

vite+vue3搭建的工程热更新失效问题

前段时间开发新的项目&#xff0c;由于没有技术上的限制&#xff0c;所以选择了vitevue3ts来开发新的项目&#xff0c;一开始用vite来开发新项目过程挺顺利&#xff0c;确实比vue2webpack的项目高效些&#xff08;为什么选择vite&#xff09;,但是过了一段时间后&#xff0c;不…...

Hazel游戏引擎(001-003)

文章目录前言001.游戏引擎介绍002.什么是游戏引擎003设计我们的游戏引擎本人菜鸟&#xff0c;文中若有代码、术语等错误&#xff0c;欢迎指正 前言 我写的项目地址 https://github.com/liujianjie/GameEngineLightWeight&#xff08;中文的注释适合中国人的你&#xff09; 关于…...

耗时一个星期整理的APP自动化测试工具大全

在本篇文章中&#xff0c;将给大家推荐14款日常工作中经常用到的测试开发工具神器&#xff0c;涵盖了自动化测试、APP性能测试、稳定性测试、抓包工具等。 一、UI自动化测试工具 1. uiautomator2 openatx开源的ui自动化工具&#xff0c;支持Android和iOS。主要面向的编程语言…...

算法设计与分析(屈婉玲)视频笔记day2

序列求和的方法 数列求和公式 等差、等比数列与调和级数 求和的例子 二分检索算法 二分检索运行实例 2 n 1个输入 比较 t 次的输入个数 二分检索平均时间复杂度 估计和式上界的放大法 放大法的例子 估计和式渐近的界 估计和式渐近的界 小结 • 序列求和基本公式&#xff1a;…...

14-PHP使用过的函数 131-140

131、session_unset 释放当前会话注册的所有会话变量。 没有返回值。 132、session_destroy 销毁当前会话中的全部数据&#xff0c; 但是不会重置当前会话所关联的全局变量&#xff0c; 也不会重置会话 cookie。 如果需要再次使用会话变量&#xff0c; 必须重新调用 session_…...

【第39天】实现一个冒泡排序

本文已收录于专栏 🌸《Java入门一百例》🌸 学习指引 序、专栏前言一、冒泡排序一、【例题1】1、题目描述2、解题思路3、模板代码三、推荐专栏序、专栏前言 本专栏开启,目的在于帮助大家更好的掌握学习Java,特别是一些Java学习者难以在网上找到系统地算法学习资料帮助自身…...

「2」线性代数(期末复习)

&#x1f680;&#x1f680;&#x1f680;大家觉不错的话&#xff0c;就恳求大家点点关注&#xff0c;点点小爱心&#xff0c;指点指点&#x1f680;&#x1f680;&#x1f680; 方阵的行列式 (1) &#xff5c;A^T&#xff5c;&#xff5c;A&#xff5c;(2) |&#x1d6…...

动态规划专题——背包问题

&#x1f9d1;‍&#x1f4bb; 文章作者&#xff1a;Iareges &#x1f517; 博客主页&#xff1a;https://blog.csdn.net/raelum ⚠️ 转载请注明出处 目录前言一、01背包1.1 使用滚动数组优化二、完全背包2.1 使用滚动数组优化三、多重背包3.1 使用二进制优化四、分组背包总结…...

数据的分组聚合

1&#xff1a;分组 t.groupby #coding:utf-8 import pandas as pd import numpy as np file_path./starbucks_store_worldwide.csv dfpd.read_csv(file_path) #print(df.head(1)) #print(df.info()) groupeddf.groupby(byCountry) print(grouped) #DataFrameGroupBy #可以遍历…...

【Airplay_BCT】Bonjour conformance tests苹果IOT

从Airplay开始&#xff0c;接触到BCT&#xff0c;这是什么&#xff1f;被迫从安卓变成ios用户和开发。。。开始我的学习之旅&#xff0c;记录成长过程&#xff0c;不定时更新 Bonjour 下面是苹果官网关于bonjour的解释 Bonjour, also known as zero-configuration networking, …...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...