日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言中几个容易踩的“坑”!

發布時間:2023/12/2 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言中几个容易踩的“坑”! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天給大家分享幾個C語言中的坑。

一、帶參數的宏展開順序

#include? #define?f(a,b)?a##b #define?g(a)?#a #define?h(a)?g(a)int?main(void) {printf("%s\n",h(f(1,2)));printf("%s\n",g(f(1,2)));return?0; }

運行結果:

12f(1,2)

淺析:

本題中的#運算符可以利用宏參數創建字符串。##運算符和#運算符一樣也可以用于類函數宏的替換部分。另外,##還可以用于類對象宏的替換部分,這個運算符可以把兩個語言符號組合成單個語言符號,所以該運算符也被成為“預處理粘合劑”。類參數宏展開遵循一定的順序,先從外層開始探尋如果遇到#即刻結束探尋,從遇到#處開始一步一步向外層展開,如果沒有遇到#探尋到最里層結束探尋,然后一步一步向外層展開。

所以printf("%s\n",h(f(1,2)));這條語句的展開順序為:h(f(1,2))(沒有#)? --->>? f(1,2)(到達最里層依然沒有#)? ---->>? h(12)? ---->>? 12。

然而printf("%s\n",g(f(1,2)));這條語句的展開順序是:g(f(1,2))(碰到#即刻結束探尋,開始展開)? ----->>f(1,2)。

二、類型轉換

#include? int?main(void) { int?a?=?-10; unsigned?b?=?1; if(a b?>?0) printf("a? ?b?>?0\n"); else?if?(a? ?b?<?0) printf("a? ?b?<?0\n"); else printf("a? ?b?=?0\n"); return?0; }

運行結果:

a? ?b?>?0

淺析:

第一眼看到這道題心里想到這不明擺著 -10 1 < 0么,如此easy的題目還要算嗎?當程序運行出結果時頓時傻眼了,仔細看了看數據類型發現問題出在了類型的轉換上。眾所周知,在不同類型的數據進行運算時如果不進行特別的轉換那么在數據運算時會先將表示范圍較小的數據自動轉換成表示范圍更廣的數,再參與運算,所以本題中會先將int型的a轉換成unsigned int型,通過補碼運算得知該值為:4294967286,該值加上1會肯定會遠大于0,因此輸出的是a b>0。

三、溢出問題

程序一:

unsigned?i; for?(i?=?110;?i?>=?0;?i--)printf("%u\n",i);

運行結果:

死循環

淺析:

該題的坑就在于沒有注意到unsigned int 的存儲范圍,當小于零溢出時又會從unsigned int 的最大值開始遞減,這就仿佛進入了一個圓環,永遠都沒有辦法找到跳出圓環形跑道的缺口。

程序二:

#include? #include? int?main(void) {char?a[1000];int?i;for(i?=?0;?i?<?1000;?i )a[i]?=?-1?-??i;printf("%d\n",strlen(a));return?0; }

運行結果:

255

淺析:

這道題看上去很簡單但是卻暗藏殺機,很少有人能夠答對,當i從0開始自增,自增到127時-1 - 127 = -128,而這個數正好是char型變量所能表示的最小數字,i再自增一次就會溢出,變成char所能表示的最大數字,這樣又進入了上一題的那個“環”,當i增加到255時-1 - i = 0,此時第一次出現了0,而strlen函數碰到'\0'就結束(不包括),因此輸出結果為255。

四、strcpy函數

void?test() { char?str[10],str1[10]; int?i; for(i?=?0;?i?<?10;?i ){str1[i]?=?'a'? ?i;} strcpy(str,str1); }

淺析:

這段代碼第一眼看過去是沒問題的,但是再看一眼就能夠很輕松找到錯誤了,strcpy函數是拷貝字符串的函數,它是以'\0'為結尾的,因此當程序運行strcpy這一行時會發生內存非法訪問導致程序崩潰。

來源:

https://www.cnblogs.com/jungzhang/p/5547348.html

總結

以上是生活随笔為你收集整理的C语言中几个容易踩的“坑”!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。