C++ 指針學習筆記 引入 指針是什麼 指針是一個變數,其值為另一個變數的地址。 指針聲明的一般形式為: type *ptr_name; type 是指針的基類型,ptr_name 是指針的名稱,* 用來指定一個變數是指針 對於一個指針,需要明確四個方面的內容:指針的類型、指針所指向的類型、指針的值 ...
C語言【運算符、分支控制語句】
1、運算符分類
-
按照操作個數分類:
一元運算符(一目運算符):只有一個操作數。如 負號
-1。 二元運算符(二目運算符):有兩個操作數。如 加號
1+2。 三元運算符(三目運算符):有三個操作數。如 ?:
a>b?1:2。 -
按功能分類:
算數運算符:正(+)、負(-)、加(+)、減(-)、乘(*)、除(/)、取模(%)、自增(++)、自減(--)。
賦值運算符:賦值(=)、相加賦值(+=)、相減賦值(-=)、相乘賦值(*=)、相除賦值(/=)、取餘賦值(%=)、左移賦值(<<=)、右移賦值(>>=)、按位與賦值(&=)、按位異或賦值(^=)、按位或賦值(|=)。
int te = 0; // if里是賦值 if(te = 0){ // te=0 的結果為所賦的0 printf("abcdefg"); // 不會執行 }
// 連續賦值 int a = b = c = 6; // 從右往左賦值,a、b、c都為6
// 相乘賦值+連續賦值 int a = 2; int c; // 下麵中間那個c得提前定義。 int b = c = a*=3; // a、b、c都為6
賦值運算符一般是從右往左運算。運算方向是當表達式中出現多個該運算符時每個運算符的操作順序。
關係運算符:相等(==)、不等(!=)、小於(<)、大於(>)、小於等於(<=)、大於等於(>=)。
關係運算符的結果為0或1
邏輯運算符:邏輯與(&&)、邏輯或(||)、邏輯非(!)
邏輯與(&&)也叫短路與,如果&&前面的表達式為0時,後面的表達式不作運算,直接返回為0;
邏輯或(||)也叫短路或,如果||前面的表達式為1時,後面的表達式不作運算,直接返回1。
在表達式前加邏輯非時記得給表達式加括弧。
邏輯運算符的結果為0或1
位運算符:按位與(&)、按位或(|)、按位異或(^)、按位取反(~)、按位左移(<<)、按位右移(>>)
左移n位就相當於乘2的n次方;右移n位就相當於除以2的n次方。
int a = 10; a >> 3; // a不發生改變,因為沒有再賦值給a
int b = 10; b = b >> 3; // b在原來的基礎上縮小了2的3次方。 10 / 3 = 1
int y = -10; y = y >> 2; printf("%d\n", y); // -3 // -10 / 4 = -2...-2 把商的-2退為-3, 即 -10 / 4 = -3...2
負整數的除法和右移操作結果並不一樣,如下:
int z = -10 / 4; printf("%d\n", z); // -2
左移時出現的溢出問題:左移時,會出現結果大過所接收值類型範圍導致溢出。
// 第一種情況,如果只關心輸出結果,而不關心是不是在類型範圍內,可以在輸出時使用大格式,把超出的看作有效 int num_max = 0x7fffffff; num_max = num_max<<2; // 乘4,已經超過了int能表示的範圍 printf("%lld", num_max); // 輸出時使用 %lld 把超出的範圍也視作有效
// 第二種情況,就是想知道溢出後在有效範圍內為多少,也就是這個數的實際值,可以看作對類型能表示的個數取餘 int num_max = 0x7fffffff; num_max = num_max<<2; // 實際結果8589934588,超了。 8589934588 % int能表示的個數(4294967296) = 4294967292。 num_max類型為有符號int, 4294967292最高位為1,轉換為原碼為-4,所以num_max為-4。在記憶體種這32位里存的就是4294967292的二進位形式。 printf("%d", num_max); // %d 表示有符號int, 4294967292最高位為1,轉換為原碼為-4,輸出-4
有符號數右移時,對於負數,前面空出來的位全補1;對於正數,前面空出來的位全補0。
遺留問題:按位異或可以實現交換兩個變數的值,如何實現的?原理是什麼?
2、運算符的優先順序
具體的不作瞭解,使用時不確定就用括弧。
總體來說:一元運算符 > 算數運算符 > 關係運算符 > 邏輯運算符 > 三元運算符 > 賦值運算符
從右到左運算是指同一表達式出現多次同一運算符時,運算的方向。
右到左的運算符有: todo
3、記幾個整型和浮點型之間的運算。
// 整型的除法運算
int num01 = 10;
int num02 = 3;
int num03 = num01 / num02; // 3
// 浮點型接收整型的運算
float num04 = 10 / 3; // 斷點調試此處為3, printf用%f輸出時記得補6位小數
問題:上行代碼的num04如果用%f輸出是3.000000,如果用%d輸出呢?我試了試是0。為什麼?
// 浮點型與整型的運算
float num05 = (float)10 / 3; // 3.33333325
printf("%f\n", num05); // printf用%f輸出時保留6位小數為3.333333
// 浮點數參與的運算其實是四捨五入的,手動保留小數時也是四捨五入
float num06 = (float)20 / 3; // 6.66666651
printf("%f\n", num05); // 6.666667
4、取餘(%)操作時,餘數的符號跟著被除數(前面的數)的符號。
5、關於自增(++)和 自減(--)
不多解釋,舉個特別的例子。
/**
i=i++時
第一步:將i的值放到臨時空間,作為後續運算的依據
第二步:將i的值+1
第三步:將臨時空間里存進去的值拿出來賦給i (如果是j=i++時這一步就是賦給j)
*/
int i = 1;
i = i++;
printf("%d\n", i); // 1
/**
i = ++i時
不多解釋,上面步驟 二、一、三
*/
int i = 1;
i = ++i;
printf("%d\n", i); // 2
註意:以上這兩種情況在gcc可以編譯通過,在clang編譯器編譯時就會報錯。