真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C語言關(guān)鍵字(三)

這篇文件繼續(xù)講解 C 語言關(guān)鍵字

扎魯特旗網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),扎魯特旗網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為扎魯特旗上千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的扎魯特旗做網(wǎng)站的公司定做!

想問大家一個(gè)問題,什么是聲明什么是定義?

舉個(gè)例子:

A)int i ;

B)extern int i ; ( 關(guān)于 extern ,后面解釋 )

哪個(gè)是定義?哪個(gè)是聲明?或者都是定義或者都是聲明?

什么是定義: 所謂的定義就是 ( 編譯器 ) 創(chuàng)建一個(gè)對(duì)象,為這個(gè)對(duì)象分配一塊內(nèi)存并給它取上一個(gè)名字,這個(gè)名字就是我們經(jīng)常所說的變量名或?qū)ο竺5⒁?,這個(gè)名字一旦和這塊內(nèi)存匹配起來,它們就同生共死,終生不離不棄。并且這塊內(nèi)存的位置也不能被改變。一個(gè)變量或?qū)ο笤谝欢ǖ膮^(qū)域內(nèi)(比如函數(shù)內(nèi),全局等)只能被定義一次,如果定義多次,編譯器會(huì)提示你重復(fù)定義同一個(gè)變量或?qū)ο蟆?/p>

什么是聲明: 有兩重含義,如下:

第一重含義:告訴編譯器,這個(gè)名字已經(jīng)匹配到一塊內(nèi)存上了,(就比如你拿出結(jié)婚證告訴別人,我已經(jīng)和別的內(nèi)存塊結(jié)婚了,請(qǐng)不要再勾搭我了)。

第二重含義:告訴編譯器,我這個(gè)名字我先預(yù)定了,別的地方再也不能用它來作為變量名或?qū)ο竺?。(這個(gè)就有點(diǎn)耍賴,你拿著一個(gè)假的結(jié)婚證告訴別人,我已經(jīng)結(jié)婚了,但是實(shí)際上,你還沒有妹子,還沒有分配內(nèi)存空間)。

好,這樣一解釋,我們可以很清楚的判斷 :A) 是定義; B) 是聲明。

那他們的區(qū)別也很清晰了。記住, 定義聲明最重要的區(qū)別:定義創(chuàng)建了對(duì)象并為這個(gè)對(duì)象一塊內(nèi)存,而聲明的時(shí)候是沒有分配內(nèi)存空間的。

 

1 ,不需要記住的關(guān)鍵字 ----auto

 

auto :他太普通了,你就當(dāng)它不存在吧。編譯器在默認(rèn)的缺省情況下,所有變量

都是 auto  的。

 

2 ,最快的關(guān)鍵字 ---- register

 

register :這個(gè)關(guān)鍵字請(qǐng)求編譯器盡可能的將變量存在 CPU  內(nèi)部寄存器中而不是通過內(nèi)

存尋址訪問以提高效率。注意是盡可能,不是絕對(duì)。你想想,一個(gè) CPU  的寄存器也就那么

幾個(gè)或幾十個(gè),你要是定義了很多很多 register  變量,它累死也可能不能全部把這些變量放

入寄存器吧,輪也可能輪不到你。

 

2.1 ,皇帝( CPU )身邊的小太監(jiān) ---- 寄存器

把 cpu 類比成為一個(gè)皇帝,那 register 就是皇帝身邊的小太監(jiān)了,不知道大家見過太監(jiān)沒有,我們看各種宮斗劇的時(shí)候,太監(jiān)是唯命是從,只要皇帝叫做什么,太監(jiān)馬上就去做,速度之快令人瞠目結(jié)舌,也就是因?yàn)樗俣瓤?,所以皇帝才配有太監(jiān),而且不止有一個(gè)太監(jiān),太監(jiān)就像一個(gè)文件中轉(zhuǎn)站,把下面人的折子拿給皇帝批閱。

所以太監(jiān)的特點(diǎn)是

1 、響應(yīng)速度快

2 、數(shù)量少,只給皇帝工作

3 、價(jià)格貴

 

 

2.2 ,使用 register 修飾符的注意點(diǎn)

 

雖然寄存器的速度非常快,但是使用 register  修飾符也有些限制的: register  變量必須是能被 CPU  寄存器所接受的類型。意味著 register  變量必須是一個(gè)單個(gè)的值,并且其長(zhǎng)度應(yīng)小于或等于整型的長(zhǎng)度。 而且 register  變量可能不存放在內(nèi)存中,所以不能用取址運(yùn)算符 “&” 來獲取 register  變量的地址。

3 、確定位置的關(guān)鍵字 ----static

3.1 、 static  修飾變量

修飾靜態(tài)全局變量:作用域僅限制于被定義的文件中,其他文件即使用 extern 聲明也沒有辦法使用,作用域從定義之處開始,到文件結(jié)尾處,在定義之前的代碼不能使用。本文件可以在之前加 extern  ,不過這樣還不如直接在頂端定義。

 

靜態(tài)全局變量:在函數(shù)體里面定義的,就只能在函數(shù)里面使用了,由于 static 定義的變量存在靜態(tài)區(qū),改函數(shù)執(zhí)行結(jié)束,變量的值還是存在,不會(huì)銷毀,下次該函數(shù)調(diào)用時(shí), static 定義的變量值是上一次調(diào)用時(shí)候的值。

3.2 、 static 修飾函數(shù)

在函數(shù)前面加 static 表示函數(shù)成為靜態(tài)函數(shù),表示該函數(shù)的作用域僅限于定義處到文件結(jié)尾。如果全局函數(shù)有一個(gè)函數(shù)名字和靜態(tài)函數(shù)一樣的名字,編譯器不會(huì)報(bào)錯(cuò),使用本文件的靜態(tài)函數(shù)運(yùn)行。

#include

 

static int j;

 

void func1 ( void )

{

      static int = ;

     i ++ ;

     printf( "i = %d\n" , i);

}

 

void func2 ( void )

{

     j  = ;

     j ++ ;

     printf( "j = %d\n" , j);

}

 

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

{

      int = ;

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

     {

         func1();

         func2();

         printf( "\n" );

     }

      return ;

}

大家運(yùn)行上面代碼加深下對(duì) static 的理解

 

4 、大喇叭關(guān)鍵字 ----extern

上面有一個(gè)例子已經(jīng)說到了 extern,extern 就像一個(gè)大喇叭一樣,他不分配內(nèi)存,就是不討老婆,但是總是跟別人說,誰誰娶媳婦了,這個(gè)標(biāo)識(shí)符就定義了,這個(gè)函數(shù)被定義了,如此如此,不過這個(gè)大喇叭非常有用,比如他可以跟編譯器說,這個(gè)家伙已經(jīng)討老婆了,你可以用他生孩子了,就不要再讓他二婚了。

既然 extern 不能給別人發(fā)結(jié)婚證,那么下面這個(gè)

extern int i = 10;

是否有問題?

不能發(fā)結(jié)婚證,就是不能分配內(nèi)儲(chǔ)存,沒有內(nèi)存怎么把 10 存下來?所以肯定是錯(cuò)的。

 

5 、讓 cpu 最累的關(guān)鍵字 ----volitile

volitile 這個(gè)關(guān)鍵字讓 cpu 非常累,每次運(yùn)行到他的位置,都要去內(nèi)存重新確定他的值,在中斷的使用的變量最好用這個(gè)關(guān)鍵字修飾,因?yàn)橹袛嗟淖兞磕悴恢朗裁磿r(shí)候會(huì)被改變, volatile 的變量是說這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。說白了就是不能讓 cpu 偷懶,所以說是類似老大 CPU 了。

 

6 、只能讀的關(guān)鍵字 ----const

const 可以理解為別人只能來讀我的值,不能改變我,有的人寫代碼加上這個(gè)就是擔(dān)心自己的值被改變,比如 const int i =5; 下一次, i =6; 這就是有問題的, i  的值已經(jīng)確定了,就像 define 一樣( 不過 define 不是關(guān)鍵字 )。

/*************************************************************************

    > File Name: const.c

    > Author:           

    > Mail:             

    > Created Time: Mon 29 Oct 2018 02:33:19 PM CST

 ************************************************************************/

                        

#include        

#define M 3             

const int = 5 ;        

                        

void main ( void )        

{                       

    printf( "%p\n" , & N);

     int = M;          

     int = N;          

    printf( "%p\n" , & N);                                                                                                

     int = M;          

     int = N;          

    printf( "%p %p %p %p\n" , & i, & j, & x, & y);

    printf( "%d %d %d %d\n" ,i,j,x,y);

}         

7 、不色不空的關(guān)鍵字 ----void

大家可以看看 void  和 void*  ,誰是色,誰是空呢? void  表示這個(gè)是空的,什么都沒有,比如 void i;  我們定義一個(gè)空的 i ,這就有問題了,這個(gè) i 編譯器到底要不要給他分配空間呢?就是這樣的情況,編譯器報(bào)錯(cuò)了,你搞什么飛機(jī)給我一個(gè)空的東西還想讓我給你討老婆。

但是 void  不一樣, void  * 表示所有類型的指針,這就是色啊,女人都想入非非。

說明: 既然提供了 void 的這兩種用法,就去運(yùn)用。即函數(shù)沒返回值就將其返回值類型寫為 void ,函數(shù)沒有形參就將其形參寫為 void 。不了解編譯器默認(rèn)操作時(shí),不要依賴。即使了解其默認(rèn)操作,也別依賴,因?yàn)榭隙ㄓ腥瞬涣私獾?,這樣別人就看不懂你的代碼了。

大家看看這個(gè)是否正確

add(int a,int b)

{

    return (a+b);

}

下面兩個(gè)函數(shù)就是用 void* 作為返回值

memcpy   

原型: extern void *memcpy(void *dest, void *src, unsigned int count); 

用法: #include 

功能:由 src 所指內(nèi)存區(qū)域復(fù)制 count 個(gè)字節(jié)到 dest 所指內(nèi)存區(qū)域。

說明: src 和 dest 所指內(nèi)存區(qū)域不能重疊,函數(shù)返回指向 dest 的指針。

注意:與 strcpy 相比, memcpy 并不是遇到 '\0' 就結(jié)束,而是一定會(huì)拷貝完 n 個(gè)字節(jié)。

 

memset

原型: extern void *memset(void *buffer, int c, int count);

用法: #include

功能:把 buffer 所指內(nèi)存區(qū)域的前 count 個(gè)字節(jié)設(shè)置成字符 c 。

說明:返回指向 buffer 的指針。

8 return  關(guān)鍵字

return  關(guān)鍵字終止一個(gè)函數(shù)并返回一個(gè)值。

#include "stdio.h"

 

add( int a, int b)

{

     return (a + b);

}

 

char * str( void )

{

     char * strc  = "This is c\n" ;

     return strc;

}

 

main( void )

{

    printf( "%d\n" ,add( 1 , 4 ));

    printf( "%s\n" ,str);

     return ;

}

看看上面這個(gè)函數(shù)的輸出,會(huì)有陷阱的

9 、柔性數(shù)組

講了很多關(guān)鍵字,現(xiàn)在討論一個(gè)酷的東西,以后也會(huì)經(jīng)常用到,柔性數(shù)組是可以自由變化長(zhǎng)度的數(shù)組,對(duì)開發(fā)上來說是非常有用的。

C99 中,結(jié)構(gòu)體的最后一個(gè)元素允許是未知大小的數(shù)組,這就叫做柔性數(shù)組成員,但結(jié)構(gòu)體的柔性數(shù)組成員前面必須至少一個(gè)其他成員。

#include

typedef struct _SoftArray{

     int len;

     int array[];

}SoftArray;

 

int main ()

{

     int len  = 10 ;

 

    printf( "The struct's size is %d\n" , sizeof (SoftArray));

}

C語言關(guān)鍵字(三)

我們可以看出, _SoftArray 結(jié)構(gòu)體的大小是 4 ,顯然,在 32 位操作系統(tǒng)下一個(gè) int 型變量大小剛好為 4 ,也就說結(jié)構(gòu)體中的數(shù)組沒有占用內(nèi)存。為什么會(huì)沒有占用內(nèi)存,我們平時(shí)用數(shù)組時(shí)不時(shí)都要明確指明數(shù)組大小的嗎?但這里卻可以編譯通過呢?這就是我們常說的動(dòng)態(tài)數(shù)組,也就是柔性數(shù)組。

#include

#include

typedef struct _SoftArray{

int len;

int array[];

}SoftArray;

int main ()

{

     int len = 10 ,i = ;

    

    SoftArray  * p = (SoftArray * )malloc( sizeof (SoftArray) +sizeof ( int ) * len);

    p -> len = len;

    

     for (i = ;i < p -> len;i ++ )

   {

        p -> array[i] = i + 1 ;

    }

     for (i = ;i < p -> len;i ++ )

   {  

        printf( "%d\n" ,p -> array[i]);

    }

 

    free(p);

 

     return ;

}

C語言關(guān)鍵字(三)

這代碼的作用是用柔性數(shù)組動(dòng)態(tài)創(chuàng)建數(shù)組并輸出數(shù)組內(nèi)容,這里我就直接解釋解釋這兩句代碼

    SoftArray * = (SoftArray * )malloc( sizeof (SoftArray)  + sizeof ( int * 10 );

       p -> len  = 10 ;

第一句,主要是根據(jù)你要定義的數(shù)組長(zhǎng)度和數(shù)據(jù)類型以及柔性數(shù)組本身的大小來開辟一塊內(nèi)存空間給柔性數(shù)組,第二個(gè)是定義 len 的長(zhǎng)度,便于確定循環(huán)打印輸出


網(wǎng)站題目:C語言關(guān)鍵字(三)
文章鏈接:http://weahome.cn/article/iieosi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部