你到底占多大内存?---字符变量

新手必看:C51单片机编程,你的char、int、long到底占多大内存? 本文详细解析了C51单片机编程中char、int、long等数据类型的内存占用情况,帮助新手精准掌握内存管理。通过Keil调试器的内存窗口展示实际存储内容,对比PC与C51的差异,提供内存优化技巧,如使用data、idata关键字和code存储,显著提升编程效率。 阅读详情

在c/c++中,经常会遇到考察一个变量占多大的内存,往往会涉及到很多的细节问题,这里就进行总结一下。

1、关于字符变量的内存占用大小

2、关于struct的内存占用大小

3、关于enum的内存占用大小

4、关于union的内存占用大小

5、关于类的内存占用大小


1、字符数组和字符串

首先区分两个名词:字符数组和字符串

字符数组:首先它是一个数组,然后它存储的元素是字符。如char ch[3]={};

字符串:用双引号包围的字符序列。在C中为了标志一个字符串的结束,会在字符序列的最后一个字符后添加'\0',以标志字符串的结束。

下面来看具体的例子:

char ch[3] = {'a', 'b', 'c'};	
    char *p = "abc";
ch[3]是一个字符数组,“abc”是一个字符串。他们的长度是不一样的,ch[3]只有三个元素,而“abc”有四个元素,分别是‘a’,'b','c','\0'.

再看一个例子:

char ch[] = "abc";
这时候数组ch有几个元素呢?答案是4,因为这里是用一个字符串来初始化一个字符数组,而字符串有四个元素,都拷贝到数组内存中,即ch[]={‘a’,'b','c','\0'}.

#include <iostream>
using namespace std;

int main()
{
	char ch[3] = {'a', 'b', 'c'};	
	char *p = "abcdefg";
	char array[] = "abcdefg";

	cout<<sizeof(ch)<<endl;		//3
	cout<<sizeof(p)<<endl;		//4
	cout<<sizeof(array)<<endl;	//8

	return 0;
}
ch[3]占用3字节,这个很显然。但是p占用4字节,而array占用8字节,这是为什么呢?


         这是因为p的类型是char*,也即p是一个指针变量,指针变量在32位系统中占用4字节;而array的类型为char[8], 所以会占用8个字节。

这里有一个细节需要注意:"abcdefg"是存储在静态常量区。p是栈区的一个指针,指向该位于静态常量区的字符串;array也是位于栈区,但是用一个字符串常量来初始化一个栈区的字符数组,会在栈区开辟一段空间,然后将字符串常量拷贝到栈区,所以array就占有8个字节了,这时候它存储的只是字符串常量的一个副本,更改array数组,并不能更改字符串常量。示例如下:

#include <iostream>
using namespace std;

int main()
{
	char *p = "abcdefg";
	char array[] = "abcdefg";

	array[3] = 'a';

	while (*p)
	{
		cout<<*p;
		p++;
	}
	cout<<endl;

	cout<<array<<endl;

	return 0;
}

输出结果:

abcdefg

abcaefg


另外需要注意的一个问题是:p指向的是一个常量区的字符串,该字符串是不允许被更改,即它是只读的。为了防止疏忽,即通过指针p来修改常量,通常将p声明为const char*.

2、还有一个特别需要注意的问题:当数组作为函数的参数时,它又占用多大的内存呢?

对于数组参数,编译器把它解释为普通的指针类型,如void fun(char ch[10], char *p),ch的类型是char*,而不是char[10], p的类型是char*,这样p和ch占用的内存都是4个字节。

下面看一道面试题,练习一下。


char array[] = "abcdefg";
printf("%d\n",sizeof(array));        // 8

char ch[7] = "abcd";
printf("%d\n", sizeof(ch));			 //7

char *p = "abcdefg";
printf("%d\n",sizeof(p));            // 4

void func(char p[10])
{
	printf("%d\n",sizeof(p));        // 4
}

void func(char (&p)[10])
{
	printf("%d\n",sizeof(p));        // 10
}

int main(void)
{
	printf("%d\n",sizeof(char[2]));     // 2
	printf("%d\n",sizeof(char&));       // 1
	return 0;
}

3、上面所讲的其实都是关于sizeof()对于字符相关变量的操作,字符操作还有另一个常用的函数strlen()

extern unsigned int strlen(char *s)
函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个'\0'.

#include <iostream>
using namespace std;

int main()
{
	char str1[3] = {'a', 'b', 'c'};	
	char str2[10] = {'a', 'b', 'c'};
	char str3[10] = "abc";
	char str4[] = "abc";
	char *str5 = "abc";
	
	cout<<strlen(str1)<<endl;	//非正确值,因为找不到'\0'
	cout<<strlen(str2)<<endl;	//3
	cout<<strlen(str3)<<endl;	//3
	cout<<strlen(str4)<<endl;	//3
	cout<<strlen(str5)<<endl;	//3

	return 0;
}




c#窗体应用(.NET Framework)项目对Yaml文件进行写入与读取,Yaml数据转换成json 用到的技术与版本准备工作Yaml数据在C#中进行定义对Yaml文件的读取与写入代码的添加窗体控件控制操作写入数据到Yaml文件读取Yaml文件数据Yaml数据转换成json改进——对yaml文件读取时根据yaml文件中的键进行获取,对c#中怎么取名字无关yaml文件中多个数据读取遇到的问题总结的小点参考的文章在对Yaml文件进行读取前,先将Yaml文件中的数据结构在c#中进行定义,以便后面更好的读取。这里对这四个类型进行举例(这里为了想看看这四个类型到Yaml文件的格式是什么样子的) 阅读详情

相关推荐

macOS 12.7.6部署Ollama+Dify避坑指南

本文介绍了在macOS 12.7.6系统下部署Ollama和Dify的详细步骤及避坑指南。主要内容包括:1)关闭系统完整性保护(SIP)以允许修改系统目录;2)安装特定版本的Docker(2.1.0.5)和docker-compose(v2.38.2)以避免兼容性问题;3)配置Ollama服务并下载nomic-embed-text和deepseek-r1:7b模型;4)针对macOS调整Dify的docker配置文件,包括延长超时时间、修改存储路径、增加资源限制等关键设置。文中提供了完整的命令操作步骤和配置

Hi20240217的博客 3103

C++字符串类实现:从动态内存管理到STL string核心原理

在C++编程中,字符串处理是基础且高频的操作。理解字符串类的底层实现原理,尤其是动态内存管理机制,对于掌握C++核心编程思想至关重要。字符串类本质上是对字符序列的封装,其核心在于通过指针和动态内存分配,实现安全高效的变长存储。这涉及到深拷贝与浅拷贝的区别、拷贝构造函数与赋值运算符的重载(Rule of Three),以及为避免频繁内存分配而采用的倍增扩容策略等关键技术。这些原理不仅是面试常见考点,更是编写健壮、高效C++代码的基石。通过手动实现一个简化的`MyString`类,可以深入理解`std::str

weixin_32576389的博客 242

SPH vs Lagrange网格混合建模实战:用LS-DYNA模拟弹丸穿孔效应

本文深入探讨了在LS-DYNA中运用SPH与Lagrange网格混合建模技术,高效模拟超高速碰撞下弹丸穿孔效应的实战方法。通过分析模型分区策略、耦合界面处理及关键参数设置,解决了传统方法在模拟大变形、材料断裂时的网格畸变或计算成本高昂问题,为相关工程仿真提供了兼顾精度与效率的解决方案。

weixin_29211309的博客 109

sizeof(数组名)与sizeof(*数组名)

sizeof(数组名)与sizeof(*数组名) 举例 #include<stdio.h> int main() { int a[5]={1,2,3,4,5}; printf(“sizeof数组名=%d\n”,sizeof(a)); printf(“sizeof *数组名=%d\n”,sizeof(*a)); } 运行结果 sizeof数组名=20 sizeof *数组名=4 分析:...

weixin_45479946的博客 1338

ROS激光雷达动态避障算法优化(C++实战)

本文深入探讨了ROS激光雷达动态避障算法的C++实战优化。针对动态环境的核心挑战,文章系统性地介绍了从激光数据预处理(降噪、瘦身)、动态障碍物检测与跟踪,到基于动态窗口法(DWA)的智能决策与调优的全流程。重点分享了如何将障碍物速度预测融入DWA打分函数,以实现更安全、流畅的避障,并提供了工程架构、性能优化及真机调试的实用建议。

weixin_29192141的博客 945

从生成到检测:全面解析Deepfake技术的演进与对抗策略

本文全面解析了Deepfake技术的演进与对抗策略,从GAN生成技术到先进的检测手段,探讨了其在娱乐与安全领域的双重影响。文章详细介绍了Deepfake的核心原理、技术迭代关键节点以及最新的检测方法,揭示了AI生成与识别的激烈博弈。同时,展望了量子计算和生物特征认证在未来攻防战中的潜在应用。

jenkins8butler的博客 255

sizeof()用法汇总

转自:https://www.cnblogs.com/chengxin1982/archive/2009/01/13/1374575.html sizeof()功能:计算数据空间的字节数 1.与strlen()比较 strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为’\0’的数组元素。 而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。 2.指针...

u013728021的博客 316

【BigWorld 游戏服务器引擎】Cell 架构设计介绍,及Java实现方案的探索

横向扩展(Scalability):通过动态增减CellApp和BaseApp的数量,可以轻松应对玩家人数的变化。世界可以做得非常大,只需增加更多的 Cell。负载分离(Load Separation):将不同性质的负载分离,避免了单一进程瓶颈。CPU 密集型的实时计算(CellApp)和 I/O 密集型的数据操作(BaseApp)互不影响。高效的视野管理(AOI):每个 Cell 只关心自己区域内和边界上的实体,大大降低了计算复杂度。容错性:某个CellApp。

代码时光 1205

sizeof(*P)与sizeof(p)的区别

例如,如果有一个指向整型变量的指针 `int *p`,那么 `sizeof(p)` 返回的是指针 `p` 在当前系统中的大小,通常是 4 或 8 字节,而 `sizeof(*p)` 返回的是整型变量的大小,通常是 4 字节。另外,如果有一个指向字符数组的指针 `char *p`,那么 `sizeof(*p)` 返回的是字符数组的大小,而不是指针的大小。当 `sizeof` 的参数是指针类型时,它返回的是指针类型在当前系统中的大小,通常是 4 或 8 字节,具体取决于系统的位数。

Xiao_li______的博客 1390

Unity 2021 LTS安装避坑指南:从下载到第一个3D项目的完整流程

本文提供了一份详尽的Unity 2021 LTS安装与首个3D项目创建指南。内容涵盖从Unity Hub下载、版本选择、模块安装避坑,到编辑器界面解析、创建旋转立方体脚本的完整流程,旨在帮助初学者快速搭建稳定开发环境并上手核心操作。

mango的博客 310

ISP算法:自动白平衡(AWB)

1. 为什么要做白平衡? 人类视觉系统具有颜色恒常性特点,一次人类对物体观察不受光源影响。但是Sensor在不同光线下,物体呈现的颜色不同,在晴朗天空下会偏蓝,在烛光下会偏红。如图: 2.什么是自动白平衡? 为了消除光源对于图像传感器成像的影响,模拟人类视觉系统的颜色恒常性。保证在任何场景下看到的白色是真正的白色。 3. 如何做自动白平衡? 只要乘以一个对角矩阵,便可以进行白平衡...

a200800170331的专栏 1万+

sizeof(指针)和sizeof(数组)的区别

对指针利用sizeof得到的都是一个相同的值。在C语言中,指针只保存一个地址,所以任何类型的指针都占用相同的字节数。 对数组名利用sizeof得到的是整个数组占用的字节数。 printf(“sizeof(a)/sizeof(a[0])=%d\n”,sizeof(a)/sizeof(a[0])); 根据数组名a来计算数组到底有多少个元素。 大多数情况下,sizeof多被用在文件的二进制读写方面。 ...

weixin_47965641的博客 1594

液滴碰撞壁面的过程背景论文——bouncing反弹,spreading扩展,splashing飞溅。铺展过程介绍。还存在很多未解之谜。

【1993-德国-Phenomena of liquid drop impact on solid and liquid surfaces】液滴碰撞壁面的过程背景——bouncing反弹,spreading扩展,splashing飞溅。还存在很多未解之谜。还存在很多未解之谜。不同液滴形状碰撞过程。

qq_15963745的博客 199

C语言中用sizeof()测量指针变量结果却不同,如sizeof(*p)和sizeof(p)

对字符指针变量p初始化,实际是把字符串第一个元素的地址(即存放字符串的字符数组的首元素地址)赋给指针变量p,使p指向字符串的第一个字符,由于字符串常量"hello"已由系统分配在内存连续的6个字节,因此,p就指向字符串第一个字符,所以,1.如char *p="hello",*p所指的是内容,p所指的地址,这是因为p是指向地址,地址是为8位,所以,为什么会出现1和8呢?

m0_69808624的博客 2554

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

详解 C 数据类型|常量、变量、内存大小、进制转换

通过预处理指令#define定义的标识符,用于代表一个固定常量(预处理阶段,会直接替换成宏值)增强代码的可读性(用有意义的标识符代替魔法数字)提升代码的可维护性(需修改常量时,仅需要修改宏定义,无需逐个修改代码)#define 宏名称 宏值① 宏名称与宏值之间用空格隔开;② 行末不能加;(否则替换是会带入分号,导致语法错误)③ 宏名称命名规范:字母(A~Za~z)+ 数字(0~9)+ 下划线(),不能以数字开头。习惯上宏名使用全大写(如MAX_VALUE),小写字母也合法但较少用于宏(如。

2401_82399733的博客 613

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C语言学习(1)--安装环境和初识C语言(1)

开发环境:vscode,在vscode中配置C语言,具体操作主要看第一章。

Ice_JS的博客 1140

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

java中8中基本数据类型及类型转换

数据类型转换的很基础的知识,也很详细。

pan_jianping的博客 1264

C语言知识点总结

C语言的数据类型 数据类型包括:基本数据类型、构造数据类型和指针类型。 基本数据类型有:整形(short int、int、long int),实型(float、double、long double),字符型char。 构造类型有:数组、结构体struct、枚举型enum、共用体union。 注:数组说白了就是一个容器;枚举就是为了限定数据选择 二、规定不同的数据类型是为了计算机内

vincerce的专栏 2040

孙子教我学编程008/数据类型

📦 C语言变量与数据类型:电脑的"小盒子"分类法(用傻瓜翻译大法拆解内存存储原理) 🔢 变量:内存里的"收纳盒"1. 定义变量 = 找个盒子贴标签int a; // 找个盒子,贴标签叫"a",专门放整数 a = 123; // 往盒子里塞数字123 int = 整数(英文Integer的缩写) = = 塞数据进盒子(不是数学的“等于”)2. 变量能变!a = 1000; // 把123扔掉,换成1000 a = 9999; // 再换成9999(盒子里永远只有最新值)变量就像便利贴,值能随时

blacklive233的博客 340

C的数据类型

unsigned char // 无符号字符(只可以是正数,一般存图片/字节)signed char // 有符号字符(可正可负)long double // 超高精度小数。double // 双精度小数(最常用)布尔类型(_Bool /bool)char // 字符类型(常用)—— 小数(精度更高,最常用):身高、体重、温度、BMI 等。1、字符(char)用来存。float // 单精度小数。(整数、小数、字符、真假):年龄、身高、分数、数量等。四、浮点型(小数类型)int // 最常用。

XRQ13的博客 31

c基础核心总结

一、数组和指针数组名存的就是数组首元素的地址,所以:1.数组名其实就是常量指针,不能对其进行自加自减等操作,它指向数组的第一个元素,那么它的步长是多少呢?这得看数组的类型,例如:1)int arr[6]; 这是个一维数组,类型是int[6],数组名就是第一个元素的地址,所以数组名指向arr[0],步长是4(4个字节)。2)int arr[6][7]; 这是个二维数组,类型是int[6][7],数组......

m0_37829435的博客 310

关于【Node、npm、yarn】的安装教程

关于node、npm、yarn的安装教程以及简单介绍

WQH_Boss的博客 2068

AGentleIntroductiontoPointersinCProgramming

在C语言中,指针是一个核心且强大的概念。本质上,指针是一个变量,但与其他变量不同,它存储的不是一个普通的值(比如整数或字符),而是另一个变量的内存地址。你可以把内存想象成一个巨大的、由无数房间(内存单元)组成的旅馆,每个房间都有唯一的房间号(内存地址)。指针就是一张写着特定房间号的纸条。通过这张纸条,你不仅能知道那个房间里住的是谁(存储的值),还能直接去访问甚至改变那个房间的住客。指针是C语言赋予程序员的强大工具,它提供了直接操作内存的能力,使得程序更加高效和灵活。

hhl0910的专栏 236

Windows下MySQL安装与环境配置

1.先去官网下载:Mysql包 下载下来是压缩包形式,解压到你要指定的文件夹下,再一步步点击安装即可 2.安装完成后,进入mysql目录下进行环境配置 (1)配置my.ini,我的mysql安装在D:\mysql-8.0.20-winx64下,在该文件夹里新建my.ini,把下面内容复制进去即可 [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [mysqld] # 设置3306端口 port = 3306 # 设置mysql的安装目录 b

追梦人 719

Go语言基本数据类型

float32:单精度,精度约 6~7 位小数float64:双精度,精度约 15~16 位小数(开发默认首选)Go 不支持自动类型转换,不同类型必须手动强转整型不能当 bool 使用,没有 0 假 1 真len(字符串) 是字节数,不是字符数中文必须用 rune 遍历,byte 遍历会乱码、统计错误字符串不可修改,只能重新赋值Go 基础类型分为:布尔、整型、浮点、字符、字符串。byte 处理 ASCII,rune 处理 Unicode 中文。

m0_75069300的博客 202

java基础知识总结

java基础知识总结

卓越之识论道,平常之识论事,狭隘之识论人 1871
上一篇: KMP算法
下一篇: 最长对称子串
traceorigin
博客等级 码龄15年 38粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值