溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

發(fā)布時間:2020-08-10 03:25:32 來源:ITPUB博客 閱讀:207 作者:LinuxDevqqqqqq 欄目:編程語言

1.  前面說點話

上一個章節(jié)

嵌入式 Linux c 語言深度解剖(入門篇)

zhuanlan.zhihu.com

寫完后,很多看完的人都想把我按在地上摩擦,咬牙切齒不足解恨,但是也有很多人表示支持,在此,鄙人表示感謝。

這個章節(jié)說下 C 語言的關(guān)鍵字

我很想好好說下這個章節(jié),主要是很多人不知道數(shù)據(jù)如何在內(nèi)存里面存儲的,而且什么是內(nèi)存,很多初學(xué)者也不理解,內(nèi)存可以理解成很多很多個格子,比如 1G 的內(nèi)存,就有 1024x1024x1024 byte 個格子,每個格子里面都有 8 個小格子,而且每個格子都有自己的編號,這樣想就沒那么復(fù)雜了,數(shù)據(jù)類型就是把各種各樣的數(shù)據(jù)保存在這些格子里面。

如何存?怎么存?就跟不同的數(shù)據(jù)類型有關(guān)系了

 

什么是關(guān)鍵字?

C 語言有多少個關(guān)鍵字?

1 、關(guān)鍵字要跟編譯器聯(lián)系起來,比如 int 關(guān)鍵字,我寫了個 ( int i = 0;) 編譯器就知道 int 這個家伙是認(rèn)識的,編譯器就會給 int  修飾的變量分配一個房子,比如說這個房子有四個字節(jié)。

2 、 C 語言有 32 個關(guān)鍵字

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

  2. C 語言的關(guān)鍵字(數(shù)據(jù)類型關(guān)鍵字)

數(shù)據(jù)類型關(guān)鍵字一共有 12 個,分別是下面

字符類型

(1) char  :聲明字符型變量或函數(shù)

數(shù)值類型

(1) double  :聲明雙精度變量或函數(shù)

(2) float :聲明浮點型變量或函數(shù)

(3) int 聲明整型變量或函數(shù)

(4) long  :聲明長整型變量或函數(shù)

(5) short  :聲明短整型變量或函數(shù)

構(gòu)造類型

(1) enum  :聲明枚舉類型

(2) struct :聲明結(jié)構(gòu)體變量或函數(shù)

(3) union :聲明聯(lián)合數(shù)據(jù)類型

有符號型和無符號型

(1) unsigned :聲明無符號類型變量或函數(shù)

(2) signed :聲明有符號類型變量或函數(shù)

 

什么是數(shù)據(jù)類型?

我相信很多人有疑問,或者很多人自信滿滿覺得自己對數(shù)據(jù)類型非常懂,在我看來就是由不同的格子組成的,最最最基本的數(shù)據(jù)類型是 char ,char 數(shù)據(jù)類型就有一個格子(一個字節(jié)),像下面這樣

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

char 數(shù)據(jù)類型的一個格子

先說 char 數(shù)據(jù)類型

這個格子能裝多少東西呢?這是我們最想知道的,編譯器告訴你這個格子可以裝二進(jìn)制數(shù) 0B11111111, 里面有 8 個小格子,每個格子里面的東西是未知的。

<img src="https://pic4.zhimg.com/v2-1d8e0ca353ee26aa6a1411a0a3ff849f_b.jpg" data-size="normal" data-rawwidth="84" data-rawheight="88" width="84">

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

一個格子里面裝的東西示意圖

如果里面裝的是 0B11111111, 那這個格子應(yīng)該是這個樣子的,對應(yīng)的十進(jìn)制就是 255

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

上面說了 char, 下面說 unsigned  signed

上面說了,一個大格子里面有 8 個小格子,但是 8 個小格子是有順序編號的,就是 0~7

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

 

比如一個數(shù)字 0B 11111111  ,這個我們都知道是  =256 ,

定義

無符號數(shù)( unsigned )無符號數(shù)只能表示非負(fù)數(shù)( 及正數(shù))。

有符號數(shù)( signed )可以表示任何類型規(guī)定范圍內(nèi)的數(shù)。

8 個小格子,我們需要有一個格子來告訴編譯器,這個大格子裝的數(shù)據(jù)是有符號型的還是無符號類型。編譯器指定最高位的格子第 8 個格子表示符號位

所以

unsigned char i;

表示的大小是 0~255 ,一共 256 個數(shù)字

signed char i;

表示的大小是 -   c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)  ~ c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)    =-128~127 ,其中包括 ,也是 256 個數(shù)字

小例子

#include "stdafx.h"

 

int main ( int argc,  char * argv[])

{

 

      unsigned char = ;

      signed char = ;

      int = ;

      for (k = ;k < 300 ;k ++ )

     {

        i ++ ;

        j ++ ;

       printf( "%4d %4d\t" ,i,j);

     }

      return ;

}

 

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

從圖上可以看到, j 最大值是 127 , i 最小值是 i 最大值可以達(dá)到 255 , j 最小值是 -128

變量在內(nèi)存里怎么保存的,看看下面這個圖片

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

我們上面把 char unsigned signed  搞定之后,我們再來看看其他的數(shù)據(jù)類型

數(shù)值類型

(1) double  :聲明雙精度變量或函數(shù)

(2) float :聲明浮點型變量或函數(shù)

(3) int 聲明整型變量或函數(shù)

(4) long  :聲明長整型變量或函數(shù)

(5) short  :聲明短整型變量或函數(shù)

 

既然我們知道了 char 是一個格子,那么 double , float,int,long,short 是多少個格子呢?

這時候,我們就需要用到一個關(guān)鍵字 sezeof ,這個關(guān)鍵字是用來確定對象的大小的,然后我們把上面的代碼改一下

#include "stdio.h"

 

 

int main ( int argc,  char * argv[])

{

     

      char x1  = ;

      int   x2  = ;

      short x3  = ;

      long x4  = ;

      double   x5  = ;

      float x6  = ;

 

     printf( "char %d int %d short %d long %d double %d float %d\n" \

         , sizeof (x1), sizeof (x2), sizeof (x3), sizeof (x4), sizeof (x5), sizeof (x6));

     

      return ;

}

輸出如圖

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

所以我們可以知道

int  類型和 long,float 類型的格子大小如下

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

double 類型的格子大小如下

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

short 類型的格子大小如下

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

char 類型的格子大小如下

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

好了,到這里了,大家想想看

char char i = 0 ;

i 占領(lǐng)的格子大小有多少呢?有沒有這樣的寫法呢?

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

看上面的圖片, char char i =0; 是編譯不通過的,但是你想過 int int ,long long ,short short,long double 呢?

為什么會編譯出錯呢?

說太多會有別人說我裝逼厲害,有一種東西叫做編譯器,編譯器就像我們?nèi)祟惖姆梢粯?,?guī)定什么可以做什么是違法的,人類有很多種國家的法律,有些國家的法律允許一個老公娶幾個老婆,當(dāng)然,編譯器也有很多個,這個自行百度。

 

說完數(shù)值數(shù)據(jù)類型,下面就開始說

構(gòu)造類型

(1) enum  :聲明枚舉類型

(2) struct :聲明結(jié)構(gòu)體變量或函數(shù)

(3) union :聲明聯(lián)合數(shù)據(jù)類型

 

先說枚舉類型 enum

enum union_type_age{

     UNION_AGE_1 = 10 ,

     UNION_AGE_2,

     UNION_AGE_3

}union_var_age;

enum 是關(guān)鍵字, union_type_age 說明是這個整體,是這個枚舉變量的類型,就像一個戶口本,有一個戶主的名字一樣,比如小明家的爸爸叫做小寶,小寶是小明家的戶主,別人會這樣說,小寶家的小明,小寶家的 XX 之類的。

里面的 UNION_AGE_1=10, UNION_AGE_2, UNION_AGE_3  是這個枚舉類型的數(shù)值,它們是 const 常數(shù)類型的,只能在初始化的時候取設(shè)定它的值。

union_var_age 是枚舉類型的變量,它的值只能取花括號里面的數(shù)據(jù)。

 

用下面的一個小程序理解上面的內(nèi)容,不理解的請留言

#include "stdio.h"

 

enum union_type_age{

     UNION_AGE_1 = 10 ,

     UNION_AGE_2,

     UNION_AGE_3

}union_var_age;

 

 

int main ( int argc,  char * argv[])

{

     

     printf( "enum %d\n" , sizeof ( enum ));

     

     union_var_age  = UNION_AGE_2;

     printf( "union_var_age %d\n" ,union_var_age);

      return ;

}

再說結(jié)構(gòu)體 struct  數(shù)據(jù)類型

這個關(guān)鍵字的數(shù)據(jù)類型太厲害了,學(xué)過 C++ 都知道 C++ 是面向?qū)ο蟮恼Z言,但是 linux 內(nèi)核下面有很多通過 c 實現(xiàn)面向?qū)ο蟮?,其? struct 起到了非常重要的作用, struct 可以把很多不一樣的數(shù)據(jù)類型統(tǒng)一成一個整體去使用。

#include "stdafx.h"

#include "stdio.h"

 

struct str_cpu{

      int age;

      char * name;

      double f;

}str_t;

 

 

int main ( int argc,  char * argv[])

{

     str_t.age  = 10 ;

     str_t.name  = "Linux" ;

     str_t.f  = 1.077 ;

 

     printf( "str_t.age %d str_t.name %s str_t.f %f\n" ,str_t.age,str_t.name,str_t.f);

      return ;

}

跟枚舉一樣 strcpu 這個指的是結(jié)構(gòu)體花括號里面的所有東西,結(jié)構(gòu)體變量名字的大小是花括號里面所有變量大小的總和,你可以用 sizeof(strcpu) 看看它的大小, str_cpu 的大小是里面大小的總和( 16 個字節(jié)),但是枚舉類型那個名字的大小卻不一樣,只有他自己的大?。? 4 個字節(jié))。

#include "stdio.h"

 

int add ( int a, int b)

{

      return (a + b);

}

 

typedef struct str_cpu{

      int age;

      char * name;

      double f;

      int ( * func)( int , int );

}str_t;

 

str_t m_str_t;

str_t * str_p  = & m_str_t;

 

int main ( int argc,  char * argv[])

{

     

     m_str_t.age  = 10 ;

     m_str_t.name  = "Linux" ;

     m_str_t.f  = 1.077 ;

     m_str_t.func  = add;

 

     

     printf( "%d %d %s %f\n" ,m_str_t.age,m_str_t.func( 5 , 9 ),m_str_t.name,m_str_t.f);

     str_p -> age  = 12 ;

 

     printf( "str_p->age = %d\n" ,str_p -> age);

     

      return ;

}

union  數(shù)據(jù)類型

union 數(shù)據(jù)類型關(guān)鍵字的用法與 struct 的用法非常相似, union 維護(hù)足夠多的空間來放置成員的一種。

union 中,所有的數(shù)據(jù)成員公用一個空間,同一個時間只能存儲其中一個數(shù)據(jù)成員,所有成員變量的起始地址都是一樣的

#include "stdio.h"

 

union CpuMachine

{

     char name;

     int number;

     char * str;

     double time;

}UnionCpu;

 

int main ( int argc,  char * argv[])

{

     printf( "UnionCpu %d double %d\n" , sizeof (UnionCpu), sizeof ( double ));

     ret

urn ;

}

看上面的例子, union 最大的數(shù)據(jù)是 double , 所以 CpuMachine 的長度也是 double 的長度。

c語言深度解剖(數(shù)據(jù)類型關(guān)鍵字)

但是在內(nèi)存里如何組織這個大小的呢?

我們用一個視頻來體驗一下下面的代碼

#include "stdio.h"

 

union CpuMachine

{

     char name;

     int number;

     char * str;

     double time;

}UnionCpu;

 

int main ( int argc,  char * argv[])

{

     UnionCpu.name  = 0x55 ;

     UnionCpu.number  = 500 ;

     UnionCpu.str  = "Microsoft Visual" ;

     UnionCpu.time  = 1.5678 ;

 

     printf( "UnionCpu %d double %d\n" , sizeof (UnionCpu), sizeof ( double ));

      return ;

}

每次單步執(zhí)行之后,共用體之后的值把之前的值給覆蓋了,一個時間點后,共用體只能保存一個值。

 

問題:

1 、數(shù)據(jù)類型是有不同大小的格子來組成的,那么不同的數(shù)據(jù)類型型格子保存在哪里呢?是由誰來決定的呢?

2 、說下下面代碼的輸出是多少?

#include "stdio.h"

 

union CpuMachine

{

     int i;

     char array[ 2 ];

}UnionCpu;

 

int main ( int argc,  char * argv[])

{

     UnionCpu.array[ = 0x55 ;

     UnionCpu.array[ 1 = 0x33 ;

 

     printf( "i 0x%x\n" ,UnionCpu.i);

      return ;

}

 

看完覺得有收獲的,請幫忙點贊支持


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI