最近做一些面试题目碰到了很多次考察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. Spring Boot 2 实践记录之 Powermock 和 SpringBootTest

    由于要代码中使用了 Date 类生成实时时间,单元测试中需要 Mock Date 的构造方法,以预设其行为,这就要使用到 PowerMock 在 Spring Boot 的测试套件中,需要添加 @Ru ...

  2. 记一次golang的实践

    之前做过一个深交所股票数据的接存储软件,消息的协议是这样. 协议文档在这  https://wenku.baidu.com/view/d102cd0b4a73f242336c1eb91a37f111f ...

  3. 解决vs2015引用时没有Report Viewer的问题

    1.选择“工具”>“Nuget包管理器”>“程序包管理器控制台” 执行命令:Install-Package Microsoft.ReportingServices.ReportViewer ...

  4. 批处理系列(18) - 基于BitLocker的开锁上锁

    首先要配置好BitLocker. 上锁 lock.bat @echo off rem 上锁前要结束一些程序,浏览器要注意:有恢复上次关闭项功能,按需设置取消该操作 taskkill /f /t /im ...

  5. TCP BBR - 一键安装最新内核并开启 TCP BBR

    原文地址: https://teddysun.com/489.html 最近,Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9 开始,Linux 内核已经 ...

  6. Recursion-687. Longest Univalue Path

    Given a binary tree, find the length of the longest path where each node in the path has the same va ...

  7. 八,mysql优化——读写分离

    读写分离目的是给大型网站缓解查询压力.

  8. Android之系统架构

    Android 是Google开发的基于Linux平台的开源手机操作系统.它包括操作系统.用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍.Andr ...

  9. 【ARC072F】 Dam 单调队列

    题目大意: 有一个水库,容量为$L$,一开始是空的.有$n$天. 对于第i天,每天早上有$v_i$单位的,水温为$t_i$的水流进来.每天晚上你可以放掉一些水,多少自定.但是必须保证第二天水库不会溢出 ...

  10. 移动端h5直播项目|html5直播实战开发|h5仿陌陌

    最近一些直播.小视频什么的都比较火,像陌陌.抖音.火山短视频… 于是空闲时间自己也利用html5技术也试着倒腾了下直播项目,使用到了h5+css3+iscroll+zepot+swiper+wlsPo ...