数组的sizeof

转载:http://blog.163.com/chen_xinghuan/blog/static/17220158220112182838196/
数组的sizeof值等于数组所占用的内存字节数,如:
  char a1[] = “abc”;
  int a2[3];
  sizeof( a1 ); // 结果为4,字符 末尾还存在一个NULL终止符
  sizeof( a2 ); // 结果为3*4=12(依赖于int)
  一些朋友刚开始时把sizeof当作了求数组元素的个数,现在,你应该知道这是不对的,那么应该**怎么求数组元素的个数呢**Easy,通常有下面两种写法:
  int c1 = sizeof( a1 ) / sizeof( int ); // 总长度/单个元素的长度
  int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 总长度/第一个元素的长度
  写到这里,提一问,下面的c3,c4值应该是多少呢
  void foo3(char a3[3])
  {
  int c3 = sizeof( a3 ); // c3 ==
  }
  void foo4(char a4[])
  {
  int c4 = sizeof( a4 ); // c4 ==
  }
  也许当你试图回答c4的值时已经意识到c3答错了,是的,c3!=3。这里函数参数a3已不再是数组类型,而是蜕变成指针,相当于char* a3,为什么仔细想想就不难明白,我们调用函数foo1时,程序会在栈上分配一个大小为3的数组吗不会!数组是“传址”的,调用者只需将实参的地址传递过去,所以a3自然为指针类型(char*),c3的值也就为4。
  7. 结构体的sizeof
  这是初学者问得最多的一个问题,所以这里有必要多费点笔墨。让我们先看一个结构体:
  struct S1
  {
  char c;
  int i;
  };
  问sizeof(s1)等于多少聪明的你开始思考了,char占1个字节,int占4个字节,那么加起来就应该是5。是这样吗你在你机器上试过了吗也许你是对的,但很可能你是错的!VC6中按默认设置得到的结果为8。
  Why为什么受伤的总是我
  请不要沮丧,我们来好好琢磨一下sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节数,好吧,那就让我们来看看S1的内存分配情况:
  S1 s1 = { ‘a’, 0xFFFFFFFF };
  定义上面的变量后,加上断点,运行程序,观察s1所在的内存,你发现了什么
  以我的VC6.0为例,s1的地址为0x0012FF78,其数据内容如下:
  0012FF78: 61 CC CC CC FF FF FF FF
  发现了什么怎么中间夹杂了3个字节的CC看看MSDN上的说明:
  When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.
  原来如此,这就是传说中的字节对齐啊!一个重要的话题出现了。
  为什么需要字节对齐计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。
  让我们交换一下S1中char与int的位置:
  struct S2
  {
  int i;
  char c;
  };
  看看sizeof(S2)的结果为多少,怎么还是8再看看内存,原来成员c后面仍然有3个填充字节,这又是为什么啊别着急,下面总结规律。
  字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
  1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
  2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal padding);
  3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
  对于上面的准则,有几点需要说明:
  1) 前面不是说结构体成员的地址是其大小的整数倍,怎么又说到偏移量了呢因为有了第1点存在,所以我们就可以只考虑成员的偏移量,这样思考起来简单。想想为什么。
  结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得,这个宏也在stddef.h中定义,如下:
  #define offsetof(s,m) (size_t)&(((s *)0)->m)
  例如,想要获得S2中c的偏移量,方法为
  size_t pos = offsetof(S2, c);// pos等于4
  2) 基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型,这里所说的“数据宽度”就是指其sizeof的大小。由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。
  这里叙述起来有点拗口,思考起来也有点挠头,还是让我们看看例子吧(具体数值仍以VC6为例,以后不再说明):
  struct S3
  {
  char c1;
  S1 s;
  char c2;
  };
  S1的最宽简单成员的类型为int,S3在考虑最宽简单类型成员时是将S1“打散”看的,所以S3的最宽简单类型为int,这样,通过S3定义的变量,其存储空间首地址需要被4整除,整个sizeof(S3)的值也应该被4整除。
  c1的偏移量为0,s的偏移量呢这时s是一个整体,它作为结构体变量也满足前面三个准则,所以其大小为8,偏移量为4,c1与s之间便需要3个填充字节,而c2与s之间就不需要了,所以c2的偏移量为12,算上c2的大小为13,13是不能被4整除的,这样末尾还得补上3个填充字节。最后得到sizeof(S3)的值为16。
  通过上面的叙述,我们可以得到一个公式:
  结构体的大小等于最后一个成员的偏移量加上其大小再加上末尾的填充字节数目,即:
  sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构行编辑成簇 c语言,索引的数据结构及底层存储

索引是帮助数据库高效获取数据的数据结构索引的数据结构1.hash表a.利用hash存储的话需要将所有的数据文件添加到内存,比较耗费内存空间b.hash表存储的是无序数据,范围查找的时候需要挨个进行遍历,比较耗费时间。2.二叉树二叉树规定左子树必须…

卓同学的 Swift 面试题

我觉得应该掌握的知识点,没有实际意义。 class 和 struct 的区别不通过继承,代码复用(共享)的方式有哪些Set 独有的方法有哪些?实现一个 min 函数,返回两个元素较小的元素map、filter、reduce 的作用map 与…

使用CImage双缓冲

一普通显示:现在的VC显示图片非常方便,远不是VC6.0那个年代的技术可比,而且支持多种格式的如JPG,PNG。 CImage _img; 初始化: _img.Load(L"map.png"); 显示:OnPaint事件中 CRect rect; this…

汇编语言学习系列 for循环实现

假如汇编语言要实现如下C语言的功能&#xff0c;编译环境Ubuntu14.04&#xff08;32位&#xff09;。 #include<stdio.h> int fact_for(int n) {int i;int result 1;for(i 2; i < n; i)result * i;return result; }int main(){printf("%d\n", fact_for(3)…

川大锦城c语言期末考试答案,四川大学《计算机组成原理》2018期末考试B卷答案及评分标准.doc...

四川大学期末考试试题(闭卷)答案及评分标准(2017——2018学年第 2 学期) B卷课程号&#xff1a;304036030 课程名称&#xff1a;计算机组成原理填空题(本大题共15空&#xff0c;每空2分&#xff0c;共30分)在评价计算机性能时用 响应时间 表示计算机完成某任务所需时间;用 吞吐…

2014届华为校园招聘机试题2

第一题、输入一个正整数&#xff0c;并编码为字符串进行输出 描述: 1、输入一个正整数&#xff0c;并编码为字符串进行输出。 编码规则为&#xff1a;数字0-9分别编码为字符a-j 2、输入肯定是正整数&#xff0c;不用做错误较验 运行时间限制: 无限制 内存限制: 无限制 输…

图解phpstorm常用快捷键

查询快捷键 CTRLN 查找类 CTRLSHIFTN 全局搜索文件 ,优先文件名匹配的文件 CTRLSHIFTALTN 查找php类名/变量名 ,js方法名/变量名, css 选择器 CIRLB 找变量的来源&#xff0c;跳到变量申明处 (CTRL 鼠标单击 也可以) CTRLALTB 找到继承该接口或者父级 的所有子类, 统计所有子类…

The C Programming Language--可变参数的函数

函数 printf的正确声明形式为&#xff1a;int printf(char *fmt, ...) void va_start (va list ap, last-required) type va_arg (va list ap, type) void va_end (va list ap) 其中&#xff0c;省略号表示参数表中参数的数量和类型是可变的。 va_list 类型用于声明一个变量&am…

二分查找法的循环与递归实现及时间复杂度分析

转载&#xff1a;http://baike.baidu.com/link?url3aEK-qcVbYi6ioJOsf-dFmvFQ6WQgzTwnE9JkmlHBc88qk-D00SambfrSl3hVh_UyqyxF8QEUosfq20IQQW5z_ 和http://hi.baidu.com/networkor/item/80d817f8331d8e08a7298834 设数组为整数数组&#xff0c;从小到大排序。二分法强调一定是…

cifar10 c语言,Python3读取深度学习CIFAR-10数据集出现的若干问题解决

今天在看网上的视频学习深度学习的时候&#xff0c;用到了CIFAR-10数据集。当我兴高采烈的运行代码时&#xff0c;却发现了一些错误&#xff1a;# -*- coding: utf-8 -*-import pickle as pimport numpy as np import os def load_CIFAR_batch(filename): """ 载…

Java程序性能优化

一、避免在循环条件中使用复杂表达式 在不做编译优化的情况下&#xff0c;在循环中&#xff0c;循环条件会被反复计算&#xff0c;如果不使用复杂表达式&#xff0c;而使循环条件值不变的话&#xff0c;程序将会运行的更快。 例子&#xff1a; import java.util.vector; class …

asp.net表单提交方法:GET\POST介绍

表单form的提交有两种方式&#xff0c;一种是get的方法&#xff0c;一种是post 的方法&#xff0c;如果没有特殊指定&#xff0c;默认为post。看下面代码,理解ASP.NET Get和Post两种提交的区别: 1.< form id"form1" method"get" runat"server"…

各种排序算法总结

转载&#xff1a;http://blog.csdn.net/warringah1/article/details/8951220 明天就要去参加阿里巴巴的实习生笔试了&#xff0c;虽然没想着能进去&#xff0c;但是态度还是要端正的&#xff0c;也没什么可以准备的&#xff0c;复习复习排序吧。 1 插入排序 void InsertSort(in…

CentOS7 上安装 Zookeeper-3.4.9 服务

在 CentOS7 上安装 zookeeper-3.4.9 服务1、创建 /usr/local/services/zookeeper 文件夹&#xff1a; mkdir -p /usr/local/services/zookeeper 2、进入到 /usr/local/services/zookeeper 目录中&#xff1a; cd /usr/local/services/zookeeper 3、下载 zookeeper-3.4.9.…

c语言在程序中显示现在星期几,C语言程序设计: 输入年月日 然后输出是星期几...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include main(){int year,month,day0,a,b,week,c,i,sum0,days,d;printf("please input year,month,days\n");scanf("%d,%d,%d",&year,&month,&days);for(i1;i{if (year%40){if(year%1000){if (ye…

static之用法

本文转载于http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html 在C语言中&#xff0c;static的字面意思很容易把我们导入歧途&#xff0c;其实它的作用有三条。 &#xff08;1&#xff09;先来介绍它的第一条也是最重要的一条&#xff1a;隐藏。 当我们同时编译…

HTTP响应报文与工作原理详解

HTTP 是一种请求/响应式的协议&#xff0c;即一个客户端与服务器建立连接后&#xff0c;向服务器发送一个请求;服务器接到请求后&#xff0c;给予相应的响应信息。 超文本传输协议(Hypertext Transfer Protocol&#xff0c;简称HTTP)是应用层协议。HTTP 是一种请求/响应式的协议…

优先队列priority_queue 用法详解

转载&#xff1a; 1.优先队列priority_queue 用法详解 2.STL系列之五 priority_queue 优先级队列 优先队列是队列的一种&#xff0c;不过它可以按照自定义的一种方式&#xff08;数据的优先级&#xff09;来对队列中的数据进行动态的排序 每次的push和pop操作&#xff0c;队…

android自定义画板,android 自定义控件 -- 画板

如图&#xff1a;package com.example.myview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Paint.Style;import android.util.Attrib…

postgreSQl pathman 用法语句总结

2019独角兽企业重金招聘Python工程师标准>>> --新建主表 create table part_test(id int, info text, crt_time timestamp not null); --插入测试数据 insert into part_test select id,md5(random()::text),clock_timestamp() (id|| hour)::interval from generat…