C/C++ 类型内存占用详解
最近做一些面试题目碰到了很多次考察C/C++类型内存占用的题目,主要考察队C/C++的指针、类型等的熟悉程度。
本blog为了方面大家参考,总结了常见的类型内存占用的情况,能力所限,若有问题,请指出!
1. 基本类型
C/C++的基本类型包括int/long等等,这些基本类型在内存中的字节数一般是固定的(当然根据不同bit的系统有所调整),下表是基本类型的占用字节数。
PS: 1byte=8bit, byte通常写成大写B, bit一般写为小写b
下表单位均为Byte
System | char | short | int | long | long long | float | dobule | void * (任意类型指针) |
---|---|---|---|---|---|---|---|---|
32bit | 1 | 2 | 4 | 4 | 8 | 4 | 8 | 4 |
64bit | 1 | 2 | 4 | 8 | 8 | 4 | 8 | 8 |
不信?我们以代码说话:
#include <iostream>
using namespace std;
int main()
{
cout<<"sizeof(char)="<<sizeof(char)<<endl;
cout<<"sizeof(short)="<<sizeof(short)<<endl;
cout<<"sizeof(int)="<<sizeof(int)<<endl;
cout<<"sizeof(unsigned int)="<<sizeof(unsigned int)<<endl;
cout<<"sizeof(long)="<<sizeof(long)<<endl;
cout<<"sizeof(long long)="<<sizeof(long long)<<endl;
cout<<"sizeof(float)="<<sizeof(float)<<endl;
cout<<"sizeof(double)="<<sizeof(double)<<endl;
//Poiter type
cout<<endl;
cout<<"sizeof(void *)="<<sizeof(void *)<<endl;
cout<<"sizeof(char *)="<<sizeof(char *)<<endl;
cout<<"sizeof(int *)="<<sizeof(int *)<<endl;
cout<<"sizeof(float *)="<<sizeof(float *)<<endl;
cout<<"sizeof(double *)="<<sizeof(double *)<<endl;
return 0;
}
结果如下(我的系统是64bit的):
可以看到,任意类型的指针的位数皆为8byte,即与系统位数保持一致,因此,判断系统的位数我可以直接用sizeof(void *)
.
2. 复杂类型
编程时,有时我们会碰到如下情况:
- int *p[n]
- int (*p)[n]
以上两者到底有什么区别呢?
下面我们先看一下代码:
#include <iostream>
using namespace std;
struct A
{
int a;
int b;
long c;
long d;
};
int main()
{
//Complex type
cout<<endl;
int p1[5] = {1,2,3,4,5}; //①.P1相关
//int *p1 = &p1+1; //It's warning in c but error in C++
cout<<"sizeof(p1)="<<sizeof(p1)<<endl;
cout<<"sizeof(&p1)="<<sizeof(&p1)<<endl;
cout<<"*(p1+1) = "<<*(p1+1)<<endl;
cout<<endl;
int *p2[3]; //②.P2相关
int a[10] = {0};
int b[10] = {0};
int c[10] = {0};
p2[0] = a;
p2[1] = b;
p2[2] = c;
cout<<"int *p2[3], sizeof(p2)="<<sizeof(p2)<<endl;
cout<<"int *p2[3], sizeof(&p2)="<<sizeof(&p2)<<endl;
cout<<endl;
int (*p3)[4]; //③.P3相关
int d[3][4]={0};
p3=d;
cout<<"sizeof(p3)="<<sizeof(p3)<<endl;
cout<<"sizeof(p3[0])="<<sizeof(p3[0])<<endl;
return 0;
}
①. P1 : 数组
- p1为一维数组的数组名,包含五个int型元素
- p1虽然数值上与&p1[0]相等,但是两者不是一个东西(&p1[0]是第一个元素的地址)
- p1+1 其实就是 &p1[1]
②. P2 : 数组指针 (int *p2[n])
[]
的优先级高于*
,因此先p2[3]
,即p2先是一个数组,然后与*
结合,*p2[n]即成了数组指针(数组内部存放的内容皆为指针)
③. P3 : 指针数组(int(*p3)[n])
int (p3)[n],由于()
优先级大于[]
,所以先(p3),后为数组,即p3所指向的对象是有n个int
型元素的数组,即p3是指向一维数组的指针;p3的值即为该一维数组的地址。
以上,相当于二维数组。
结果:
根据以上讲解,你是否已经得出答案?
3. 函数相关
有的时候,我们还会遇到以下的情况:
- int *p() : 返回指针的函数
- int (*p)() : 指向函数的指针
①. int *p() 指针函数
实际上,它就是一个函数,只不过返回类型为指针而已,和普通函数没什么区别的。
#include <iostream>
#include <cstring>
using namespace std;
char *array()
{
auto ptr = new char(10);
ptr="hello";
return ptr;
}
int main()
{
char *pt = array();
cout<<pt<<endl;
return 0;
}
②. int (*p)(): 函数指针
指向函数的指针变量,其本质是一个指针。
int (*fptr)(int x); /*声明一个函数指针*/
fptr = func; /*将func函数的首地址赋给该指针*/
每个函数都有一个入口地址,将该入口地址赋值给一个指针,通过该指针即可以调用这个函数。
#include <stdio.h>
void (*ptr)(char *str);
void prt1(char *str)
{
printf("ptr1 string=%s\n", str);
return ;
}
void prt2(char *str)
{
printf("ptr2 string=%s\n", str);
return ;
}
int main()
{
ptr = prt1;
(*ptr)("hello");
ptr = prt2;
(*ptr)("world");
return 0;
}
特别类似于C++的多态是不是?
③. 函数的形式参数
有时候,我们函数的形参需要为指针,这个时候,其实我们可以有多重写法
- void *func(char *str)
- void *func(char str[])
- void *func(char str[n])
以上三种写法一个意思,即使n小于实参的字节数也无妨,此处的n只是一个提示作用而已。
C/C++ 类型内存占用详解的更多相关文章
- C语言内存对齐详解(2)
接上一篇:C语言内存对齐详解(1) VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式.VC 中提供了#pr ...
- C语言内存对齐详解(3)
接上一篇:C语言内存对齐详解(2) 在minix的stdarg.h文件中,定义了如下一个宏: /* Amount of space required in an argument list for a ...
- java程序运行时内存分配详解
java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下 一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...
- JVM之内存结构详解
对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bug.同时,JVM也是面试环节的中重灾区.今天开始,<JVM详解>系列开启,带大家深入了解JVM相 ...
- Tomcat内存设置详解
Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...
- Tomcat内存溢出详解【转载】
本文转载自 http://elf8848.iteye.com/blog/378805 Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryEr ...
- Linux 内存机制详解宝典
Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...
- (转)Tomcat内存设置详解
Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出JVM在启 ...
- 《转载》Tomcat内存设置详解
原文地址:Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 ...
随机推荐
- linux系统编程之文件与IO(一):文件描述符、open,close
什么是IO? 输入/输出是主存和外部设备之间拷贝数据的过程 设备->内存(输入操作) 内存->设备(输出操作) 高级I/O ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的 ...
- signalR常见问题
一.安装signalR会对应安装自己的NewJson包,如果引用了含有不同NewJson包的dll组件,会造成版本不一致.必须在运行环境中指出使用目标版本. 问题截图: 解决方式: <runti ...
- 构建NetCore应用框架之实战篇(三):BitAdminCore框架功能规划选择
本篇承接上篇内容,如果你不小心点击进来,建议从第一篇开始完整阅读,文章内容继承性连贯性. 构建NetCore应用框架之实战篇系列 一.BitAdminCore功能规划 如何选择框架的落地功能,前篇文章 ...
- 【大数据之数据仓库】kudu性能测试报告分析
本文由 网易云发布. 这篇博文主要的内容不是分析说明kudu的性能指标情况,而是分析为什么kudu的scan性能会这么龊!当初对外宣传可是加了各种 逆天黑科技的呀:列独立存储.bloom filte ...
- Mysql-基础+安装指南
安装指南: https://www.cnblogs.com/majj/p/9160383.html 小马哥 下载完后初始化操作数据库: 1. 将文件放在 : G:\软件\mysql-8.0.15-w ...
- web请求的状态码
摘录于 https://www.cnblogs.com/lovychen/p/6256343.html 1xx消息 这一类型的状态码,代表请求已被接受,需要继续处理.这类响应是临时响应,只包含状态行 ...
- hot code loading in nodejs
Hot Code Loading in Node.js Node.js Web应用代码热更新的另类思路 Reading through Fever today, this post by Jack M ...
- Educational Codeforces Round 26 A B C题
题目链接 A. Text Volume 题意:计算句子中,每个单词大写字母出现次数最多的那个的出现次数(混不混乱QAQ). 解题思路:注意getchar()就没啥了. #include<cstd ...
- 析构方法 deinit
/* 析构方法: 对象的内存被回收前被隐式调用的方法, 对应OC的dealloc方法 主要执行一些额外操作, 例如释放一些持有资源, 关闭文件, 断开网络等 */ class FileHandle { ...
- Vue-Router路由Vue-CLI脚手架和模块化开发 之 使用props替代路由对象的方式获取参数
在上一章博文中使用路由对象$route获取参数时,组件和路由对象耦合,在这篇博文中就可以使用props来进行解耦: 1.在组件中使用props选项定义数据,接收参数: 2.在路由中,使用props选项 ...