數組的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.pswp.cn/news/259398.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259398.shtml
英文地址,請注明出處:http://en.pswp.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…