最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言編程中的聯(lián)合體union入門學(xué)習(xí)教程

 更新時(shí)間:2015年12月02日 17:59:41   作者:海子  
這篇文章主要介紹了C語(yǔ)言編程中的聯(lián)合體union入門學(xué)習(xí)教程,也是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下

聯(lián)合體(union)在C語(yǔ)言中是一個(gè)特殊的數(shù)據(jù)類型,能夠存儲(chǔ)不同類型的數(shù)據(jù)在同一個(gè)內(nèi)存位置??梢远x一個(gè)聯(lián)合體使用許多成員,但只有一個(gè)部件可以包含在任何時(shí)候給定的值。聯(lián)合體會(huì)提供使用相同的存儲(chǔ)器位置供多用途的有效方式。

定義聯(lián)合體
要定義聯(lián)合體,必須使用union語(yǔ)句很相似于定義結(jié)構(gòu)。聯(lián)合體聲明中定義了一個(gè)新的數(shù)據(jù)類型,程序不止一個(gè)成員。聯(lián)合體聲明的格式如下:

union [union tag]
{
  member definition;
  member definition;
  ...
  member definition;
} [one or more union variables]; 

union標(biāo)簽是可選的,每個(gè)成員的定義是一個(gè)正常的變量定義,如 int i; 和 float f; 或任何其他有效的變量的定義。在聯(lián)合體定義的結(jié)尾,最后分號(hào)之前,可以指定一個(gè)或多個(gè)變量的聯(lián)合,但它是可選的。這里定義一個(gè)名為數(shù)據(jù)聯(lián)合類型有三個(gè)成員 i, f, 和 str:

union Data
{
  int i;
  float f;
  char str[20];
} data; 

現(xiàn)在,數(shù)據(jù)類型的變量可以存儲(chǔ)的整數(shù),一個(gè)浮點(diǎn)數(shù),或字符的字符串。這意味著一個(gè)單可變結(jié)構(gòu)即相同的存儲(chǔ)單元可用于存儲(chǔ)多個(gè)類型的數(shù)據(jù)。可以使用任何內(nèi)置或用戶定義的數(shù)據(jù)類型根據(jù)需要在聯(lián)合里面。

通過union所占用的內(nèi)存將大到足以容納聯(lián)合體的最大成員。例如,在上面的例子中的數(shù)據(jù)類型將占用20個(gè)字節(jié)的存儲(chǔ)空間,因?yàn)檫@是通過文字串所占用的最大空間。以下將顯示由上述聯(lián)合共占用內(nèi)存大小的例子:

#include <stdio.h>
#include <string.h>
 
union Data
{
  int i;
  float f;
  char str[20];
};
 
int main( )
{
  union Data data;    

  printf( "Memory size occupied by data : %d
", sizeof(data));

  return 0;
}

讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:

Memory size occupied by data : 20

訪問聯(lián)合體成員
要訪問聯(lián)合體的任何成員,我們使用成員訪問運(yùn)算符(.)。成員訪問運(yùn)算符編碼為聯(lián)合體變量名和成員,訪問時(shí)使用union關(guān)鍵字定義聯(lián)合體類型的變量。以下為例子來解釋聯(lián)合體的用法:

#include <stdio.h>
#include <string.h>
 
union Data
{
  int i;
  float f;
  char str[20];
};
 
int main( )
{
  union Data data;    

  data.i = 10;
  data.f = 220.5;
  strcpy( data.str, "C Programming");

  printf( "data.i : %d
", data.i);
  printf( "data.f : %f
", data.f);
  printf( "data.str : %s
", data.str);

  return 0;
}

讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:

data.i : 1917853763
data.f : 4122360580327794860452759994368.000000
data.str : C Programming

在這里,我們可以看到,聯(lián)合體成員i 和f 值被損壞,因?yàn)榉峙浣o變量終值已占用的內(nèi)存位置,如果str成員的值被很好的打印的原因?,F(xiàn)在,讓我們來再一次看看同樣的例子,我們將使用一個(gè)變量在同一時(shí)間,它是聯(lián)合體的主要目的:

#include <stdio.h>
#include <string.h>
 
union Data
{
  int i;
  float f;
  char str[20];
};
 
int main( )
{
  union Data data;    

  data.i = 10;
  printf( "data.i : %d
", data.i);
  
  data.f = 220.5;
  printf( "data.f : %f
", data.f);
  
  strcpy( data.str, "C Programming");
  printf( "data.str : %s
", data.str);

  return 0;
}

讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:

data.i : 10
data.f : 220.500000
data.str : C Programming

這里,所有的成員都得到打印得非常好,因?yàn)橐粋€(gè)部件被一次使用。

應(yīng)用場(chǎng)合
當(dāng)多個(gè)數(shù)據(jù)需要共享內(nèi)存或者多個(gè)數(shù)據(jù)每次只取其一時(shí),可以利用聯(lián)合體(union)。在C Programming Language 一書中對(duì)于聯(lián)合體是這么描述的:

     1)聯(lián)合體是一個(gè)結(jié)構(gòu);

     2)它的所有成員相對(duì)于基地址的偏移量都為0;

     3)此結(jié)構(gòu)空間要大到足夠容納最"寬"的成員;

     4)其對(duì)齊方式要適合其中所有的成員;

下面解釋這四條描述:

     由于聯(lián)合體中的所有成員是共享一段內(nèi)存的,因此每個(gè)成員的存放首地址相對(duì)于于聯(lián)合體變量的基地址的偏移量為0,即所有成員的首地址都是一樣的。為了使得所有成員能夠共享一段內(nèi)存,因此該空間必須足夠容納這些成員中最寬的成員。對(duì)于這句“對(duì)齊方式要適合其中所有的成員”是指其必須符合所有成員的自身對(duì)齊方式。

下面舉例說明:

如聯(lián)合體

union U
{
  char s[9];
  int n;
  double d;
};

s占9字節(jié),n占4字節(jié),d占8字節(jié),因此其至少需9字節(jié)的空間。然而其實(shí)際大小并不是9,用運(yùn)算符sizeof測(cè)試其大小為16.這是因?yàn)檫@里存在字節(jié)對(duì)齊的問題,9既不能被4整除,也不能被8整除。因此補(bǔ)充字節(jié)到16,這樣就符合所有成員的自身對(duì)齊了。從這里可以看出聯(lián)合體所占的空間不僅取決于最寬成員,還跟所有成員有關(guān)系,即其大小必須滿足兩個(gè)條件:1)大小足夠容納最寬的成員;2)大小能被其包含的所有基本數(shù)據(jù)類型的大小所整除。

測(cè)試程序:

/*測(cè)試聯(lián)合體 2011.10.3*/

#include <iostream>
using namespace std;

union U1
{
  char s[9];
  int n;
  double d;
};

union U2
{
  char s[5];
  int n;
  double d;
};

int main(int argc, char *argv[])
{
  U1 u1;
  U2 u2;
  printf("%d\n",sizeof(u1));
  printf("%d\n",sizeof(u2));
  printf("0x%x\n",&u1);
  printf("0x%x\n",&u1.s);
  printf("0x%x\n",&u1.n);
  printf("0x%x\n",&u1.d);
  u1.n=1;
  printf("%d\n",u1.s[0]);
  printf("%lf\n",u1.d);
  unsigned char *p=(unsigned char *)&u1;
  printf("%d\n",*p);
  printf("%d\n",*(p+1));
  printf("%d\n",*(p+2));
  printf("%d\n",*(p+3));
  printf("%d\n",*(p+4));
  printf("%d\n",*(p+5));
  printf("%d\n",*(p+6));
  printf("%d\n",*(p+7));
  return 0;
}

輸出結(jié)果為:

16
8
0x22ff60
0x22ff60
0x22ff60
0x22ff60
1
0.000000
1
0
0
0
48
204
64
0
請(qǐng)按任意鍵繼續(xù). . .

對(duì)于sizeof(u1)=16。因?yàn)閡1中s占9字節(jié),n占4字節(jié),d占8字節(jié),因此至少需要9字節(jié)。其包含的基本數(shù)據(jù)類型為char,int,double分別占1,4,8字節(jié),為了使u1所占空間的大小能被1,4,8整除,則需填充字節(jié)以到16,因此sizeof(u1)=16.

對(duì)于sizeof(u2)=8。因?yàn)閡2中s占5字節(jié),n占4字節(jié),d占8字節(jié),因此至少需要8字節(jié)。其包含的基本數(shù)據(jù)類型為char,int,double分別占1,4,8字節(jié),為了使u2所占空間的大小能被1,4,8整除,不需填充字節(jié),因?yàn)?本身就能滿足要求。因此sizeof(u2)=8。

從打印出的每個(gè)成員的基地址可以看出,聯(lián)合體中每個(gè)成員的基地址都相同,等于聯(lián)合體變量的首地址。

對(duì)u1.n=1,將u1的n賦值為1后,則該段內(nèi)存的前4個(gè)字節(jié)存儲(chǔ)的數(shù)據(jù)為00000001 00000000 00000000 00000000

因此取s[0]的數(shù)據(jù)表示取第一個(gè)單元的數(shù)據(jù),其整型值為1,所以打印出的結(jié)果為1.

至于打印出的d為0.000000愿意如下。由于已知該段內(nèi)存前4字節(jié)的單元存儲(chǔ)的數(shù)據(jù)為00000001 00000000 00000000 00000000,從上面打印結(jié)果48,204,64,0可以知道后面4個(gè)字節(jié)單元中的數(shù)據(jù)為00110000 11001100 01000000 00000000,因此其表示的二進(jìn) 制浮點(diǎn)數(shù)為

00000000 01000000 11001100 00110000 00000000 00000000 00000000 00000001

對(duì)于double型數(shù)據(jù),第63位0為符號(hào)位,62-52 00000000100為階碼,0000 11001100 00110000 00000000 00000000 00000000 00000001為尾數(shù),根據(jù)其值知道尾數(shù)值約為0,而階碼為4-1023=-1019,因此其表示的浮點(diǎn)數(shù)為1.0*2^(-1019)=0.00000000000......,因此輸出結(jié)果為0.000000。

相關(guān)文章

  • C++實(shí)現(xiàn)鬧鐘程序的方法

    C++實(shí)現(xiàn)鬧鐘程序的方法

    這篇文章主要介紹了C++實(shí)現(xiàn)鬧鐘程序的方法,比較實(shí)用的功能,需要的朋友可以參考下
    2014-08-08
  • C語(yǔ)言計(jì)算器的3種實(shí)現(xiàn)方法代碼

    C語(yǔ)言計(jì)算器的3種實(shí)現(xiàn)方法代碼

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言計(jì)算器的3種實(shí)現(xiàn)方法,文中通過代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一的參考借鑒價(jià)值,需要的朋友可以參考下
    2007-01-01
  • C語(yǔ)言簡(jiǎn)明分析選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)的使用

    C語(yǔ)言簡(jiǎn)明分析選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)的使用

    C語(yǔ)言條件控制語(yǔ)句選擇結(jié)構(gòu),是屬于計(jì)算機(jī)的語(yǔ)言編輯,有在C語(yǔ)言條件控制中的語(yǔ)句選擇結(jié)構(gòu)的存在,即是C語(yǔ)言條件控制語(yǔ)句選擇結(jié)構(gòu),循環(huán)控制語(yǔ)句是一個(gè)基于C語(yǔ)言的編程語(yǔ)句,該語(yǔ)句主要有while循環(huán)語(yǔ)句、do-while循環(huán)語(yǔ)句和for循環(huán)語(yǔ)句來實(shí)現(xiàn)循環(huán)結(jié)構(gòu)
    2022-04-04
  • OpenCV通過透視變換實(shí)現(xiàn)矯正圖像詳解

    OpenCV通過透視變換實(shí)現(xiàn)矯正圖像詳解

    這篇文章主要為大家詳細(xì)介紹了OpenCV如何通過透視變換實(shí)現(xiàn)將一張折射的圖片給矯正過來,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-02-02
  • C++中的四個(gè)默認(rèn)成員函數(shù)與運(yùn)算符重載詳解

    C++中的四個(gè)默認(rèn)成員函數(shù)與運(yùn)算符重載詳解

    這篇文章主要給大家介紹了關(guān)于C++中四個(gè)默認(rèn)成員函數(shù)與運(yùn)算符重載的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來跟著小編一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • 詳解c++11以正確的姿勢(shì)輸出enum class的值

    詳解c++11以正確的姿勢(shì)輸出enum class的值

    這篇文章主要介紹了詳解c++11以正確的姿勢(shì)輸出enum class的值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • c語(yǔ)言算術(shù)運(yùn)算符越界問題解決方案

    c語(yǔ)言算術(shù)運(yùn)算符越界問題解決方案

    大量的安全漏洞是由于計(jì)算機(jī)算術(shù)運(yùn)算的微妙細(xì)節(jié)引起的, 具體的C語(yǔ)言, 諸如符號(hào)數(shù)和無(wú)符號(hào)數(shù)之間轉(zhuǎn)換, 算術(shù)運(yùn)算的越界都會(huì)導(dǎo)致不可預(yù)知的錯(cuò)誤和安全漏洞, 具體的案例數(shù)不勝數(shù).
    2012-11-11
  • C++標(biāo)準(zhǔn)庫(kù)介紹及使用string類的詳細(xì)過程

    C++標(biāo)準(zhǔn)庫(kù)介紹及使用string類的詳細(xì)過程

    C++中將string封裝為單獨(dú)的類,string?類是?C++?標(biāo)準(zhǔn)庫(kù)中的一個(gè)非常重要的類,用于表示和操作字符串,這篇文章主要介紹了C++標(biāo)準(zhǔn)庫(kù)介紹及使用string類,需要的朋友可以參考下
    2024-08-08
  • C語(yǔ)言實(shí)現(xiàn)三子棋程序

    C語(yǔ)言實(shí)現(xiàn)三子棋程序

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)三子棋程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C++關(guān)鍵字之likely和unlikely詳解

    C++關(guān)鍵字之likely和unlikely詳解

    這篇文章主要介紹了C++關(guān)鍵字之likely和unlikely,C++20之前的,likely和unlikely只不過是一對(duì)自定義的宏,而C++20中正式將likely和unlikely確定為屬性關(guān)鍵字,本文給大家詳細(xì)講解,需要的朋友可以參考下
    2022-10-10

最新評(píng)論

普兰店市| 廊坊市| 合川市| 全州县| 从江县| 浦城县| 孝昌县| 云梦县| 富裕县| 江阴市| 巨野县| 阿鲁科尔沁旗| 县级市| 莆田市| 前郭尔| 泸定县| 靖远县| 南安市| 延津县| 札达县| 军事| 兴和县| 罗田县| 姚安县| 手机| 泽普县| 图们市| 西昌市| 孝感市| 都江堰市| 米林县| 土默特左旗| 谢通门县| 保山市| 六枝特区| 当雄县| 湘潭县| 六安市| 曲阳县| 中卫市| 富裕县|