C++程序设计基础(5)sizeof的使用
1.知识点
(1)sizeof是一个单目运算发,而不是一个函数,其用于获取操作数所占内存空间的字节数。
(2)sizeof的操作数可以使类型名,也可以是表达式,如果是类型名则直接获得该类型所占字节数,如果是表达式,则先分析表达式结果的类型,再根据类型确定所占字节数,并不对表达式进行实际计算。
1 int a = 1; 2 double b = 1.5; 3 sizeof(int);//结果为4 4 sizeof(a); //结果为4 5 sizeof(b); //结果为8
(3)sizeof很少单独使用,而是和内存分配或者计算法数组长度等需求进行配合使用。
1 //与内存空间分配配合使用 2 int *ptr = (int *)malloc(sizeof(int) * 20); 3 //与计算数组长度配合使用 4 int count = sizeof(darray) / sizeof(double);
(4)数组名作为操作数时,将获得整个数组所占空间,当数组名作为实参传递给子函数时,此时数组名已经成为了指针,其计算结果将是指针的所占空间。
void subfunc(double darray[]) { cout << sizeof(darray) / sizeof(double) << endl; //输出4/8=0 } int main(int argc, char *argv[]) { double darray[20]; cout << sizeof(darray) / sizeof(double) << endl; //输出16/8=20 subfunc(darray); getchar(); return 0; }
(5)在计算字符串长度时要用strlen。sizeof是一个运算符,用于获取类型或表达式的所占内存大小;strlen是一个函数,用于计算字符串中字符的个数,其中字符串结尾符\0不会被计算在内。
2.面试题
2.1不能使用sizeof计算的表达式
1 struct baby 2 { 3 unsigned int gender : 1; 4 unsigned int weight : 5; 5 unsigned int week : 7; 6 unsigned int blood : 3; 7 unsigned int height : 8; 8 }; 9 int triple(int number) { 10 return 3 * number; 11 } 12 int main(int argc, char *argv[]) { 13 sizeof(baby); //A 14 sizeof(baby.gender);//B 15 sizeof(triple);//C 16 sizeof(triple(3));//D 17 sizeof(show());//E 18 19 getchar(); 20 return 0; 21 }
答案:正确:A,D;错误:B,C,E.
(1)sizeof计算结构体是结果是结构体的所占内存空间,结构体中使用了位域定义成员,要求一个位域成员不能横跨两个字节,故可以算出该结构体的字节数为4,A正确。
(2)sizeof计算的结果是字节数,但是不允许计算结构体中某个位域成员的所占空间,当然如果不是位域定义的是可以计算的。故B错。
(3)不允许计算函数名的所占字节数大小,有点莫名其妙,C错。
(4)允许计算表达函数表达式,其结果是函数返回值的类型的字节数,即该题的int大小,D正确。
(5)函数返回值类型不确定使,不允许通过sizeof计算,故E错误。
2.2sizeof计算结构体是的内存对其问题
写出下面两个结构体的sizeof计算结果
struct s1{ char a;//1 short b;//4 int c;//8 double d;//16,16刚好是double大小的整数倍 }; struct s2 { char a;//1 short b;//4 double c;//16(从9开始排) int d;//20(该结果不是double的整数倍,故需要加到24) };
数据对其总结:(1)每个成员在内存中的起始位置都必须是自身大小的整数倍。
(2)最终结构体计算结果必须是占字节数最大的成员的整数倍。
答案:16,24。
2.3结构体嵌套时的sizeof计算
1 struct s1 { 2 int a; 3 }; 4 struct s2 { 5 char a[4]; 6 }; 7 struct s3{ 8 char a[4]; 9 char b; 10 }; 11 struct s4 { 12 s1 a; 13 char b; 14 }; 15 struct s5{ 16 s2 a; 17 char b; 18 };
含复杂结构体的数据对其总结:在数据对其时,要以结构体中最深层的基本数据类型为准。例如:如果结构体成员是一个数组,应以数组的元素的类型作为数据对其的标准,如果结构体成员是其他结构体,应以内层结构体中的基本元素类型成员作为外层结构体数据对齐的标准。故答案如下
1 sizeof(struct s1)=4; 2 sizeof(struct s2)=4; 3 sizeof(struct s3)=5; 4 sizeof(struct s4)=8; 5 sizeof(struct s5)=5;
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java类的初始化顺序
做Java开发的,起码要知道类的初始化顺序,因为这样你才知道编写的代码运行到了那里。 与文无关 一段代码 public class BaseTest { private String baseName = "baseName"; static { System.out.println("父类静态代码块"); } public BaseTest() { System.out.println("父类构造方法"); callName(); } public void callName(){ System.out.println(baseName); } static class Sub extends BaseTest{ private String baseName = "subName"; public Sub() { System.out.println("子类构造方法"); } static { System.out.println("子类静态代码块"); } @Override public void callName() { System.out.println(baseName...
- 下一篇
Java多线程 -- 互斥锁/共享锁/读写锁 快速入门
什么是互斥锁? 在访问共享资源之前对进行加锁操作,在访问完成之后进行解锁操作。 加锁后,任何其他试图再次加锁的线程会被阻塞,直到当前进程解锁。 如果解锁时有一个以上的线程阻塞,那么所有该锁上的线程都被编程就绪状态, 第一个变为就绪状态的线程又执行加锁操作,那么其他的线程又会进入等待。 在这种方式下,只有一个线程能够访问被互斥锁保护的资源。 什么是共享锁? 互斥锁要求只能有一个线程访问被保护的资源,共享锁从字面来看也即是允许多个线程共同访问资源。 什么是读写锁? 读写锁既是互斥锁,又是共享锁,read模式是共享,write是互斥(排它锁)的。 读写锁有三种状态:读加锁状态、写加锁状态和不加锁状态 一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。 用ReentrantLock手动实现一个简单的读写锁。 MyReadWriteLock.java /** * Created by Fant.J. */ public class MyReadWriteLock { private Map<String,Object> map = new HashMap...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果