蘇州網(wǎng)站運(yùn)營公司淘寶關(guān)鍵詞優(yōu)化怎么弄
1. 操作符的分類
算術(shù)操作符:+
-
*
/
%
移位操作符:<<
>>
位操作符:&
|
^
賦值操作符:=
+=
-=
單目操作符
關(guān)系操作符
邏輯操作符
條件操作符
逗號(hào)表達(dá)式
下標(biāo)引用、函數(shù)調(diào)用和結(jié)構(gòu)成員
2. 算術(shù)操作符
+
-
*
/
%
注意/
操作符:
對于整型的除法運(yùn)算結(jié)果依然是整數(shù)
對于浮點(diǎn)型的除法是, 如果有一個(gè)是浮點(diǎn)型, 結(jié)果就是浮點(diǎn)型
#include <stdio.h>int main()
{int a = 7 % 2;//7/2...1int b = 7 / 2;printf("%d\n", a);//1printf("%d\n", b);//1return 0;
}
//% 取模操作符的兩端必須是整數(shù)
3. 移位操作符
移位操作符: 移動(dòng)的是二進(jìn)制位
<<
左移操作符
>>
右移操作符
注: 移位操作符的操作數(shù)只能是 整數(shù)
關(guān)于計(jì)算機(jī)中的 進(jìn)制
對于整數(shù)的二進(jìn)制表示有3種: 原碼, 反碼, 補(bǔ)碼.
如果是正的整數(shù), 它的原碼、反碼、補(bǔ)碼要相同
如果是負(fù)的整數(shù), 它的原碼、反碼、補(bǔ)碼是要計(jì)算的.
比如數(shù)字7.
0000 0000 0000 0000 0000 0000 0000 0111 - 原碼
0000 0000 0000 0000 0000 0000 0000 0111 - 反碼
0000 0000 0000 0000 0000 0000 0000 0111 - 補(bǔ)碼
數(shù)字-7
1000 0000 0000 0000 0000 0000 0000 0111 - 原碼
1111 1111 1111 1111 1111 1111 1111 1000 - 反碼( 原碼的符號(hào)位不變,其他位按位取反就是反碼)
1111 1111 1111 1111 1111 1111 1111 1001 - 補(bǔ)碼( 反碼+1就是補(bǔ)碼)
整數(shù)在內(nèi)存中存儲(chǔ)的是補(bǔ)碼.
3.1 左移操作符的使用
int main()
{int a = 7;int b = a << 1;printf("a=%d\n", a);printf("b=%d\n", b);return 0;
}
運(yùn)行結(jié)果:
下面是a為負(fù)數(shù)的情形, 以int a = -7;
為例:
注: 移位操作符只能用在整數(shù).
3.2 右移操作符的使用
右移操作符分為兩種: 算術(shù)移位和邏輯移位.
算術(shù)移位: 右邊丟棄, 左邊補(bǔ)原符號(hào)位;
邏輯移位: 右邊丟棄, 左邊補(bǔ)0.
int main()
{int a = 7;int b = a >> 1;printf("a=%d\n", a);printf("b=%d\n", b);return 0;
}
VS2019采用算術(shù)右移.
下面是a為負(fù)數(shù)的情形, 以int a = -7;
為例:
注意: 對于移位運(yùn)算符,不要移動(dòng)負(fù)數(shù)位,這個(gè)是標(biāo)準(zhǔn)未定義的。
4. 位操作符
&
- 按(2進(jìn)制)位與
|
- 按(2進(jìn)制)位或
^
- 按(2進(jìn)制)位異或 - 相同為0,相異為1
int main()
{int a = 3;int b = -5;int c = a & b;int d = a | b;int e = a ^ b;printf("c=%d\n", c);printf("d=%d\n", d);printf("e=%d\n", e);return 0;
}
0000 0000 0000 0000 0000 0000 0000 0011 - 3的補(bǔ)碼
1000 0000 0000 0000 0000 0000 0000 0101 - -5的原碼
1111 1111 1111 1111 1111 1111 1111 1010 - -5的反碼
1111 1111 1111 1111 1111 1111 1111 1011 - -5的補(bǔ)碼
于是:
1111 1111 1111 1111 1111 1111 1111 1011 - -5的補(bǔ)碼
0000 0000 0000 0000 0000 0000 0000 0011 - 3的補(bǔ)碼
0000 0000 0000 0000 0000 0000 0000 0011 - &運(yùn)算
1111 1111 1111 1111 1111 1111 1111 1011 - -5的補(bǔ)碼
0000 0000 0000 0000 0000 0000 0000 0011 - 3的補(bǔ)碼
1111 1111 1111 1111 1111 1111 1111 1011 - |運(yùn)算 - 補(bǔ)碼
1111 1111 1111 1111 1111 1111 1111 1010 - 反碼
1000 0000 0000 0000 0000 0000 0000 0101 - 原碼
1111 1111 1111 1111 1111 1111 1111 1011 - -5的補(bǔ)碼
0000 0000 0000 0000 0000 0000 0000 0011 - 3的補(bǔ)碼
1111 1111 1111 1111 1111 1111 1111 1000 - ^運(yùn)算 - 補(bǔ)碼
1111 1111 1111 1111 1111 1111 1111 0111 - 反碼
1000 0000 0000 0000 0000 0000 0000 1000 - 原碼
不能創(chuàng)建臨時(shí)變量(第三個(gè)變量),實(shí)現(xiàn)兩個(gè)數(shù)的交換。
原來我們允許創(chuàng)建臨時(shí)變量的時(shí)候可以這么實(shí)現(xiàn)兩個(gè)數(shù)的交換:
int main()
{int a = 3;int b = 5;int c = 0;printf("交換前:a=%d b=%d\n", a, b);c = a;a = b;b = c;printf("交換后:a=%d b=%d\n", a, b);return 0;
}
那么要滿足題意的代碼如下:
int main()
{int a = 3;int b = 5;//這種方法會(huì)有溢出的問題printf("交換前:a=%d b=%d\n", a, b);a = a + b;b = a - b;a = a - b;printf("交換后:a=%d b=%d\n", a, b);return 0;
}
但是, 理論上講, 這種方法會(huì)出現(xiàn)問題.
a是int類型, 而int類型又有它自己的最大值, b也是int類型, 有它自己的最大值.
那么它們就有自己的上限.
假設(shè)a放的值非常大, 但是沒有超出它的最大值, b也是一樣,
此時(shí)a+b的和就會(huì)超出最大值, 再賦給a就有可能不是真正的a了, a就會(huì)棧溢出, 導(dǎo)致后續(xù)的運(yùn)算結(jié)果出錯(cuò).
我們來看最沒有問題的代碼:
int main()
{int a = 3;int b = 5;printf("交換前:a=%d b=%d\n", a, b);a = a ^ b;//a=3^5b = a ^ b;//3^5^5 --> b=3a = a ^ b;//3^5^3 --> a=5printf("交換后:a=%d b=%d\n", a, b);return 0;
}
注意這里使用了異或運(yùn)算符的特點(diǎn).
3^3 = 0 -> a^a=0 任何數(shù)和它本身異或, 結(jié)果是0.
011
011
000
0^5=5 -> 0^a = a 任何數(shù)和0異或都是它本身.
000
101
101
3^3^5 = 5
3^5^3 = 5
異或操作符支持交換律
011
101
3^3 = 110
011
3^3^5 = 101
求一個(gè)整數(shù)存儲(chǔ)在內(nèi)存中的二進(jìn)制中1的個(gè)數(shù)
翻譯題意就是: 求補(bǔ)碼的二進(jìn)制中1的個(gè)數(shù)
比如int a = 3;
它的二進(jìn)制為00000000000000000000000000000011
我們進(jìn)行a&1操作
00000000000000000000000000000011
00000000000000000000000000000001
結(jié)果
00000000000000000000000000000001
可以知道, 可以通過&1的方式來得到一個(gè)數(shù)的二進(jìn)制位的最后一位是什么.
3&1得到的結(jié)果是1, 說明他的最低位是1.
那么當(dāng)我們統(tǒng)計(jì)完這最后一位是什么之后, 我們可以通過右移來讓每一位都來到最低位, 然后再通過&1的方式來得到一個(gè)數(shù)的二進(jìn)制位的最后一位是什么, 這樣就能得到二進(jìn)制位1的個(gè)數(shù)
>> <<
#include <stdio.h>
int main()
{int num = -1;int i = 0;int count = 0;//計(jì)數(shù)for(i=0; i<32; i++){if( num & (1 << i) )count++;}printf("二進(jìn)制中1的個(gè)數(shù) = %d\n",count);return 0;
}
5. 賦值操作符
賦值操作符可以更新變量的數(shù)據(jù), 并且它是可以連續(xù)使用的, 但是不建議寫連續(xù)賦值的代碼.
int b = 0;
b = 20;//賦值int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//連續(xù)賦值
復(fù)合賦值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
int a = 3;
a = a + 5;
a += 5;a = a >> 1;
a >>= 1;
6. 單目操作符
在C語言中,單目操作符是只對一個(gè)操作數(shù)進(jìn)行操作的操作符,而雙目操作符是對兩個(gè)操作數(shù)進(jìn)行操作的操作符。
舉個(gè)例子,單目操作符包括取地址操作符&
(用于獲取變量的地址)、遞增操作符++
(用于增加變量的值)、遞減操作符--
(用于減少變量的值)等等。這些操作符只需要一個(gè)操作數(shù)。
雙目操作符包括加法操作符+
、減法操作符-
、乘法操作符*
、除法操作符/
等等。這些操作符需要兩個(gè)操作數(shù)來執(zhí)行相應(yīng)的操作。
例如,a++
是一個(gè)單目操作符,它將變量a
的值遞增1。而a + b
是一個(gè)雙目操作符,它將變量a
和b
的值相加。
! 邏輯反操作
- 負(fù)值
+ 正值
& 取地址
sizeof 操作數(shù)的類型長度(以字節(jié)為單位)
~ 對一個(gè)數(shù)的二進(jìn)制按位取反
-- 前置、后置--
++ 前置、后置++
* 間接訪問操作符(解引用操作符)
(類型) 強(qiáng)制類型轉(zhuǎn)換
//! 邏輯反操作
//C語言中0表示假,非0表示真int flag = 3;
//flag為真,進(jìn)入if
if (flag)
{} //flag為假,進(jìn)入if
if(!flag)
{}
//& 取地址int a = 10;
printf("%p\n", &a);
int* p = &a;//p就是指針變量
//sizeof 操作數(shù)的類型長度(以字節(jié)為單位)
//計(jì)算的是變量所占內(nèi)存空間的大小,單位是字節(jié)
//計(jì)算類型所創(chuàng)建的變量占據(jù)空間的大小,單位是字節(jié)
int arr[5] = {0};
printf("%d\n", sizeof(arr));//20int a = 10;
//int n = sizeof(a);//計(jì)算的是a所占內(nèi)存的大小,單位是字節(jié)
int n = sizeof(int);
printf("n=%d\n", n);//4
//~ 對一個(gè)數(shù)的二進(jìn)制按位取反
int a = 0;
//0000 0000 0000 0000 0000 0000 0000 0000 - 補(bǔ)碼
//1111 1111 1111 1111 1111 1111 1111 1111 -> ~a
//1111 1111 1111 1111 1111 1111 1111 1110 - -1得到反碼
//1000 0000 0000 0000 0000 0000 0000 0001 - 再按位取反得到原碼
//-1
printf("%d\n", ~a);//-1int b = 3;
//0000 0000 0000 0000 0000 0000 0000 0011
//1111 1111 1111 1111 1111 1111 1111 1100 - 補(bǔ)碼
//1111 1111 1111 1111 1111 1111 1111 1011 - 反碼
//1000 0000 0000 0000 0000 0000 0000 0100 - 原碼
//-4
printf("%d\n", ~b);
//* 間接訪問操作符(解引用操作符)
int a = 10;
int* p = &a;
*p = 20;
printf("%d\n", a);
//(類型) 強(qiáng)制類型轉(zhuǎn)換
int a = (int)3.14;
int main()
{int a = 0;printf("%d\n", sizeof(a));printf("%d\n", sizeof(int));printf("%d\n", sizeof a);//ok//printf("%d\n", sizeof int);//errreturn 0;
}
sizeof是操作符,不是函數(shù)
strlen是庫函數(shù),是用來求字符串長度
7. 關(guān)系操作符
關(guān)系操作符是用于比較兩個(gè)值之間的關(guān)系的C語言操作符。它們通常返回一個(gè)布爾值(真或假),表示比較的結(jié)果。
>
>=
<
<=
!= 用于測試“不相等”
== 用于測試“相等”
注意: 在編程的過程中== 和=不小心寫錯(cuò),導(dǎo)致的錯(cuò)誤。
int a = 5;
int b = 10;if (a < b) {// 執(zhí)行這個(gè)代碼塊,因?yàn)閍小于bprintf("a小于b\n");
} else {// 如果條件不成立,執(zhí)行這個(gè)代碼塊printf("a不小于b\n");
}
在上述示例中,<
是一個(gè)關(guān)系操作符,用于比較變量a
和b
的值,根據(jù)比較結(jié)果執(zhí)行不同的代碼塊。
if ("abc" == "abcdef")//這樣寫是在比較2個(gè)字符串的首字符的地址
{}
//兩個(gè)字符串比較相等應(yīng)該使用strcmp
8. 邏輯操作符
邏輯操作符是用于在布爾表達(dá)式中執(zhí)行邏輯運(yùn)算的C語言操作符。它們通常用于組合多個(gè)條件以生成更復(fù)雜的條件。
&&
(邏輯與,AND):當(dāng)兩個(gè)條件都為真時(shí),返回真(1),否則返回假(0)。||
(邏輯或,OR):當(dāng)至少一個(gè)條件為真時(shí),返回真(1),只有兩個(gè)條件都為假時(shí)才返回假(0)。!
(邏輯非,NOT):對一個(gè)條件取反,如果條件為真則返回假(0),如果條件為假則返回真(1)。
int x = 5;
int y = 10;if (x < 10 && y > 5) {// 執(zhí)行這個(gè)代碼塊,因?yàn)閤小于10且y大于5printf("x小于10且y大于5\n");
}if (x > 10 || y < 5) {// 執(zhí)行這個(gè)代碼塊,因?yàn)閤大于10或y小于5printf("x大于10或y小于5\n");
}if (!(x < 10)) {// 執(zhí)行這個(gè)代碼塊,因?yàn)閷 < 10 取反得到假printf("x不小于10\n");
}
在上述示例中,&&
和||
是邏輯操作符,用于組合不同的條件,以便在if
語句中執(zhí)行不同的代碼塊。而!
操作符則用于取反一個(gè)條件。
&&
左邊為假,右邊就不計(jì)算了
||
左邊為真,右邊就不計(jì)算了
9. 條件操作符
條件操作符,也稱為三元運(yùn)算符,是C語言中的一種特殊操作符,用于在一個(gè)表達(dá)式中根據(jù)條件的真假選擇不同的值。條件操作符具有以下語法形式:
condition ? expression_if_true : expression_if_false
condition
是一個(gè)條件表達(dá)式,如果它的值為真(非零),則返回 expression_if_true
的值,否則返回 expression_if_false
的值。
例如:
int x = 10;
int y = 20;
int max;// 使用條件操作符選擇最大值
max = (x > y) ? x : y;// 等效的 if-else 語句
/*
if (x > y) {max = x;
} else {max = y;
}
*/printf("最大值是:%d\n", max);
在上述示例中,條件操作符 (x > y) ? x : y
用于比較 x
和 y
的值,如果 x
大于 y
,則選擇 x
作為最大值,否則選擇 y
。這是一種緊湊的方式來根據(jù)條件選擇不同的值。
10. 逗號(hào)表達(dá)式
逗號(hào)表達(dá)式是C語言中的一種特殊表達(dá)式,它允許你在一個(gè)表達(dá)式中使用逗號(hào) ,
來分隔多個(gè)子表達(dá)式,并按順序依次計(jì)算這些子表達(dá)式,最終返回最后一個(gè)子表達(dá)式的值。逗號(hào)表達(dá)式的一般形式如下:
expression1, expression2, expression3, ..., expressionN
- 逗號(hào)
,
用于分隔不同的子表達(dá)式。 - 所有子表達(dá)式會(huì)按照從左到右的順序依次計(jì)算。
- 逗號(hào)表達(dá)式的最終值是最后一個(gè)子表達(dá)式的值。
逗號(hào)表達(dá)式通常用于一些特定的情況,例如在 for
循環(huán)的表達(dá)式部分,或者在需要在一個(gè)語句中執(zhí)行多個(gè)操作并返回最后一個(gè)操作結(jié)果的情況下。
以下是一個(gè)示例:
int x = 5, y = 10, z;z = (x++, y++, x + y); // 逗號(hào)表達(dá)式,計(jì)算x++,然后y++,最后計(jì)算x + y,將結(jié)果賦給zprintf("x = %d, y = %d, z = %d\n", x, y, z);
在上述示例中,逗號(hào)表達(dá)式 (x++, y++, x + y)
先計(jì)算 x++
和 y++
,然后計(jì)算 x + y
,最后將結(jié)果賦給變量 z
。在輸出中,x
和 y
的值都增加了,而 z
的值是 x + y
的結(jié)果。
11. 下標(biāo)引用、函數(shù)調(diào)用和結(jié)構(gòu)成員
11.1 下標(biāo)引用操作符
下標(biāo)引用操作符是用于訪問數(shù)組和其他類似數(shù)據(jù)結(jié)構(gòu)的元素的操作符。在C語言中,下標(biāo)引用操作符采用方括號(hào) []
來實(shí)現(xiàn)。它允許您通過指定元素的索引來訪問數(shù)組中的特定元素。
下標(biāo)引用操作符的一般形式如下:
array[index]
array
是數(shù)組的名稱或指向數(shù)組的指針。index
是要訪問的元素的索引,通常是一個(gè)整數(shù)表達(dá)式。
例如,考慮以下示例:
int numbers[5] = {1, 2, 3, 4, 5};// 使用下標(biāo)引用操作符訪問數(shù)組元素
int thirdNumber = numbers[2]; // 訪問索引為2的元素,即第三個(gè)元素
在上述示例中,numbers[2]
使用下標(biāo)引用操作符訪問了數(shù)組 numbers
中索引為2的元素,即值為3的元素。這樣,thirdNumber
變量就被賦值為3。
需要注意的是,C語言中的數(shù)組索引通常從0開始,因此第一個(gè)元素的索引是0,第二個(gè)元素的索引是1,以此類推。
11.2 函數(shù)調(diào)用操作符
函數(shù)調(diào)用操作符是一種特殊的操作符,用于調(diào)用函數(shù)并傳遞參數(shù)給它。在C語言中,函數(shù)調(diào)用操作符采用圓括號(hào) ()
來表示,用于標(biāo)識(shí)函數(shù)的名稱以及傳遞給函數(shù)的參數(shù)列表。
函數(shù)調(diào)用操作符的一般形式如下:
function_name(arguments)
function_name
是要調(diào)用的函數(shù)的名稱。arguments
是傳遞給函數(shù)的參數(shù)列表,可以是零個(gè)或多個(gè)參數(shù),用逗號(hào),
分隔。
例如,考慮以下示例:
#include <stdio.h>// 聲明一個(gè)函數(shù)
int add(int a, int b) {return a + b;
}int main() {int result;// 調(diào)用函數(shù)add,并傳遞兩個(gè)參數(shù)result = add(5, 3);printf("5 + 3 = %d\n", result);return 0;
}
在上述示例中,函數(shù)調(diào)用操作符 (5, 3)
用于調(diào)用 add
函數(shù),并傳遞兩個(gè)參數(shù) 5 和 3 給該函數(shù)。add
函數(shù)計(jì)算它們的和,并將結(jié)果返回給 result
變量。然后,printf
函數(shù)用于打印結(jié)果。
函數(shù)調(diào)用是C程序中的重要部分,它使您能夠執(zhí)行各種任務(wù),包括數(shù)據(jù)處理、輸入輸出、數(shù)學(xué)計(jì)算等。函數(shù)的名稱和參數(shù)列表定義了您要執(zhí)行的操作。
11.3 訪問一個(gè)結(jié)構(gòu)的成員
要訪問一個(gè)結(jié)構(gòu)的成員,需要使用成員訪問操作符 .
(點(diǎn)號(hào))來引用結(jié)構(gòu)變量的成員名稱。結(jié)構(gòu)成員訪問操作符的一般形式如下:
structure_variable.member_name
structure_variable
是包含要訪問成員的結(jié)構(gòu)變量的名稱。member_name
是要訪問的結(jié)構(gòu)成員的名稱。
以下是一個(gè)示例:
#include <stdio.h>// 定義一個(gè)結(jié)構(gòu)
struct Point {int x;int y;
};int main() {// 聲明一個(gè)結(jié)構(gòu)變量并初始化struct Point p1;p1.x = 10;p1.y = 5;// 訪問結(jié)構(gòu)成員并打印它們的值printf("p1.x = %d\n", p1.x);printf("p1.y = %d\n", p1.y);return 0;
}
在上述示例中,我們首先定義了一個(gè)名為 Point
的結(jié)構(gòu),該結(jié)構(gòu)有兩個(gè)成員 x
和 y
。然后,在 main
函數(shù)中,我們聲明了一個(gè)名為 p1
的結(jié)構(gòu)變量,并分別使用成員訪問操作符 .
來設(shè)置和訪問結(jié)構(gòu)的成員 x
和 y
的值。
通過這種方式,可以有效地組織和操作數(shù)據(jù),將相關(guān)的數(shù)據(jù)項(xiàng)存儲(chǔ)在一個(gè)結(jié)構(gòu)中,并使用成員訪問操作符來訪問它們。這在構(gòu)建復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)記錄時(shí)非常有用。
訪問一個(gè)結(jié)構(gòu)的成員時(shí),還可以使用箭頭操作符 ->
。這個(gè)操作符通常用于訪問指向結(jié)構(gòu)體的指針的成員。結(jié)構(gòu)體的成員可以是變量、其他結(jié)構(gòu)體或其他數(shù)據(jù)類型。
下面是箭頭操作符的一般形式:
pointer_to_structure->member
pointer_to_structure
是指向結(jié)構(gòu)體的指針。member
是要訪問的結(jié)構(gòu)體成員的名稱。
示例代碼:
#include <stdio.h>// 定義一個(gè)結(jié)構(gòu)體
struct Point {int x;int y;
};int main() {// 創(chuàng)建一個(gè)Point類型的結(jié)構(gòu)體變量struct Point myPoint;myPoint.x = 10;myPoint.y = 20;// 創(chuàng)建指向結(jié)構(gòu)體的指針struct Point *ptr = &myPoint;// 使用箭頭操作符訪問結(jié)構(gòu)體的成員printf("x坐標(biāo):%d\n", ptr->x); // 輸出:x坐標(biāo):10printf("y坐標(biāo):%d\n", ptr->y); // 輸出:y坐標(biāo):20return 0;
}
在上述示例中,我們定義了一個(gè)名為 Point
的結(jié)構(gòu)體,其中包含 x
和 y
兩個(gè)成員。然后,我們創(chuàng)建了一個(gè) Point
類型的結(jié)構(gòu)體變量 myPoint
和一個(gè)指向結(jié)構(gòu)體的指針 ptr
。使用箭頭操作符 ptr->x
和 ptr->y
可以訪問結(jié)構(gòu)體 myPoint
的成員。