操作符詳解
操作符
- 各種操作符的介紹
操作符
分類:
- 算術操作符
- 移位操作符
- 位操作符
- 賦值操作符
- 單目操作符
- 關係操作符
- 邏輯操作符
- 條件操作符
- 逗號表示式
- 下標引用、函式呼叫和結構成員
算術操作符
+ - * / %
- 除了 % 操作符之外,其他的幾個操作符可以作用於整數和浮點數。
- 對於 / 操作符如果兩個運算元都為整數,執行整數除法。而只要有浮點數執行的就是浮點數除法。
- % 操作符的兩個運算元必須為整數。返回的是整除之後的餘數。
移位操作符
<< 左移操作符
>> 右移操作符
左移操作符
移位規則:左邊拋棄、右邊補0
右移操作符
移位規則:首先右移運算分兩種:
- 邏輯移位(無符號) 左邊用0填充,右邊丟棄
- 算術移位(有符號) 左邊用原該值的符號位填充,右邊丟棄
警告⚠ : 對於移位運算子,不要移動負數位,這個是標準未定義的。 例如:
int num = 10;
num>>-1;//error
位操作符
位操作符有:
& //按位與
| //按位或
^ //按位異或
注:他們的運算元必須是整數。
練習一下:
#include <stdio.h>
int main()
{
int num1 = 1;
int num2 = 2;
num1 & num2;
num1 | num2;
num1 ^ num2;
return 0;
}
一道變態的面試題:
不能建立臨時變數(第三個變數),實現兩個數的交換。
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;// 異或相同為0 不同為1
printf("a = %d b = %d\n", a, b);
return 0;
}
練習:
編寫程式碼實現:求一個整數儲存在記憶體中的二進位制中1的個數。
參考程式碼:
//方法1
#include <stdio.h>
int main()
{
int num = 10;
int count= 0;//計數
while(num)
{
if(num%2 == 1)
count++;
num = num/2;
}
printf("二進位制中1的個數 = %d\n", count);
return 0;
}
//思考這樣的實現方式有沒有問題?
//方法2:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//計數
for(i=0; i<32; i++)
{
if( ((num>>i)&1) == 1 )
count++;
}
printf("二進位制中1的個數 = %d\n",count);
return 0;
}
//思考還能不能更加優化,這裡必須迴圈32次的。
//方法3:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//計數
while(num)
{
count++;
num = num&(num-1);// 運算一次就會少一個1,迴圈了多少次那麼就會有多少個1
}
printf("二進位制中1的個數 = %d\n",count);
return 0;
}
//這種方式是不是很好?達到了優化的效果,但是難以想到。
賦值操作符
賦值操作符是一個很棒的操作符,他可以讓你得到一個你之前不滿意的值。也就是你可以給自己重新賦值。
int weight = 120;//體重
weight = 89;//不滿意就賦值
double salary = 10000.0;
salary = 20000.0;//使用賦值操作符賦值。
賦值操作符可以連續使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//連續賦值
這樣的程式碼感覺怎麼樣?
那同樣的語義,你看看:
x = y+1;
a = x;
這樣的寫法是不是更加清晰爽朗而且易於除錯。
複合賦值符
+=
-=
*=
/=
%=
=
<<=
&=
|=
^=
這些運算子都可以寫成複合的效果。 比如:
int x = 10;
x = x+10;
x += 10;//複合賦值
//其他運算子一樣的道理。這樣寫更加簡潔。
單目操作符
! 邏輯反操作
- 負值
+ 正值
& 取地址
sizeof 運算元的型別長度(以位元組為單位)
~ 對一個數的二進位制按位取反
-- 前置、後置--
++ 前置、後置++
* 間接訪問操作符(解引用操作符)
(型別) 強制型別轉換
注意:
強轉並不改變目標資料的二進位制序列,只改變看待他的方式(哪種型別)
轉化本質是對資料的二進位制序列進行改變。
演示程式碼:
#include <stdio.h>
int main()
{
int a = -10;
int *p = NULL;
printf("%d\n", !2);
printf("%d\n", !0);
a = -a;
p = &a;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof a);//這樣寫行不行?
printf("%d\n", sizeof int);//這樣寫行不行? 不行·!!
return 0;
}
關於sizeof其實我們之前已經見過了,可以求變數(型別)所佔空間的大小。
sizeof和陣列
#include <stdio.h>
void test1(int arr[])
{
printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch));//(4)
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\n", sizeof(arr));//(1)
printf("%d\n", sizeof(ch));//(3)
test1(arr);
test2(ch);
return 0;
}
問:
(1)、(2)兩個地方分別輸出多少? // 40 4
(3)、(4)兩個地方分別輸出多少? // 10 4
注意;傳的指標型別都是4位元組。
//++和--運算子
//前置++和--
//前置++和--:
#include <stdio.h>
int main()
{
int a = 10;
int x = ++a;
//先對a進行自增,然後對使用a,也就是表示式的值是a自增之後的值。x為11。
int y = --a;
//先對a進行自減,然後對使用a,也就是表示式的值是a自減之後的值。y為10;
return 0;
}
//後置++和--
#include <stdio.h>
int main()
{
int a = 10;
int x = a++;
//先對a先使用,再增加,這樣x的值是10;之後a變成11;
int y = a--;
//先對a先使用,再自減,這樣y的值是11;之後a變成10;
return 0;
}
關係操作符
注意:不能用來判斷字串關係
>
>=
<
<=
!= 用於測試“不相等”
== 用於測試“相等”
這些關係運算子比較簡單,沒什麼可講的,但是我們要注意一些運算子使用時候的陷阱。
警告: 在程式設計的過程中== 和=不小心寫錯,導致的錯誤。
邏輯操作符
&& 邏輯與
|| 邏輯或
區分邏輯與和按位與 區分邏輯或和按位或
1&2----->0
1&&2---->1
1|2----->3
1||2---->1
360筆試題
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
//i = a++||++b||d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
//程式輸出的結果是什麼?
注意當邏輯或的時候,有1則可以直接返回,後邊的就會發生短路。
注意當邏輯與的時候,有0則可以直接返回,後邊的就會發生短路。
條件操作符
exp1 ? exp2 : exp3
練習:
1.
if (a > 5)
b = 3;
else
b = -3;
轉換成條件表示式,是什麼樣?
2.使用條件表示式實現找兩個數中較大值。
比較簡單我就不寫了。
逗號表示式
exp1, exp2, exp3, …expN
逗號表示式,就是用逗號隔開的多個表示式。 逗號表示式,從左向右依次執行。整個表示式的結果是最後一個表示式的結果。
//程式碼1
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗號表示式
c是多少?
//程式碼2
if (a =b + 1, c=a / 2, d > 0)
//程式碼3
a = get_val();
count_val(a);
while (a > 0)
{
//業務處理
a = get_val();
count_val(a);
}
如果使用逗號表示式,改寫:
while (a = get_val(), count_val(a), a>0)
{
//業務處理
}
int arr[10];//建立陣列
arr[9] = 10;//實用下標引用操作符。
[ ]的兩個運算元是arr和9。
下標引用、函式呼叫和結構成員
1.[ ] 下標引用操作符
運算元:一個陣列名 + 一個索引值
int arr[10];//建立陣列
arr[9] = 10;//實用下標引用操作符。
[ ]的兩個運算元是arr和9。
2.( ) 函式呼叫操作符 接受一個或者多個運算元:第一個運算元是函式名,剩餘的運算元就是傳遞給函式的引數。
#include <stdio.h>
void test1()
{
printf("hehe\n");
}
void test2(const char *str)
{
printf("%s\n", str);
}
int main()
{
test1(); //實用()作為函式呼叫操作符。
test2("hello bit.");//實用()作為函式呼叫操作符。
return 0;
}
3.訪問一個結構的成員
. 結構體.成員名
-> 結構體指標->成員名
#include <stdio.h>
struct Stu
{
char name[10];
int age;
char sex[5];
double score;
};
void set_age1(struct Stu stu)
{
stu.age = 18;
}
void set_age2(struct Stu* pStu)
{
pStu->age = 18;//結構成員訪問
}
int main()
{
struct Stu stu;
struct Stu* pStu = &stu;//結構成員訪問
stu.age = 20;//結構成員訪問
set_age1(stu);
pStu->age = 20;//結構成員訪問
set_age2(pStu);
return 0;
}
相關文章
- java 操作符詳解Java
- 詳解 JavaScript 建構函式和 "new" 操作符JavaScript函式
- == 和 === 操作符詳細解析
- 正規表示式教程之操作符及說明詳解
- js高階程式設計(第三版)--元操作符遞增和遞減操作符(前置型和後置型)詳解JS程式設計
- Swift - RxSwift的使用詳解10(條件和布林操作符:amb、takeWhile、skipWhile等)SwiftWhile
- RxJava操作符之建立操作符(三)RxJava
- ES規範解讀之自增操作符
- RxJava操作符之組合操作符(六)RxJava
- RxJava操作符之轉換操作符(四)RxJava
- RxJava操作符之過濾操作符(五)RxJava
- SQL UNION 操作符 和 UNION ALL 操作符SQL
- Android RxJava: 這是一份全面的 操作符 使用匯總 (含詳細例項講解)AndroidRxJava
- JavaScript in 操作符JavaScript
- Java操作符Java
- Flutter (一) Dart 語言基礎詳解(變數、內建型別、函式、操作符、流程控制語句)FlutterDart變數型別函式
- %操作符與/操作符(寫給自己看,以防忘記)
- 【Java】位操作符Java
- Java 操作符(3)Java
- JavaScript中 |、& 、!!操作符JavaScript
- [譯] Pipeable 操作符
- RxJava常用操作符RxJava
- RxJava操作符列表RxJava
- [譯] 谷歌搜尋操作符大全(包含 42 個高階操作符)谷歌
- RxJava 學習筆記 -- 條件操作符和布林操作符RxJava筆記
- Kotlin——初級篇(五):操作符與操作符過載一Kotlin
- http協議/cookie詳解/session詳解HTTP協議CookieSession
- 深入瞭解python2.7 str(), repr(), (``操作符)的區別Python
- 3章 RxJava操作符RxJava
- JavaScript (,)逗號操作符JavaScript
- PostgreSQL:模式匹配操作符SQL模式
- PHP goto操作符使用PHPGo
- RxJava 操作符系列二RxJava
- RxJava操作符系列一RxJava
- RxJava操作符系列二RxJava
- RxJava操作符系列三RxJava
- RxJava 操作符系列五RxJava
- RxJava操作符系列四RxJava