久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C語言中的const

 昵稱65078105 2019-07-07

今天探討const,,首先來說是將變量常量化,。為什么要將變量常量化,原因有諸多好處有諸多,。比如可以使數(shù)據(jù)更加安全不會(huì)被修改,!

但是這個(gè)詞有幾個(gè)點(diǎn)要注意,那就是他究竟修飾了誰,?

1.const int a/ int const a

如果我們給出 const int  a;你應(yīng)該知道這是將a常量化了,,但是為什么那?那是因?yàn)閕nt 和const 都作為一個(gè)類型限定詞,,有相同的地位。

所以你也可以寫成 int const a;似乎這樣更加好理解,!當(dāng)然這都不難,,難點(diǎn)在哪里哪?當(dāng)然此時(shí)你如果定義指針也是可以修改的,,但是會(huì)報(bào)警告,!當(dāng)然強(qiáng)制類型轉(zhuǎn)換后警告也不會(huì)報(bào)了!

const int a; int *pi=(int*)&a; *pi=19;[針對(duì)gcc]

 

const修飾的變量真的不能改嗎,?
(1)課堂練習(xí)說明:const修飾的變量其實(shí)是可以改的(前提是gcc環(huán)境下),。
(2)在某些單片機(jī)環(huán)境下,const修飾的變量是不可以改的,。const修飾的變量到底能不能真的被修改,,取決于具體的環(huán)境,C語言本身并沒有完全嚴(yán)格一致的要求,。
(3)在gcc中,,const是通過編譯器在編譯的時(shí)候執(zhí)行檢查來確保實(shí)現(xiàn)的(也就是說const類型的變量不能改是編譯錯(cuò)誤,不是運(yùn)行時(shí)錯(cuò)誤,。)所以我們只要想辦法騙過編譯器,,就可以修改const定義的常量,而運(yùn)行時(shí)不會(huì)報(bào)錯(cuò),。
(4)更深入一層的原因,,是因?yàn)間cc把const類型的常量也放在了data段,其實(shí)和普通的全局變量放在data段是一樣實(shí)現(xiàn)的,,只是通過編譯器認(rèn)定這個(gè)變量是const的,,運(yùn)行時(shí)并沒有標(biāo)記const標(biāo)志,所以只要騙過編譯器就可以修改了,。

 

const究竟應(yīng)該怎么用
(1)const是在編譯器中實(shí)現(xiàn)的,,編譯時(shí)檢查,并非不能騙過,。所以在C語言中使用const,,就好象是 一種道德約束而非法律約束,所以大家使用const時(shí)更多是傳遞一種信息,,就是告訴編譯器,、也告訴讀程序的人,這個(gè)變量是不應(yīng)該也不必被修改的,。

 

2.const int (*p);/int const (*p);

const int* p; 這是修飾了誰那,?其實(shí)我們可以這樣想,如果我們把int 拿出來 也就是 等價(jià)于
const int (*p);
int const (*p);

由此我們可以看出來這是修飾了*p啊,,也就是指向的內(nèi)容不可以改變,,但是地址是可以改變的,。但是我們?nèi)绻麑憺閕nt const *p 似乎就非常好理解了。就是修飾了*p

既然修飾了*p那就是指向的值是不能賦值了,。換句話說就是*p不可賦值,。

3.int * const p

那么如何聲明一個(gè)自身是常量指針呢?方法是讓const盡可能的靠近p,下面的這個(gè)就是

int * const p;這個(gè)夠靠近了,,當(dāng)然這個(gè)就是修飾的p,就是修飾的地址,,換句話說,,地址你只能賦值一次。

 

 4.const int *const p 

這個(gè)相對(duì)來說是最簡(jiǎn)單的,,因?yàn)檫@個(gè)是將地址和內(nèi)容都常量化,,有了前面的鋪墊,我想是可以看出來的吧,!哈哈哈哈

最后談?wù)勎乙姷降腸onst 比如函數(shù)中strcpy ()

我們可以看到源地址的內(nèi)容是不可以改變的,,還是很合理的對(duì)吧。因?yàn)槟阕址截?,拷貝過程是把源字符串的內(nèi)容放到目的字符串,,那么源應(yīng)該是只讀的。不能說,,讓你抄一下我的作業(yè)

我的作業(yè)讓你搞廢了,!談?wù)勆厦娴膸讞l如何記憶 就是看const是不是緊挨著p如果是那就是修飾地址。


 

下面是轉(zhuǎn)載 博客 寫的非常不錯(cuò)http://blog.csdn.net/sddzycnqjn/article/details/7289712

const在C語言中算是一個(gè)比較新的描述符,,我們稱之為常量修飾符,,意即其所修飾
的對(duì)象為常量(immutable)。


我們來分情況看語法上它該如何被使用,。


1,、函數(shù)體內(nèi)修飾局部變量。
例:
void func(){
const int a=0;
}


首先,,我們先把const這個(gè)單詞忽略不看,,那么a是一個(gè)int類型的局部自動(dòng)變量,
我們給它賦予初始值0,。


然后再看const.


const作為一個(gè)類型限定詞,,和int有相同的地位。
const int a;
int const a;
是等價(jià)的,。于是此處我們一定要清晰的明白,,const修飾的對(duì)象是誰,是a,和int沒
有關(guān)系,。const 要求他所修飾的對(duì)象為常量,,不可被改變,,不可被賦值,不可作為左值(l-value),。
這樣的寫法也是錯(cuò)誤的,。
const int a;
a=0;
這是一個(gè)很常見的使用方式:
const double pi=3.14;
在程序的后面如果企圖對(duì)pi再次賦值或者修改就會(huì)出錯(cuò)。


然后看一個(gè)稍微復(fù)雜的例子,。
const int* p;
還是先去掉const 修飾符號(hào),。
注意,下面兩個(gè)是等價(jià)的,。
int* p;
int *p;
其實(shí)我們想要說的是,,*p是int類型。那么顯然,,p就是指向int的指針,。
同理
const int* p;
其實(shí)等價(jià)于
const int (*p);
int const (*p);
即,*p是常量,。也就是說,,p指向的數(shù)據(jù)是常量。
于是
p+=8; //合法
*p=3; //非法,,p指向的數(shù)據(jù)是常量,。


那么如何聲明一個(gè)自身是常量指針呢?方法是讓const盡可能的靠近p;
int* const p;
const右面只有p,顯然,,它修飾的是p,說明p不可被更改,。然后把const去掉,可以
看出p是一個(gè)指向 int形式變量的指針,。
于是
p+=8; //非法
*p=3; //合法


再看一個(gè)更復(fù)雜的例子,,它是上面二者的綜合
const int* const p;
說明p自己是常量,且p指向的變量也是常量,。
于是
p+=8; //非法
*p=3; //非法


const 還有一個(gè)作用就是用于修飾常量靜態(tài)字符串,。
例如:
const char* name=David;
如果沒有const,我們可能會(huì)在后面有意無意的寫name[4]='x'這樣的語句,這樣會(huì)
導(dǎo)致對(duì)只讀內(nèi)存區(qū)域的賦值,,然后程序會(huì)立刻異常終止,。有了 const,這個(gè)錯(cuò)誤就
能在程序被編譯的時(shí)候就立即檢查出來,這就是const的好處,。讓邏輯錯(cuò)誤在編譯
期被發(fā)現(xiàn),。


const 還可以用來修飾數(shù)組
const char s[]=David;
與上面有類似的作用。


2,、在函數(shù)聲明時(shí)修飾參數(shù)
來看實(shí)際中的一個(gè)例子,。
NAME
memmove -- copy byte string


LIBRARY
Standard C Library (libc, -lc)


SYNOPSIS
#include


void *
memmove(void *dst, const void *src, size_t len);


這是標(biāo)準(zhǔn)庫(kù)中的一個(gè)函數(shù),用于按字節(jié)方式復(fù)制字符串(內(nèi)存),。
它的第一個(gè)參數(shù),,是將字符串復(fù)制到哪里去(dest),是目的地,,這段內(nèi)存區(qū)域必須
是可寫。
它的第二個(gè)參數(shù),,是要將什么樣的字符串復(fù)制出去,,我們對(duì)這段內(nèi)存區(qū)域只做讀
取,不寫,。
于是,,我們站在這個(gè)函數(shù)自己的角度來看,src 這個(gè)指針,,它所指向的內(nèi)存內(nèi)所存
儲(chǔ)的數(shù)據(jù)在整個(gè)函數(shù)執(zhí)行的過程中是不變,。于是src所指向的內(nèi)容是常量。于是就
需要用const修飾,。
例如,我們這里這樣使用它,。
const char* s=hello;
char buf[100];
memmove(buf,s,6); //這里其實(shí)應(yīng)該用strcpy或memcpy更好


如果我們反過來寫,,
memmove(s,buf,6);
那么編譯器一定會(huì)報(bào)錯(cuò)。事實(shí)是我們經(jīng)常會(huì)把各種函數(shù)的參數(shù)順序?qū)懛?。事?shí)是編
譯器在此時(shí)幫了我們大忙,。如果編譯器靜悄悄的不報(bào)錯(cuò),(在函數(shù)聲明處去掉
const即可),那么這個(gè)程序在運(yùn)行的時(shí)候一定會(huì)崩潰,。


這里還要說明的一點(diǎn)是在函數(shù)參數(shù)聲明中const一般用來聲明指針而不是變量本身,。
例如,上面的size_t len,在函數(shù)實(shí)現(xiàn)的時(shí)候可以完全不用更改len的值,,那么是否
應(yīng)該把len也聲明為常量呢,?可以,可以這么做,。我們來分析這么做有什么優(yōu)劣,。
如果加了const,那么對(duì)于這個(gè)函數(shù)的實(shí)現(xiàn)者,可以防止他在實(shí)現(xiàn)這個(gè)函數(shù)的時(shí)候修
改不需要修改的值(len),這樣很好,。
但是對(duì)于這個(gè)函數(shù)的使用者,,
1。這個(gè)修飾符號(hào)毫無意義,,我們可以傳遞一個(gè)常量整數(shù)或者一個(gè)非常量整數(shù)過
去,,反正對(duì)方獲得的只是我們傳遞的一個(gè)copy。
2,。暴露了實(shí)現(xiàn),。我不需要知道你在實(shí)現(xiàn)這個(gè)函數(shù)的時(shí)候是否修改過len的值。


所以,,const一般只用來修飾指針,。


再看一個(gè)復(fù)雜的例子
int execv(const char *path, char *const argv[]);
著重看后面這個(gè),,argv.它代表什么。
如果去掉const,我們可以看出
char * argv[];
argv是一個(gè)數(shù)組,,它的每個(gè)元素都是char *類型的指針,。
如果加上const.那么const修飾的是誰呢?他修飾的是一個(gè)數(shù)組,,argv[],意思就是
說這個(gè)數(shù)組的元素是只讀的,。那么數(shù)組的元素的是什么類型呢?是char *類型的指
針.也就是說指針是常量,,而它指向的數(shù)據(jù)不是,。
于是
argv[1]=NULL; //非法
argv[0][0]='a'; //合法




3、全局變量,。
我們的原則依然是,,盡可能少的使用全局變量。
我們的第二條規(guī)則 則是,,盡可能多的使用const,。
如果一個(gè)全局變量只在本文件中使用,那么用法和前面所說的函數(shù)局部變量沒有什
么區(qū)別,。
如果它要在多個(gè)文件間共享,,那么就牽扯到一個(gè)存儲(chǔ)類型的問題。


有兩種方式,。
1.使用extern
例如
/* file1.h */
extern const double pi;
/* file1.c */
const double pi=3.14;
然后其他需要使用pi這個(gè)變量的,,包含file1.h
#include file1.h
或者,自己把那句聲明復(fù)制一遍就好,。
這樣做的結(jié)果是,,整個(gè)程序鏈接完后,所有需要使用pi這個(gè)變量的共享一個(gè)存儲(chǔ)區(qū)域,。


2.使用static,靜態(tài)外部存儲(chǔ)類
/* constant.h */
static const pi=3.14;
需要使用這個(gè)變量的*.c文件中,,必須包含這個(gè)頭文件。
前面的static一定不能少,。否則鏈接的時(shí)候會(huì)報(bào)告說該變量被多次定義,。
這樣做的結(jié)果是,每個(gè)包含了constant.h的*.c文件,,都有一份該變量自己的copy,
該變量實(shí)際上還是被定義了多次,,占用了多個(gè)存儲(chǔ)空間,不過在加了static關(guān)鍵字
后,,解決了文件間重定義的沖突,。
壞處是浪費(fèi)了存儲(chǔ)空間,導(dǎo)致鏈接完后的可執(zhí)行文件變大。但是通常,,這個(gè),,小小
幾字節(jié)的變化,不是問題,。
好處是,,你不用關(guān)心這個(gè)變量是在哪個(gè)文件中被初始化的。




最后,,說說const的作用,。
const 的好處,是引入了常量的概念,,讓我們不要去修改不該修改的內(nèi)存,。直接的
作用就是讓更多的邏輯錯(cuò)誤在編譯期被發(fā)現(xiàn)。所以我們要盡可能的多使用const,。
但是很多人并不習(xí)慣使用它,,更有甚者,是在整個(gè)程序 編寫/調(diào)試 完后才補(bǔ)
const,。如果是給函數(shù)的聲明補(bǔ)const,尚好,。如果是給 全局/局部變量補(bǔ)const,那
么……那么,為時(shí)已晚,,無非是讓代碼看起來更漂亮了。關(guān)于const的使用,,曾有一
個(gè)笑話說,,const 就像安全套,事前要記牢,。如果做完后才想起來該用而忘了用,,
呵呵……呵呵……

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多