欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言 語義陷阱超詳細(xì)梳理總結(jié)

 更新時(shí)間:2022年03月25日 15:38:38   作者:鹿九丸  
這篇文章主要介紹了C語言常見的一些語義陷阱,梳理的比較全面,對(duì)我們做開發(fā)的過程中有一定幫助,感興趣的朋友快來看看吧

1 指針與數(shù)組

  • C語言中只有一維數(shù)組。數(shù)組中的元素可以是任意類型的對(duì)象,這也是多維數(shù)組構(gòu)建的理論基礎(chǔ)所在
  • 對(duì)于一個(gè)數(shù)組,我們只能做兩件事:確定該數(shù)組的大小以及獲得該數(shù)組下標(biāo)為0的元素的指針。任何一個(gè)數(shù)組下標(biāo)運(yùn)算都等同于一個(gè)對(duì)應(yīng)的指針運(yùn)算。
  • 數(shù)組名代表首元素的地址,無法對(duì)其進(jìn)行++或者–操作,換句話說,我們無法改變數(shù)組名(表示的值),因?yàn)閿?shù)組名是個(gè)常量,無法進(jìn)行修改。

2 非數(shù)組的指針

下面有一段程序,指出它的錯(cuò)誤:

char *r;
r = malloc(strlen(s)+strlen(t));
strcpy(r,s);
strcat(r,t);
  • malloc有可能無法提供請(qǐng)求的內(nèi)存,這種情況下malloc函數(shù)會(huì)通過返回一個(gè)空指針來作為“內(nèi)存分配失敗”事件的信號(hào)。
  • 給r分配的內(nèi)存在使用完畢后應(yīng)該及時(shí)釋放。
  • 前面的例程在調(diào)用malloc函數(shù)時(shí)并未分配足夠的內(nèi)存,因?yàn)樽址€包含結(jié)束標(biāo)志'\0'。

3 作為參數(shù)的數(shù)組聲明

1.下面列舉的兩種寫法是等價(jià)的:

char hello[] = "hello";
printf("%s\n",hello);//寫法1
printf("%s\n",&hello);//寫法2

原因:數(shù)組名hello代表數(shù)組hello首元素的地址。

2.下面的兩種寫法是等價(jià)的:

int strlen(char s[])
{
	/*具體內(nèi)容*/
}
int strlen(char *s)
{
	/*具體內(nèi)容*/
}

注意下面的兩種寫法:

extern char *hello;
extern char hello[];

這兩種寫法雖然是都是正確的,但是不同的形式傳遞給我們的意思卻是完全不一致的,我們要根據(jù)具體情況進(jìn)行使用。

4 空指針并非空字符串

注意:空指針不能對(duì)其進(jìn)行解引用。

同時(shí)注意不能出現(xiàn)下述寫法:

if(strcmp(p,(char*)0)==0)
	···

這種寫法是非法的,原因在于庫函數(shù)strcmp的實(shí)現(xiàn)中會(huì)包括一個(gè)操作,用于查看它的指針參數(shù)所指向的內(nèi)容,即對(duì)空指針進(jìn)行了解引用。

也不能出現(xiàn)下述寫法:

假設(shè)p是空指針

printf(p);
printf("%s",p);
//當(dāng)然,這兩種寫法是等價(jià)的

這種行為是未定義的。

5 邊界計(jì)算與不對(duì)稱邊界

在我們寫循環(huán)是最好這樣來寫:

int i = 0;
for(i = 0;i < 10; i++)
	···

這樣寫能夠更好的看出循環(huán)的次數(shù),即10次。

當(dāng)數(shù)組中有10個(gè)元素時(shí),下標(biāo)的取值范圍為0到9,但是當(dāng)我們不需要引用這個(gè)元素時(shí)只需要引用這個(gè)元素的地址時(shí),我們可以這樣寫

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(int i = 0;&arr[i]<&(arr[10]);i++)
	···

這樣可以順利打印出數(shù)組元素從1到10的數(shù)字,

ANSI C標(biāo)準(zhǔn)明確允許這種用法:數(shù)組中實(shí)際不存在的"溢界"元素的地址位于數(shù)組之外所占內(nèi)存之后,這個(gè)地址可以用于進(jìn)行賦值和比較。當(dāng)然,如果要引用該元素,那就是非法的了。對(duì)于實(shí)際去讀取這個(gè)元素的值,這種做法的結(jié)果是未定義的,而且極少有編譯器能偶檢測出這個(gè)錯(cuò)誤。當(dāng)然,如果試圖去修改這個(gè)元素,必然會(huì)導(dǎo)致程序崩潰,屬于非法訪問了!

6 求值順序

C語言中只有四個(gè)運(yùn)算符(&&、||、?:和,)存在規(guī)定的求值順序。==運(yùn)算符&&和運(yùn)算符||首先對(duì)左側(cè)操作數(shù)求值,只有在需要時(shí)才對(duì)右側(cè)操作數(shù)求值。==運(yùn)算符?:有三個(gè)操作數(shù):在a?b:c中。操作數(shù)a首先被求值,根據(jù)a的值再求操作數(shù)b或c的值(此時(shí)b或c兩個(gè)表達(dá)式根據(jù)前面a表達(dá)式的結(jié)果只會(huì)執(zhí)行一個(gè))。逗號(hào)運(yùn)算符則首先對(duì)左側(cè)操作數(shù)求值,然后"丟棄該值",再對(duì)右側(cè)操作數(shù)求值。

注意:分割函數(shù)的參數(shù)并非逗號(hào)運(yùn)算符。例如,x和y在函數(shù)f(x,y)中的求值順序是未定義的,而在函數(shù)g((x,y))中卻是確定的先x后y的循序。在后一個(gè)例子中,函數(shù)g只有一個(gè)參數(shù)。這個(gè)參數(shù)的值是這樣求得的:先對(duì)x求值,然后“丟棄”x的值,接著求y的值。

這種求值順序的存在使得某些“錯(cuò)誤”的程序變?yōu)榱苏_,且在執(zhí)行后得出正確的結(jié)果:

if(count!=0 && sum/count < smallaverage)
	···

注意:C語言中其它所有的運(yùn)算符對(duì)其操作數(shù)求值的順序是未定義的。特別是,賦值運(yùn)算符并不保證任何求值循序。

例如:下面的這中從數(shù)組x中復(fù)制前n個(gè)元素到數(shù)組y中的做法是不正確的,因?yàn)樗鼘?duì)求值順序做了太多的假設(shè):

i = 0;
while(i < n)
	y[i] = x[i++];

上面的代碼假設(shè)y[i]的地址將在i的自增操作指向之前被求值,但這是不一定的,這依賴于編譯器的具體實(shí)現(xiàn)。同樣,下面的這種寫法也是不正確的:

i = 0;
while(i<n)
	y[i++] = x[i];

修改成下面這種寫法即可正常工作:

i = 0;
while(i<n)
{
	y[i] = x[i];
	i++;
}

當(dāng)然,這種寫法也可以簡寫為:

for(i = 0;i < n;i++)
	y[i] = x[i];

7 整數(shù)溢出

無符號(hào)整數(shù)不會(huì)發(fā)生溢出,這是C語言所規(guī)定的,如果結(jié)果大于所能表示的最大值M,則模(M+1),也就是發(fā)生了截?cái)喱F(xiàn)象。

兩個(gè)有符號(hào)整數(shù)進(jìn)行相加時(shí)會(huì)發(fā)生溢出,而且溢出的結(jié)果是未定義的。

下面是一種錯(cuò)誤的檢查方式:

if(a + b < 0)
	complain();

因?yàn)楫?dāng)a+b卻是發(fā)生溢出時(shí),所有關(guān)于結(jié)果如何假設(shè)都不再可靠。

下面是兩種正確的方式:

//方法一:
if((unsigned)a + (unsigned) > INT_MAX)
	complain();
//方法二:
if(a > INT_MAX - b)
	complain()

8 為函數(shù)提供返回值

C語言種常常通過return 返回一個(gè)值來告知操作系統(tǒng)的執(zhí)行是成功還是失敗,典型的處理方案是。返回值為0表示程序執(zhí)行成功,返回值為非0則表示程序執(zhí)行失敗。我們常常會(huì)在程序的末尾加上return 0操作。

到此這篇關(guān)于C語言 語義陷阱超詳細(xì)梳理總結(jié)的文章就介紹到這了,更多相關(guān)C語言 語義陷阱內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言表達(dá)式求值中類型轉(zhuǎn)換和優(yōu)先級(jí)等問題詳解

    C語言表達(dá)式求值中類型轉(zhuǎn)換和優(yōu)先級(jí)等問題詳解

    表達(dá)式求值是一個(gè)常見的問題,可以用C語言實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于C語言表達(dá)式求值中類型轉(zhuǎn)換和優(yōu)先級(jí)等問題的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 使用ShellClass獲取文件屬性詳細(xì)信息的實(shí)現(xiàn)方法

    使用ShellClass獲取文件屬性詳細(xì)信息的實(shí)現(xiàn)方法

    本篇文章是對(duì)ShellClass獲取文件屬性詳細(xì)信息的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++ 花括號(hào){}初始化小結(jié)

    C++ 花括號(hào){}初始化小結(jié)

    在C++11及以后的版本中,花括號(hào){}語法在不同語境下有不同的用法,本文就詳細(xì)的介紹C++ 花括號(hào){}初始化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C++ 中boost::share_ptr智能指針的使用方法

    C++ 中boost::share_ptr智能指針的使用方法

    這篇文章主要介紹了C++ 中boost::share_ptr智能指針的使用方法的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • C++簡單又輕松的講解類和對(duì)象中友元函數(shù)

    C++簡單又輕松的講解類和對(duì)象中友元函數(shù)

    采用類的機(jī)制后實(shí)現(xiàn)了數(shù)據(jù)的隱藏與封裝,類的數(shù)據(jù)成員一般定義為私有成員,成員函數(shù)一般定義為公有的,依此提供類與外界間的通信接口。但是,有時(shí)需要定義一些函數(shù),這些函數(shù)不是類的一部分,但又需要頻繁地訪問類的數(shù)據(jù)成員,這時(shí)可以將這些函數(shù)定義為該類的友元函數(shù)
    2022-06-06
  • 使用C++ Matlab中的lp2lp函數(shù)教程詳解

    使用C++ Matlab中的lp2lp函數(shù)教程詳解

    本文介紹如何使用C++編寫數(shù)字濾波器設(shè)計(jì)算法,實(shí)現(xiàn)Matlab中的lp2lp函數(shù),將低通濾波器轉(zhuǎn)換為參數(shù)化的低通濾波器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-04-04
  • C語言字符函數(shù)與字符串函數(shù)詳解

    C語言字符函數(shù)與字符串函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于C語言字符/字符串的相關(guān)函數(shù),文中通過示例代碼總結(jié)的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C語言具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • Visual?Studio2022的完全卸載及安裝到D盤的操作方法

    Visual?Studio2022的完全卸載及安裝到D盤的操作方法

    這篇文章主要介紹了Visual?Studio2022的完全卸載以及完全安裝到D盤,因?yàn)閂S如果隨便寫在會(huì)有很多很多的亂七八糟的東西掉出來,所以我們選擇制式一點(diǎn)的卸載方式,需要的朋友可以參考下
    2022-09-09
  • C語言實(shí)現(xiàn)遍歷文件夾中的文件

    C語言實(shí)現(xiàn)遍歷文件夾中的文件

    這篇文章主要為大家詳細(xì)介紹了如何使用C語言實(shí)現(xiàn)遍歷文件夾中的文件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2024-02-02
  • Pthread并發(fā)編程之線程基本元素和狀態(tài)的剖析

    Pthread并發(fā)編程之線程基本元素和狀態(tài)的剖析

    本篇文章主要給大家介紹pthread并發(fā)編程當(dāng)中關(guān)于線程的基礎(chǔ)概念,并且深入剖析進(jìn)程的相關(guān)屬性和設(shè)置,以及線程在內(nèi)存當(dāng)中的布局形式,幫助大家深刻理解線程
    2022-11-11

最新評(píng)論