最近做一些面试题目碰到了很多次考察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++ 类型内存占用详解的更多相关文章

  1. C语言内存对齐详解(2)

    接上一篇:C语言内存对齐详解(1) VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式.VC 中提供了#pr ...

  2. C语言内存对齐详解(3)

    接上一篇:C语言内存对齐详解(2) 在minix的stdarg.h文件中,定义了如下一个宏: /* Amount of space required in an argument list for a ...

  3. java程序运行时内存分配详解

    java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下   一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...

  4. JVM之内存结构详解

    对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bug.同时,JVM也是面试环节的中重灾区.今天开始,<JVM详解>系列开启,带大家深入了解JVM相 ...

  5. Tomcat内存设置详解

    Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...

  6. Tomcat内存溢出详解【转载】

    本文转载自 http://elf8848.iteye.com/blog/378805 Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryEr ...

  7. Linux 内存机制详解宝典

    Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...

  8. (转)Tomcat内存设置详解

    Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出JVM在启 ...

  9. 《转载》Tomcat内存设置详解

    原文地址:Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 ...

随机推荐

  1. .NET Core 和 .NET .Framework 速度比较

    废话不多说! 一下是 .NET core 和 .NET framework 速度对比. 两者使用最慢的冒泡排序算法:  排序10万条数据 次数 .NET CORE(耗时) .NET framework ...

  2. dotNet core 应用部署centos

    ---恢复内容开始--- 阅读目录 需要安装的插件以及支撑架构 安装dotnetSDK 安装jexus 安装supervisord 遇到问题汇总 注意事项.扩展延伸 需要安装的插件以及支撑架构 1.d ...

  3. WPF 捕捉全局异常

    public App() { //首先注册开始和退出事件 this.Startup += new StartupEventHandler(App_Startup); this.Exit += new ...

  4. IAP远程在线升级

    IAP远程在线升级 在上一篇中实现了LWIP网口通讯,那么肯定要加个在线升级功能,这个功能所占用的资源很少,但在物联网中很重要也很实用.在线升级就是像手机一样,先下载好系统,然后点击升级~然后就没然后 ...

  5. PHP中日期函数

    1,转化为时间戳函数:strtotime() 本函数接受一个包含美国英语日期格式的字符串并尝试将其解析为Unix时间戳,其值相对于now参数给出的时间,如果没有提供此参数则使用系统当前时间. < ...

  6. 内核漏洞学习—熟悉HEVD

    一直以来内核漏洞安全给很多人的印象就是:难,枯燥.但是内核安全是否掌握是衡量一个系统安全工程师水平的标准之一,也是安全从业人员都应该掌握的基本功.本文通过详细的实例带领读者走进内核安全的大门.难度系数 ...

  7. webpack快速入门——如何安装webpack及注意事项

    1.window+R键,输入cmd打开命令行工具,输入 mkdir XXXX(XX:文件夹名): 2.cd XXX 进入刚刚创建好的文件夹里,输入cnpm install -g webpack (安装 ...

  8. 使用dev-tool定位页面性能瓶颈

    这是部门同事的一次内部分享,听完后受益颇多,趁着记忆还算新鲜,赶紧记录一波. 从 dev-tool 看页面 parse 过程 时间都去哪儿了 当浏览器发送一个请求到接受所有响应数据截止,这个过程发生了 ...

  9. jsp页面,jstl标签中的数据在<%%>java中使用

    可参考jsp的API隐式对象.. 这部分数据其实被保存在page域中,但jsp中如果使用java代码需要在特定的标签中<%%>,在这个标签中可使用的只有pageContext对象,所以可以 ...

  10. Optimizing Your App for Today’s Internet

    这个 session 的主讲人感觉是一个很典型的美国人,年纪也不小. 网络现状 四十亿人在使用因特网,大概占有世界人口的一半.上网人数的增长在减缓. 但是网络仍然在增长.增长点主要在物联网.第三世界国 ...