c語言結構體字節運算,c語言結構體運算符

本文目錄一覽:

C語言中的結構體的大小如何計算

庫函數sizeof();參數是結構體的變量。如果你自己計算的話就是每個結構體成員的大小相加,不同編譯器下是不同的,所以用sizeof()比較好。int

有的編譯器是2字節,有的就是4字節。你舉得例子就是int

2字節+float

4字節+char

1字節。

C語言裡面的字節對齊的計算方法能講解1下嗎?

首先你要知道為什麼會出現字節對齊,這是一種用空間換時間的做法,因為對齊之後可以提高取數的效率。結構體的大小一般是4或者8的倍數,具體是以最大的變量類型的大小為基數的。也就是說在內存中,數據一般是放在一個4的整數倍的起始地址。

sturct S

{

char c;

short s;

int i;

}

它的大小是8個字節,因為前面兩個佔了4字節。如果寫成下面這種形式,它就是12字節了

struct S

{

char c;

int i;

short s;

}

因為為了提高存取效率,所以第一個成員變量佔了四個字節的空間,最後一個成員也佔了四個字節

你非要說計算方法的話要根據具體情況來算了,首先看結構體中哪一個變量所佔的字節數最大,然後後面的對齊計算都以這個為基數(我這裡以4字節為例)。接着,你把每一個成員變量的大小依次相加(按照結構體定義中的順序,從第一個加到最後一個)。當你加到某一個變量的時候,發現超過了4個字節,那麼就把這個變量之前的內容當作是一個整體,它們一共點4個字節,後面的再繼續這個過程

C語言,結構體問題?所佔內在字節數,怎麼算的???

在c語言中如何計算結構體長度和共用體長度?

結構體的長度等於體內各個成員變量長度之後。如此題長度為字符串數組的長度加上兩個int型變量的長度,再加上double長度,最後結果為10+2+2+8=22。解析:char 每個字符佔一個字節(因為是一個十長度的字符數組)所以是10字節,int佔兩個字節,double佔8個字節。所以最後是10+2*2+8=22。

共用體的長度是體內成員中最長的長度。如果一個共用體內最長長度為12字節,則共用體的長度就是12。

希望能夠幫到你。如果還有什麼問題在問?

C語言中結構體字節的計算方式

  在說計算方式之前先講講幾個概念一個是 偏移量 還有一個是 內存對齊 。先說偏移量,百度百科對於它的定義是這樣:把存儲單元的實際地址與其所在段的段地址之間的距離稱為段內偏移,也稱為“有效地址或偏移量”。在結構體裡面大概是指結構體變量中成員的地址和結構體變量地址的差。然後再說一下內存對齊這個概念:內存中存放基本類型數據時,計算機的系統會對其位置有限制,系統會要求這些數據的首地址的值是某個數的倍數,而這個數被稱為該數據類型的對齊模數。雖然ANSI C標準中沒有強制規定相鄰聲明的變量內存中要相鄰,但是編譯器會自動幫你處理這個問題,也就是相鄰變量之間可能會填充一些字節。因此在這個問題上又有了編譯器的區別。

  那我們先來講講結構體變量在微軟的編譯器的對齊吧

      1.結構成員的首地址要是其最寬的基本類型成員的整數倍。編譯器在給結構體分配內存的時候先找到最寬的基本成員,然後再在內存中尋找地址,並將這個最寬的基本數據類型的大小作為對齊模數

       2.結構體每一個成員相對於首地址的偏移量是成員大小的整數倍,如果沒有達到這個要求,編譯器會自動填加字節。編譯器在為結構體成員開闢內存的時候會先檢查開闢內存的首地址與結構體變量的首地址之間的偏移量,如果是成員體的整數倍那麼就存放這個變量,不然的話就在這個成員和上一個成員之間填充字節,以達到整數倍的目的

       3.結構體所佔的總內存大小要是最大成員體大小的整數倍,如果不是,那麼編譯器會在末尾補充字節。結構體的最後一個成員,不僅要滿足前兩條原則,最後一條準則也要滿足。

      接下來來看看幾個例子。

這個結構體在VS 2017下的sizeof的運算結果是12。那麼根據上面的對其規則我們來對其進行計算。

首先是char a。char大小是1,相對於首地址的偏移量是0,然後是int i。int i的大小是4,相對於首地址的偏移量是1,但是1不是4的整數倍,所以編譯器會自動在char a和int i之間填充字節字節。所以in i的偏移量是4。而之後的float b大小4偏移量就是int i的偏移量加上int i的大小故float b的偏移量大小就是8,而8正好是4的倍數那麼就不會有字節填充。而結構體的大小也就自然是最後8+4=12了

從這裡也可以看出結構體大小等於最後一個成員體的大小加上它的偏移量。

那麼我們再來看一個例子

那麼我們再利用之前的算法來對其進行運算,int i的大小是4偏移量是0,int c 的大小是4偏移量是4,double b的大小是8,偏移量是8。char a的大小是1 ,偏移量是16。那麼這個結構體的變量的大小就是16+1=17嗎?答案肯定不是這樣的。在VS的sizeof的運算下這個的結果是24,為什是24呢,那麼這之前說的最後一條原則就要用上了。結構體的大小確實是等於最後一個成員的偏移量加上最後一個成員的大小,但是如果這個結構不滿足是結構體中最大成員大小的整數倍這個條件那麼,編譯器會自動在最後填充字節使其滿足,也就是說,雖然我們計算出的結果是17但是17並不是8的倍數,所以編譯器自動在最後填充字節使其成為8的倍數,即自動擴充成24.、

那我們再來說一下GCC編譯器下的模式。GCC編譯器在Windows環境下用的會比較少,主要在Linux平台下使用GCC編譯器就不遵守微軟的編譯器下的一些準則了,比如之前 說過的對齊模數。微軟的編譯器下的對齊模數是結構體成員中最大的大小而在GCC編譯器下對齊模數最大只能是4。這就意味着對齊模數只能是1,2,4中的一個。因此之前講過的在微軟編譯器下的的一些原則會有些不同。之前講過的成員的首地址的偏移量要是成員大小的整數倍在這裡就有點區別了。在GCC中如果成員大小小於等數4那麼繼續按照之前的標準就好了,但如果大於4,則結構體每個成員相對於結構體首地址的偏移量只能按照是4的整數倍來進行判斷是否添加填充。來看一個簡單的例子。

在這個例子中,如果是按照微軟的編譯器的話計算的結構應該是16,但是在GCC編譯器下是12。道理就是之前講的。

  雖然理論上如此但是我自己在試的時候發現上面的運算結果是16,沒錯是16而不是12!為什麼呢?難道是這個理論錯了么,當然不是。我們可以嘗試在GCC下計算一下sizeof(int *)(是int *而不是int)。你會發現結果是8(如果是sizeof(int)那麼結果結果就是4),輸出結果是8那就解決了我們的疑惑。 64位系統的對其長度默認是8而32位的才是4 。這就合理解釋了為什麼計算結果是16而不是12。

對齊模數的選擇只能是基於基本數據類型,所以對於結構體嵌套結構體就不能這麼,至於其的計算方式之後再補充

C語言結構體所佔用的字節數如何計算

結構體的數據類型的有點多我們就不啰嗦了,直接來看相同數據結構體的幾種書寫的格式吧。

格式一:

01.struct tagPhone

02.{

03.     char   A;

04.     int    B;

05.     short  C;

06.}Phone;

格式二:

01.struct tagPhone

02.{

03.     char   A;

04.     short  C;

05.     int    B;

06.}Phone2;

格式三:

01.struct tagPhone3

02.{

03.     char   A;

04.     char   B[2];

05.     char   C[4];

06.}Phone3;

我們都知道,char類型佔用1個字節,int型佔用4個字節,short類型佔用2個字節,long佔用8個,double佔用16個;

那麼我們可能會犯一個錯誤就是直接1+4+2=7,該結構體佔用7個字節。這是錯的。

以下我們簡單分析下:

計算結構體大小時需要考慮其內存布局,結構體在內存中存放是按單元存放的,每個單元多大取決於結構體中最大基本類型的大小。

對格式一:

以int型佔用4個來作為倍數,因為A佔用一個字節後,B放不下,所以開闢新的單元,然後開闢新的單元放C,所以格式一佔用的字節數為:3*4=12;

同理對於格式二,

A後面還有三個字節,足夠C存放,所以C根着A後面存放,然後開闢新單元存放B數據。所以格式二佔用的內存字節為2*4=8.

對於格式三:

上面結構計算大小,sizeof(Phone3) = 1 + 2 + 4 = 7, 其大小為結構體中個字段大小之和,這也是最節省空間的一種寫法。

總結:

第一種寫法,空間浪費嚴重,sizeof 計算大小與預期不一致,但是保持了每個字段的數據類型。這也是最常見的漫不經心的寫法,一般人很容易這樣寫;

第三種寫法,最節省空間的寫法,也是使用 sizeof 求大小與預期一樣的寫法,但是全部使用字節類型,丟失了字段本生的數據類型,不方便使用;

第二種寫法,介於第一種和第三種寫法之間,其空間上比較緊湊,同時又保持了結構體中字段的數據類型。

只要了解是這些寫法的差異性,可以視情況選用。

原創文章,作者:GZOV,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/131065.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
GZOV的頭像GZOV
上一篇 2024-10-03 23:42
下一篇 2024-10-03 23:42

相關推薦

  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演着非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • 條件運算符(?:)是什麼意思?

    條件運算符(?:)是JavaScript中的一種特殊的運算符,也是許多編程語言中相似語法的一部分。它可以允許我們在一個簡單、一行的語句中完成條件判斷和賦值操作,非常方便。 1.語法…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Vue TS工程結構用法介紹

    在本篇文章中,我們將從多個方面對Vue TS工程結構進行詳細的闡述,涵蓋文件結構、路由配置、組件間通訊、狀態管理等內容,並給出對應的代碼示例。 一、文件結構 一個好的文件結構可以極…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29
  • Python程序的三種基本控制結構

    控制結構是編程語言中非常重要的一部分,它們指導着程序如何在不同的情況下執行相應的指令。Python作為一種高級編程語言,也擁有三種基本的控制結構:順序結構、選擇結構和循環結構。 一…

    編程 2025-04-29
  • Python語言由荷蘭人為中心的全能編程開發工程師

    Python語言是一種高級語言,很多編程開發工程師都喜歡使用Python語言進行開發。Python語言的創始人是荷蘭人Guido van Rossum,他在1989年聖誕節期間開始…

    編程 2025-04-28
  • Python中的字節類數據

    Python作為其中一個最廣泛使用的編程語言之一,提供了多種數據類型來幫助開發者實現各種需求。在這些數據類型中,字節類數據(bytes)是一個被廣泛使用的類型。本文將會從各個方面詳…

    編程 2025-04-28

發表回復

登錄後才能評論