您好,登錄后才能下訂單哦!
1. 前面說點話
上一個章節
嵌入式 Linux : c 語言深度解剖(入門篇)
zhuanlan.zhihu.com
寫完后,很多看完的人都想把我按在地上摩擦,咬牙切齒不足解恨,但是也有很多人表示支持,在此,鄙人表示感謝。
這個章節說下 C 語言的關鍵字
我很想好好說下這個章節,主要是很多人不知道數據如何在內存里面存儲的,而且什么是內存,很多初學者也不理解,內存可以理解成很多很多個格子,比如 1G 的內存,就有 1024x1024x1024 byte 個格子,每個格子里面都有 8 個小格子,而且每個格子都有自己的編號,這樣想就沒那么復雜了,數據類型就是把各種各樣的數據保存在這些格子里面。
如何存?怎么存?就跟不同的數據類型有關系了
什么是關鍵字?
C 語言有多少個關鍵字?
1 、關鍵字要跟編譯器聯系起來,比如 int 關鍵字,我寫了個 ( int i = 0;) 編譯器就知道 int 這個家伙是認識的,編譯器就會給 int 修飾的變量分配一個房子,比如說這個房子有四個字節。
2 、 C 語言有 32 個關鍵字
2. C 語言的關鍵字(數據類型關鍵字)
數據類型關鍵字一共有 12 個,分別是下面
字符類型
(1) char :聲明字符型變量或函數
數值類型
(1) double :聲明雙精度變量或函數
(2) float :聲明浮點型變量或函數
(3) int : 聲明整型變量或函數
(4) long :聲明長整型變量或函數
(5) short :聲明短整型變量或函數
構造類型
(1) enum :聲明枚舉類型
(2) struct :聲明結構體變量或函數
(3) union :聲明聯合數據類型
有符號型和無符號型
(1) unsigned :聲明無符號類型變量或函數
(2) signed :聲明有符號類型變量或函數
什么是數據類型?
我相信很多人有疑問,或者很多人自信滿滿覺得自己對數據類型非常懂,在我看來就是由不同的格子組成的,最最最基本的數據類型是 char ,char 數據類型就有一個格子(一個字節),像下面這樣
char 數據類型的一個格子
先說 char 數據類型
這個格子能裝多少東西呢?這是我們最想知道的,編譯器告訴你這個格子可以裝二進制數 0B11111111, 里面有 8 個小格子,每個格子里面的東西是未知的。
<img src="https://pic4.zhimg.com/v2-1d8e0ca353ee26aa6a1411a0a3ff849f_b.jpg" data-size="normal" data-rawwidth="84" data-rawheight="88" width="84">
一個格子里面裝的東西示意圖
如果里面裝的是 0B11111111, 那這個格子應該是這個樣子的,對應的十進制就是 255
上面說了 char, 下面說 unsigned 和 signed
上面說了,一個大格子里面有 8 個小格子,但是 8 個小格子是有順序編號的,就是 0~7
比如一個數字 0B 11111111 ,這個我們都知道是 =256 ,
定義
無符號數( unsigned )無符號數只能表示非負數( 及正數)。
有符號數( signed )可以表示任何類型規定范圍內的數。
8 個小格子,我們需要有一個格子來告訴編譯器,這個大格子裝的數據是有符號型的還是無符號類型。編譯器指定最高位的格子第 8 個格子表示符號位
所以
unsigned char i;
表示的大小是 0~255 ,一共 256 個數字
signed char i;
表示的大小是 - ~ =-128~127 ,其中包括 ,也是 256 個數字
小例子
#include "stdafx.h"
int main ( int argc, char * argv[])
{
unsigned char i = ;
signed char j = ;
int k = ;
for (k = ;k < 300 ;k ++ )
{
i ++ ;
j ++ ;
printf( "%4d %4d\t" ,i,j);
}
return ;
}
從圖上可以看到, j 最大值是 127 , i 最小值是 , i 最大值可以達到 255 , j 最小值是 -128 。
變量在內存里怎么保存的,看看下面這個圖片
我們上面把 char unsigned signed 搞定之后,我們再來看看其他的數據類型
數值類型
(1) double :聲明雙精度變量或函數
(2) float :聲明浮點型變量或函數
(3) int : 聲明整型變量或函數
(4) long :聲明長整型變量或函數
(5) short :聲明短整型變量或函數
既然我們知道了 char 是一個格子,那么 double , float,int,long,short 是多少個格子呢?
這時候,我們就需要用到一個關鍵字 sezeof ,這個關鍵字是用來確定對象的大小的,然后我們把上面的代碼改一下
#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 ;
}
輸出如圖
所以我們可以知道
int 類型和 long,float 類型的格子大小如下
double 類型的格子大小如下
short 類型的格子大小如下
char 類型的格子大小如下
好了,到這里了,大家想想看
char char i = 0 ;
i 占領的格子大小有多少呢?有沒有這樣的寫法呢?
看上面的圖片, char char i =0; 是編譯不通過的,但是你想過 int int ,long long ,short short,long double 呢?
為什么會編譯出錯呢?
說太多會有別人說我裝逼厲害,有一種東西叫做編譯器,編譯器就像我們人類的法律一樣,規定什么可以做什么是違法的,人類有很多種國家的法律,有些國家的法律允許一個老公娶幾個老婆,當然,編譯器也有很多個,這個自行百度。
說完數值數據類型,下面就開始說
構造類型
(1) enum :聲明枚舉類型
(2) struct :聲明結構體變量或函數
(3) union :聲明聯合數據類型
先說枚舉類型 enum
enum union_type_age{
UNION_AGE_1 = 10 ,
UNION_AGE_2,
UNION_AGE_3
}union_var_age;
enum 是關鍵字, union_type_age 說明是這個整體,是這個枚舉變量的類型,就像一個戶口本,有一個戶主的名字一樣,比如小明家的爸爸叫做小寶,小寶是小明家的戶主,別人會這樣說,小寶家的小明,小寶家的 XX 之類的。
里面的 UNION_AGE_1=10, UNION_AGE_2, UNION_AGE_3 是這個枚舉類型的數值,它們是 const 常數類型的,只能在初始化的時候取設定它的值。
union_var_age 是枚舉類型的變量,它的值只能取花括號里面的數據。
用下面的一個小程序理解上面的內容,不理解的請留言
#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 ;
}
再說結構體 struct 數據類型
這個關鍵字的數據類型太厲害了,學過 C++ 都知道 C++ 是面向對象的語言,但是 linux 內核下面有很多通過 c 實現面向對象的,其中 struct 起到了非常重要的作用, struct 可以把很多不一樣的數據類型統一成一個整體去使用。
#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 這個指的是結構體花括號里面的所有東西,結構體變量名字的大小是花括號里面所有變量大小的總和,你可以用 sizeof(strcpu) 看看它的大小, str_cpu 的大小是里面大小的總和( 16 個字節),但是枚舉類型那個名字的大小卻不一樣,只有他自己的大小( 4 個字節)。
#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 數據類型
union 數據類型關鍵字的用法與 struct 的用法非常相似, union 維護足夠多的空間來放置成員的一種。
在 union 中,所有的數據成員公用一個空間,同一個時間只能存儲其中一個數據成員,所有成員變量的起始地址都是一樣的
#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 最大的數據是 double , 所以 CpuMachine 的長度也是 double 的長度。
但是在內存里如何組織這個大小的呢?
我們用一個視頻來體驗一下下面的代碼
#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 ;
}
每次單步執行之后,共用體之后的值把之前的值給覆蓋了,一個時間點后,共用體只能保存一個值。
問題:
1 、數據類型是有不同大小的格子來組成的,那么不同的數據類型型格子保存在哪里呢?是由誰來決定的呢?
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 ;
}
看完覺得有收獲的,請幫忙點贊支持
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。