<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                **貳** **幾個關鍵字** sizeof 1、sizeof是關鍵字而不是函數。 例:int i=3;?? sizeof(i) ;? 與? sizeof i ; 是完全等同。 sizeof在計算變量所占空間大小時,括號可以省略,而計算類型大小時不能省略。(所以我們常在其后加上括號) 2、sizeof的作用域是緊跟它后面的一個變量或類型。 故:sizeof(int)*p;//p為指針,則此表達式會報錯。此表達式的意思不是計算 *p強制轉換成int類型之后值的存儲大小,而意為sizeof(int)的值4 然后是*p的值 這兩個值中間沒有操作符故會報錯。同理:sizeof i*i ;//int i=3 此表達式值為12 1、?★sizeof的值在編譯時就已經確定,故在程序執行時不會執行sizeof括號內的表達式。 ~~~ #include <stdio.h> int main(void) { int i; i = 10; printf("sizeof(i++)is: %d\n",sizeof(i++)); printf("i :%d\n",i); return 0; }//最后打印i的值為10,因為程序不執行sizeof里的表達式i++ ~~~ switch、case組合 注意: 1、每個case語句的結尾不要忘了加break,若是為了實現某功能故意不加,應該注釋清楚 2、最后必須使用default分支。即使程序真的不需要default處理,也應該保留語句 default :?? break; 可以避免讓人誤認為你忘了default處理。 2、?case關鍵字后面只能是整型或字符型常量(小整型)或常量表達式。 3、?★switch塊中的case是一個標簽,switch根據值來選擇執行哪個case標簽的語句。故編譯器只對case和default標簽里的語句編譯,而寫在而在case塊之前的語句則忽視掉。 ~~~ #include <stdio.h> int main(void) { inta=1; switch(a) { intb=20; //此語句不被編譯,C編譯器會產生警告(C++編譯器會報錯) case1: printf("bis %d\n",b); //故此輸出隨機值 break; default: printf("bis %d\n",b); break; } return 0; } ~~~ void void的字面意思是“空類型”,void * 則為“空指針類型”任何類型的指針都可以直接賦值給它,無需進行強制類型轉換。但:void * 不可以不經強制類型轉換地賦值給其它類型的指針。因為“空類型”可以包容“有類型”,而有類型則不能包容“空類型”。 如果函數的參數可以是任意類型的指針,那么應聲明其參數為void * void不能代表一個真實的變量。(因為定義變量時必須分配內存空間,定義void類型編譯器不知道分配多少空間)故:void a ;//錯誤 void只是為了一種抽象的需要。 const 在C語言中,const修飾的值是只讀變量,其值在編譯的時候不能被使用,因為編譯器在編譯的時候不知道其存儲的內容。 例:const intmax=100 ;? int Array[max] ; 在C編譯環境下,編譯器會報錯。因為在C中,const修飾的仍然是變量,只不過是只讀屬性罷了。 而在C++中,const則修飾的值是常量,完全可以取代宏定義,其效果和宏定義相同。故上面的代碼在C++中是合法的。 volatile volatile修飾的量就是很容易變化,不穩定的量,它可能被其它線程,操作系統,硬件等等在未知的時間改變,所以它被存儲在內存中,每次取用它的時候都只能在內存中去讀取,它不能被編譯器優化放在內部寄存器中。 ★const和volatile在類型聲明中的位置 兩者的規則一樣。以const為例: 類型聲明中const用來修飾一個常量,我們一般這樣使用: ①const在前面 const int? ;?????????? //int是const const char* ;???????? //char是const char* const ;???????? //*(指針)是const const char* const ; //char和*都是const 【const所修飾的類型是 它后面的那一個】 ②const在后面( 與上面的聲明對等) int const ;???????????????????? //int是const char const* ;???????? //char是const char* const ;???????? //*(指針)是const char const* const ; //char和*都是const **建議const寫在后面:** A. const所修飾的類型是正好在它前面的那一個。 B. 我們很多時候會用到typedef的類型別名定義。比如typedef char* pchar,如果用const來修飾的話,當const在前面的時候,就是const pchar,你會以為它就是const char* ,但是你錯了,它的真實含義是char* const。是不是讓你大吃一驚!但如果你采用const在后面的寫法,意義就怎么也不會變,不信你試試! ***幾個運算符*** 邏輯運算符:**(一定要注意表達式的順序)** &&?||? 有“短路”現象??? (有好處也有壞處) **/*利用短路現象*/** 例:if( x>=0&& x<MAX && array[x]==0 ) ……….//可用 (首先檢查x值是否在數組下標范圍內。如果不是,代碼中的下標引用表達式便忽略。此可防止下標值錯誤導致引用失敗) 例:if(p==NULL|| *p==’\0’) ………….//可用 【總結:**使用&&時,把大前提條件放前面,小條件放后面** **使用&&時,是第一個表達式成立才繼續執行(有點像if-else 故我們常利用&&的短路規則)** **使用||時,是第一個表達式不成立才繼續執行**】 條件運算符:(可替換if-else) 例:a>5 ? b-6: c/2? ; //可讀作“a是不是大于5?如果是,就執行b-6,否則執行c/2” ~~~ if(a>5) b[2*c+d(e/5)]= 3 ; else b[2*c+d(e/5)]= -20 ; //用條件運算符可寫作:b[2*c+d(e/5)]= a>5 ? 3 : -20 ; ~~~ 【在某些復雜的表達式寫相似的兩次時,用條件運算符更簡潔,易修改會產生較小的目標代碼, 可以簡化表達式】 逗號運算符: 【**可用于循環判斷中(多用于while),使多次重復的語句只寫一次**】 ~~~ a=get_value(); count_value(a); while(a>0) { ………. a=get_value(); count_value(a); } ~~~ 則可簡化為: while(a=get_value() , count_value(a) , a>0){……} (這些表達式自左向右逐個求值,整個逗號表達式的值就是最后那個表達式的值) ***隱式轉換 / 溢出*** 例1:char? ch ; ????? ?While( (ch=getchar()) != EOF ) …..//錯誤! 注意:**getchar()返回一個整型值而不是字符值!** 若把getchar返回值存儲于ch中,將導致它被截斷!然后這個被截斷的值被提升為整形并與EOF比較,循環會出錯。 【用整形來定義一個字符變量更好!**字符就是一個小整數**】?sizeof(‘a’) ; 的值為4。 ~~~ char a,b,c ; a = b+c ; //b+c的值超過或等于128就會出錯。 ~~~ 注意:C的整型算數運算總是至少以缺省整型類型的精度來進行的。為了獲得這個精度,表達式中的字符型和短整型操作數在使用之前被轉換為普通整型。即:**整型提升** (上面b和c的值被提升為普通整型,然后再執行加法運算。加法運算的結果被截斷再存儲于a中) 【所以:**最好把字符型定義為int 尤其是涉及運算時**】 //WHY?在整數運算時,操作數是放到兩個寄存器中進行的(32位計算機寄存器是32位 故字符型變量被提升為整型,計算的結果又被傳回到內存中的字符型存儲位置中故被截斷) ~~~ int a=5000 ; int b=25 ; long c=a*b ; ~~~ 表達式a*b以整型進行計算,若在16位的計算機上,這個乘法可能會產生溢出! 故應該顯式轉換: longc=(long)a*b ; 【在進行算術運算時一定要警惕乘法加法的可能溢出,尤其**注意賦值號兩邊的數據類型保持一致**】 在計算類似a*b/c 這樣的表達式的時候,一些中間計算結果可能會溢出。 【**對于算術運算可能的溢出一定要保持警惕!!!**】 ***對無符號類型的建議:*** 1、盡量不要在你的代碼中使用無符號類型,以免增加不必要的復雜性。 2、盡量使用像int那樣的有符號類型,這樣在涉及升級混合類型的復雜細節時,不必擔心邊界情況。 3、只有在使用位段和二進制掩碼時,才可以使用無符號數。 ***表達式求值的順序*** ***兩個相鄰操作符的執行順序由它們的優先級決定。如果它們的優先級相同,它們的執行順序由它們的結合性決定。(即從左還是從右運算),此外編譯器可自由決定順序對表達式求值! ~~~ a*b + c*d +e*f ; //可能按下列順序運行: c*d e*f a*b (a*b)+(c*d) (a*b)+(c*d)+(e*f) //加法運算的結合性要求兩個加法運算按先左后右執行,但對表達式剩余部分執行順序沒有限制。 沒有規則要求所有的乘法首先進行,沒有規定其誰先執行。 ~~~ 【**優先級只對相鄰的操作符的執行順序起作用**】 【在C語言的眾多運算符中,**ANSI標準只規定了4種運算符的操作數的求值順序: &&? || 逗號運算符 和 ?:**】 警示:f( ) + g( )+ h( ) ; //應該避免! 如果函數執行有副作用,不同的結合順序會產生不同的結果! 故 最好使用臨時變量,讓每個函數調用都在單獨的語句中進行。 ~~~ tmp = f( ) ; tmp += g( ) ; tmp += h( ) ; //良好的編程風格 ~~~ 【**避免編寫 結果依賴于求值順序的表達式**】 例:a[i] = i++;? //應該避免! //i在同一表達式的其它地方被引用無從判斷該應用是舊值還是新值。 【**確保一個表達式只修改一個對象,如果要修改多個對象,要確保修改的對象互不相同**!(在一個表達式中,一個對象只能修改一次)】 ~~~ printf(“%d%d”,f1(), f2() ) ; //應該避免! //若函數f2( )的結果依賴于函數f1( ) 則printf的結果是不確定的! //用逗號分隔的函數參數不是逗號運算符。 ~~~ 【**函數調用的參數的求值順序是不確定的! 不要讓有副作用的函數作為參數!**】 ***左值和右值*** 左值就是那些能夠出現在賦值號左邊的東西,右值就是那些可以出現在賦值號右邊的東西。 【編譯原理:編譯器會把賦值號左邊的部分解釋成一個存儲位置,把賦值號右邊的部分解釋成一個值。在編譯過程中,編譯器會維護一張變量表,其中是我們定義過的變量名及其在內存中分配的地址。 當編譯器遇到一個變量名,若此變量名在賦值號的左邊,則編譯器查變量表得到其在內存中的地址;若此變量名在賦值號的右邊,則編譯器先查得其在內存中地址,再把地址中的內容提取出來。(不準確,但初學者可以這么理解)】 **變量作為右值時,編譯器只是取變量的值。** **左值標志了一個特定的位置來存儲結果。** 例: a =b+25? ; // 正確 ????? ?b+25 = a?;// 錯誤 當計算機計算b+25時,它的結果只是一個映像(暫存寄存器中),不在內存區中,我們無法得到它的地址,故這個表達式不是一個左值。 同理:*cp + 1 也不可做左值。(因為其值不存儲于內存區中的一個特定的位置) 而字符串字面量雖然存儲于內存區中,但其存儲于內存的無名常量區,這個位置不是由我們設定的特定位置,而是由編譯器隨機分配的,故其也不能作為左值。 **表達式也可以是左值。** 例:int? a[30] ; ……….a[b+10]=0 ; // 正確 下標引用實際是一個操作符,故左邊實際上是個表達式,但它是一個合法的左值,因為它標志了一個特定的位置。 同理: int? a, *p ; ……..p=&a; *p=20 ; // 正確 (含操作符的就是表達式。 sizeof(int) ; 也是表達式) 【**左值意味著一個位置,而右值意味著一個值(左值就是存儲右值的位置)**】
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看