freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

運算符的種類c語言的運算符可分為以下幾類-資料下載頁

2025-08-05 17:20本頁面
  

【正文】 (pa+1)。//訪問了第1號單元*(pa+2)。//訪問了第2號單元從格式上看倒是與通過指針訪問結(jié)構(gòu)成員的不正規(guī)方法的格式一樣?! ∷械腃/C++編譯器在排列數(shù)組的單元時,總是把各個數(shù)組單元存放在連續(xù)的存儲區(qū)里,單元和單元之間沒有空隙。但在存放結(jié)構(gòu)對象的各個成員時,在某種編譯環(huán)境下,可能會需要字對齊或雙字對齊或者是別的什么對齊,需要在相鄰兩個成員之間加若干個填充字節(jié),這就導(dǎo)致各個成員之間可能會有若干個字節(jié)的空隙?! ∷裕诶?,即使*pstr訪問到了結(jié)構(gòu)對象ss的第一個成員變量a,也不能保證*(pstr+1)就一定能訪問到結(jié)構(gòu)成員b。因為成員a和成員b之間可能會有若干填充字節(jié),說不定*(pstr+1)就正好訪問到了這些填充字節(jié)呢。這也證明了指針的靈活性。要是你的目的就是想看看各個結(jié)構(gòu)成員之間到底有沒有填充字節(jié),嘿,這倒是個不錯的方法。過指針訪問結(jié)構(gòu)成員的正確方法應(yīng)該是象例十二中使用指針ptr的方法。  指針和函數(shù)的關(guān)系  可以把一個指針聲明成為一個指向函數(shù)的指針。intfun1(char*,int)。int(*pfun1)(char*,int)。pfun1=fun1。........inta=(*pfun1)(abcdefg,7)。//通過函數(shù)指針調(diào)用函數(shù)。可以把指針作為函數(shù)的形參。在函數(shù)調(diào)用語句中,可以用指針表達(dá)式來作為實參。  例十三:intfun(char*)。inta。charstr[]=abcdefghijklmn。a=fun(str)。......intfun(char*s){intnum=0。for(inti=0。i{num+=*s。s++。}returnnum。}  這個例子中的函數(shù)fun統(tǒng)計一個字符串中各個字符的ASCII碼值之和。前面說了,數(shù)組的名字也是一個指針。在函數(shù)調(diào)用中,當(dāng)把str作為實參傳遞給形參s后,實際是把str的值傳遞給了s,s所指向的地址就和str所指向的地址一致,但是str和s各自占用各自的存儲空間。在函數(shù)體內(nèi)對s進(jìn)行自加1運算,并不意味著同時對str進(jìn)行了自加1運算。指針類型轉(zhuǎn)換當(dāng)我們初始化一個指針或給一個指針賦值時,賦值號的左邊是一個指針,賦值號的右邊是一個指針表達(dá)式。在我們前面所舉的例子中,絕大多數(shù)情況下,指針的類型和指針表達(dá)式的類型是一樣的,指針?biāo)赶虻念愋秃椭羔槺磉_(dá)式所指向的類型是一樣的?! ±模骸 loatf=。  float*fptr=amp。f?! nt*p?!  ≡谏厦娴睦又?,假如我們想讓指針p指向?qū)崝?shù)f,應(yīng)該怎么搞?是用下面的語句嗎?  p=amp。f?! 〔粚?。因為指針p的類型是int*,它指向的類型是int。表達(dá)式amp。f的結(jié)果是一個指針,指針的類型是float*,它指向的類型是 float。兩者不一致,直接賦值的方法是不行的。至少在我的MSVC++,對指針的賦值語句要求賦值號兩邊的類型一致,所指向的類型也一致,其它的編譯器上我沒試過,大家可以試試。為了實現(xiàn)我們的目的,需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換:p=(int*)amp。f。如果有一個指針p,我們需要把它的類型和所指向的類型改為TYEP*TYPE, 那么語法格式是:  (TYPE*)p;  這樣強(qiáng)制類型轉(zhuǎn)換的結(jié)果是一個新指針,該新指針的類型是TYPE*,它指向的類型是TYPE,它指向的地址就是原指針指向的地址。而原來的指針p的一切屬性都沒有被修改。  一個函數(shù)如果使用了指針作為形參,那么在函數(shù)調(diào)用語句的實參和形參的結(jié)合過程中,也會發(fā)生指針類型的轉(zhuǎn)換?! ±澹簐oidfun(char*)。inta=125,b。fun((char*)amp。a)。......voidfun(char*s){charc。c=*(s+3)。*(s+3)=*(s+0)。*(s+0)=c。c=*(s+2)。*(s+2)=*(s+1)。*(s+1)=c。}}注意這是一個32位程序,故int類型占了四個字節(jié),char類型占一個字節(jié)。函數(shù)fun的作用是把一個整數(shù)的四個字節(jié)的順序來個顛倒。注意到了嗎?在函數(shù)調(diào)用語句中,實參amp。a的結(jié)果是一個指針,它的類型是int*,它指向的類型是int。形參這個指針的類型是char*,它指向的類型是char。這樣,在實參和形參的結(jié)合過程中,我們必須進(jìn)行一次從int*類型到char*類型的轉(zhuǎn)換。結(jié)合這個例子,我們可以這樣來想象編譯器進(jìn)行轉(zhuǎn)換的過程:編譯器先構(gòu)造一個臨時指針char*temp,然后執(zhí)行temp=(char*)amp。a,最后再把temp的值傳遞給s。所以最后的結(jié)果是:s的類型是char*,它指向的類型是char,它指向的地址就是a的首地址?! ∥覀円呀?jīng)知道,指針的值就是指針指向的地址,在32位程序中,指針的值其實是一個32位整數(shù)。那可不可以把一個整數(shù)當(dāng)作指針的值直接賦給指針呢?就象下面的語句:unsignedinta。TYPE*ptr。//TYPE是int,char或結(jié)構(gòu)類型等等類型。......a=20345686。ptr=20345686。//我們的目的是要使指針ptr指向地址20345686(十進(jìn)制)ptr=a。//我們的目的是要使指針ptr指向地址20345686(十進(jìn)制)編譯一下吧。結(jié)果發(fā)現(xiàn)后面兩條語句全是錯的。那么我們的目的就不能達(dá)到了嗎?不,還有辦法:unsignedinta。TYPE*ptr。//TYPE是int,char或結(jié)構(gòu)類型等等類型。......a=某個數(shù),這個數(shù)必須代表一個合法的地址;ptr=(TYPE*)a;//呵呵,這就可以了。嚴(yán)格說來這里的(TYPE*)和指針類型轉(zhuǎn)換中的(TYPE*)還不一樣。這里的(TYPE*)的意思是把無符號整數(shù)a的值當(dāng)作一個地址來看待。上面強(qiáng)調(diào)了a的值必須代表一個合法的地址,否則的話,在你使用ptr的時候,就會出現(xiàn)非法操作錯誤。  想想能不能反過來,把指針指向的地址即指針的值當(dāng)作一個整數(shù)取出來。完 全可以。下面的例子演示了把一個指針的值當(dāng)作一個整數(shù)取出來,然后再把這個整數(shù)當(dāng)作一個地址賦給一個指針:  例十六:inta=123,b。int*ptr=amp。a。char*str。b=(int)ptr。//把指針ptr的值當(dāng)作一個整數(shù)取出來。str=(char*)b。//把這個整數(shù)的值當(dāng)作一個地址賦給指針str?! ‖F(xiàn)在我們已經(jīng)知道了,可以把指針的值當(dāng)作一個整數(shù)取出來,也可以把一個整數(shù)值當(dāng)作地址賦給一個指針?! ≈羔樀陌踩珕栴}看下面的例子:  例十七:chars=39。a39。int*ptr。ptr=(int*)amp。s。*ptr=1298;  指針ptr是一個int*類型的指針,它指向的類型是int。它指向的地址就是s的首地址。在32位程序中,s占一個字節(jié),int類型占四個字節(jié)。最后一條語句不但改變了s所占的一個字節(jié),還把和s相臨的高地址方向的三個字節(jié)也改變了。這三個字節(jié)是干什么的?只有編譯程序知道,而寫程序的人是不太可能知道的。也許這三個字節(jié)里存儲了非常重要的數(shù)據(jù),也許這三個字節(jié)里正好是程序的一條代碼,而由于你對指針的馬虎應(yīng)用,這三個字節(jié)的值被改變了!這會造成崩潰性的錯誤?! ∽屛覀冊賮砜匆焕骸 ±耍骸 hara?! nt*ptr=amp。a。  ...  ...  ptr++?! ?ptr=115。  該例子完全可以通過編譯,并能執(zhí)行。但是看到?jīng)]有?第3句對指針ptr進(jìn)行自加1運算后,ptr指向了和整形變量a相鄰的高地址方向的一塊存儲區(qū)。這塊存儲區(qū)里是什么?我們不知道。有可能它是一個非常重要的數(shù)據(jù),甚至可能是一條代碼。而第4句竟然往這片存儲區(qū)里寫入一個數(shù)據(jù)!這是嚴(yán)重的錯誤。所以在使用指針時,程序員心里必須非常清楚:我的指針究竟指向了哪里。在用指針訪問數(shù)組的時候,也要注意不要超出數(shù)組的低端和高端界限,否則也會造成類似的錯誤。  在指針的強(qiáng)制類型轉(zhuǎn)換:ptr1=(TYPE*)ptr2中,如果sizeof(ptr2的類型)大于sizeof(ptr1的類型),那么在使用指針ptr1來訪問ptr2所指向的存儲區(qū)時是安全的。如果sizeof(ptr2的類型)小于sizeof(ptr1的類型),那么在使用指針 ptr1來訪問ptr2所指向的存儲區(qū)時是不安全的。至于為什么,讀者結(jié)合例十七來想一想,應(yīng)該會明白的。const在C語言中算是一個比較新的描述符,我們稱之為常量修飾符,意即其所修飾的對象為常量(immutable)。我們來分情況看語法上它該如何被使用。函數(shù)體內(nèi)修飾局部變量。例:void func(){const int a=0。}首先,我們先把const這個單詞忽略不看,那么a是一個int類型的局部自動變量,我們給它賦予初始值0。然后再看const.const作為一個類型限定詞,和int有相同的地位。const int a。int const a。是等價的。于是此處我們一定要清晰的明白,const修飾的對象是誰,是a,和int沒有關(guān)系。const 要求他所修飾的對象為常量,不可被改變,不可被賦值,不可作為左值(lvalue)。這樣的寫法也是錯誤的。const int a。a=0。這是一個很常見的使用方式:const double pi=。在程序的后面如果企圖對pi再次賦值或者修改就會出錯。然后看一個稍微復(fù)雜的例子。const int* p。還是先去掉const 修飾符號。注意,下面兩個是等價的。int* p。int *p。其實我們想要說的是,*p是int類型。那么顯然,p就是指向int的指針。同理const int* p。其實等價于const int (*p)。int const (*p)。即,*p是常量。也就是說,p指向的數(shù)據(jù)是常量。于是p+=8。 //合法*p=3。 //非法,p指向的數(shù)據(jù)是常量。那么如何聲明一個自身是常量指針呢?方法是讓const盡可能的靠近p。int* const p。const右面只有p,顯然,它修飾的是p,說明p不可被更改。然后把const去掉,可以看出p是一個指向 int形式變量的指針。于是p+=8。 //非法*p=3。 //合法再看一個更復(fù)雜的例子,它是上面二者的綜合const int* const p。說明p自己是常量,且p指向的變量也是常量。于是p+=8。 //非法*p=3。 //非法const 還有一個作用就是用于修飾常量靜態(tài)字符串。例如:const char* name=David。如果沒有const,我們可能會在后面有意無意的寫name[4]=39。x39。這樣的語句,這樣會導(dǎo)致對只讀內(nèi)存區(qū)域的賦值,然后程序會立刻異常終止。有了 const,這個錯誤就能在程序被編譯的時候就立即檢查出來,這就是const的好處。讓邏輯錯誤在編譯期被發(fā)現(xiàn)。const 還可以用來修飾數(shù)組const char s[]=David。與上面有類似的作用。在函數(shù)聲明時修飾參數(shù)來看實際中的一個例子。NAMEmemmove copy byte stringLIBRARYStandard C Library (libc, lc)SYNOPSISincludevoid *memmove(void *dst, const void *src, size_t len)。這是標(biāo)準(zhǔn)庫中的一個函數(shù),用于按字節(jié)方式復(fù)制字符串(內(nèi)存)。它的第一個參數(shù),是將字符串復(fù)制到哪里去(dest),是目的地,這段內(nèi)存區(qū)域必須是可寫。它的第二個參數(shù),是要將什么樣的字符串復(fù)制出去,我們對這段內(nèi)存區(qū)域只做讀取,不寫。于是,我們站在這個函數(shù)自己的角度來看,src 這個指針,它所指向的內(nèi)存內(nèi)所存儲的數(shù)據(jù)在整個函數(shù)執(zhí)行的過程中是不變。于是src所指向的內(nèi)容是常量。于是就需要用const修飾。例如,我們這里這樣使用它。const char* s=hello。char buf[100]。memmove(buf,s,6)。 //這里其實應(yīng)該用strcpy或memcpy更好如果我們反過來寫,memmove(s,buf,6)。那么編譯器一定會報錯。事實是我們經(jīng)常會把各種函數(shù)的參數(shù)順序?qū)懛?。事實是編譯器在此時幫了我們大忙。如果編譯器靜悄悄的不報錯,(在函數(shù)聲明處去掉const即可),那么這個程序在運行的時候一定會崩潰。這里還要說明的一點是在函數(shù)參數(shù)聲明中const一般用來聲明指針而不是變量本身。例如,上面的size_t len,在函數(shù)實現(xiàn)的時候可以完全不用更改len的值,那么是否應(yīng)該把len也聲明為常量呢?可以,可以這么做。我們來分析這么做有什么優(yōu)劣。如果加了const,那么對于這個函數(shù)的實現(xiàn)者,可以防止他在實現(xiàn)這個函數(shù)的時候修改不需要修改的值(len),這樣很好。但是對于這個函數(shù)的使用者,1。這個修飾符號毫無意義,我們可以傳遞一個常量整數(shù)或者一個非常量整數(shù)過去,反正對方獲得的只是我們傳遞的一個copy。2。暴露了實現(xiàn)。我不需要知道你在實現(xiàn)這個函數(shù)的時候是否修改過len的值。所以,const一般只用來修飾指針。再看一個復(fù)雜的例子int execv(const char *path, char *const argv[])。著重看后面這個。如果去掉const,我們可以看出char * argv[]。argv是一個數(shù)組,它的每個元素都是char *類型的指針。?他修飾的是一個數(shù)組,argv[],意思就是說這個數(shù)組的元素是只讀的。那么數(shù)組的元素的是什么類型呢?是
點擊復(fù)制文檔內(nèi)容
物理相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1