C中 類型 運算符與表達式

變量

限制:1.字母+數字 ? (第一個字符必須為字母)?

2."_"視為字母 ?一般情況是 _使用在命名較長的變量命中以提高名字的可讀性 ?例如:first_const 起到駝峰命名的作用 ? ?例程中的變量名一般使用 _ 開頭命名 所以我們在命名時不要使用_ 開頭

3.區分大小寫 ? 變量名一般小寫 ?符號常量名全部大寫

4. 內部名:只在自身.c文件中使用的 命名標識符 長度最長為31個字符 (這一部分存疑,沒有試出來)

外部名:用于不同.c 文件調用的函數名,變量名 有效識別長度為6位 且不區分大小寫 , 需要保證6位字符的唯一性 ? baf ?baF 在調用時將被視為同一外部鏈接 ??

5.原則 : 命名要盡量重表面即可看出 變量或函數的用途 ?局部變量也盡可能簡潔短小

數據類型及長度

char ? ? ? ?字符型 ? ? 占一個字節

int ? ? ? ? ? 整型 ? ? ? ?通常反應機器中整數的最自然長度

float ? ? ? ?單精度浮點類型

double ? ?雙精度浮點類型

在i基本前加限定符(這是int 可以省略) ??

short ?int sh;---->short sh; ?short <=int 長度 ?至少為16位

long ?int sh;---->long sh; ?long 類型至少為32位?

long double ;?

類型限定符 signed ?與 ?unsigned 用于限定 char 類型或任何整型 (char ? short ?int long) 不包括浮點型

這里介紹兩個計算基本類型所占空間的 頭文件

sizeof() ?返回 基本數據類型的 長度(字節B)

1B(Byte 字節)=8bit,

1KB (Kilobyte 千字節)=1024B,?

1MB (Megabyte 兆字節 簡稱“兆”)=1024KB,?

1GB (Gigabyte 吉字節 又稱“千兆”)=1024MB,?

1TB (Trillionbyte 萬億字節 太字節)=1024GB,其中1024=2^10 ( 2 的10次方),?

1PB(Petabyte 千萬億字節 拍字節)=1024TB,?

1EB(Exabyte 百億億字節 艾字節)=1024PB,?

1ZB (Zettabyte 十萬億億字節 澤字節)= 1024 EB,?

1YB (Yottabyte 一億億億字節 堯字節)= 1024 ZB,?

1BB (Brontobyte 一千億億億字節)= 1024 YB.

常量

預編譯處理器形式定義 ?#define

常量定義 : ?#define ?名稱 ?+ 值(又稱為 宏定義) ? ?

#define ?LENGTH ?10;

#define ?WIDTH ?5;

#define ?NEWLINE ?'\0';

const ?關鍵字 定義

const ?+ ?類型 ?+ ?命名 ?= 值

const ?int ?LENGTH = 10;

const ?int ?WIDTH = 5;

const ?char NEWLINE = '\0';

兩種方式有什么異同:

1. 編譯器處理方式

? ? ?define 常量是在預編譯是進行 賦值的的

? ? ?const 是在編譯時進行賦值的

2. 類型檢查

? ? ?define 不聲明常量類型 ?編譯器不進行類型檢測 比較危險 ? ??

? ? ?const 需要進行類型聲明 ?并對常量值是否匹配類型進行檢測

3. 內存空間

? ? ?define - 不分配內存 ?給出的是立即值 有多少次使用就進行多少次替換,在內存中有多個拷貝,消耗內存較大

? ? ? const - 在靜態存儲區中分配空間 ?在程序運行過程中內存中只有一個拷貝

4. 其他

在編譯時 ?編譯器通常不為 const 常量分配存儲空間,而是將他們保存在符號表中,使得他成為一個編譯期間的常量,沒 ?有了存儲與讀內存的操作,使得它的效率也很高

宏定義的作用范圍僅限于當前文件

默認狀態下 ?const 對象只在文件中有效 ?當多個文件中出現 同名的const常量 那么意為著定義了不同的const對象

想在其他文件中使用一個const 常量 需要使用 extern 聲明該常量

define 可以有const 完全替換 ? 最好使用 const 常量


類似1234 的整數常量屬于int 類型 ?long類型的常量以字母l或 L結尾,123456789L

如果整數太大無法用int 處理時 ,將會被當做long類型處理 ?

無符號常量以字母u或U結尾 ? 后綴ul 或者UL 表示無符號的long類型

整型的八進制 十六進制表達?

帶前綴0的整型為八進制 ?前綴為0X或0x,則表示它為16進制

字符常量:

一個字符常量是一個整數 ,書寫時將一個字符放在單引號中‘x’

字符在機器字符集中的數值就是字符常量的值 可以參見ASIIC碼值

比如 '0' ?的值為48 ?

某些字符可以通過轉義字符序列表示為字符和字符串常量 ? 轉義字符看起來像兩個字符 一般由 ?' '單引號+ \ +字符組成

例如 ?'\ooo' ?表示任意的字節大小的位模式 ? ?其中 ?ooo 代表1-3 個八進制數字(0....7) 這種為模式還可以用'\xhh'

所以 \000 表示八進制 ? \xhh 表示16進制數

'\071' 表示一個字符 對應的只為 ?7*8^1+1*8^0 = 57

我們打印這些值 計算機自動幫我們轉化為 10進制

‘\0’字符常量 ?表示值0的字符,也是空字符null ?

常量表達式 ? 僅僅由常量包含的表達式 ? 這種表達式在編譯的時候求值而不是在運行時求值

#define MAX 1000

char line[MAX+1];

字符串常量 ?也叫字符串字面值 ? 是雙引號括起來的字符序列

例如:“I am ?a ?string”

或者 ?"" ?空字符串

雙引號不是字符串的一部分 它只是用來限制字符串的 ? 字符常量中使用的轉移字符常量在字符串中仍然可以使用?

字符串常量就是字符數組 ? 字符串內部使用一個空字符'\0'作為串的結尾

存儲字符串的物理存儲單元要比“”號括起來的字符 多一個?'\0' 的結束字 (在存儲的時候編譯器自動添加該'\0' 如果字符串結尾沒有添加)

標準庫中 strlen() 計算字符串長度是 空字符是不計入其中的'\0'

字符常量 與 字符串常量的區別

首先字符常量由' ' ?包裹 ? 字符串常量由 " " 包裹

那么 'c' 與 "c" ?里一個區別 'c' 存儲是為單個字符 ?“c” 存儲是 是兩個字符 ?字符c 與?'\0'

枚舉常量? ? 是另外類型的常量?

組成 ? ?enum + 名稱 ?+ { 枚舉值 } +;?

enum boolean {NO,YES}; ? boolean ?中的 第一個值NO 為0 ? ?第二個值為 1;

如果沒有特殊說明 ?那么 枚舉{} 中的第一個值 為 0 第二個值為1 ? 依次類推

enum months { JAN = 1,FEB,APR } ?

第一個JAN 為1,FEB =2 ?APR =3 ?默認值根據第一個枚舉值一次加1

不同枚舉類型的名字必須互不相同 ? 同一枚舉中 的枚舉值是可以重復的?

例如 : enum months { JAN = 1,FEB = 1,APR = 3 }

c語言中枚舉類型如何使用

#include <stdio.h>

enum java{

? ? day,

? ? other,

? ? app

};

int main() {

? ? ?enum java ik = -12; ? ? ? //這里 聲明的枚舉變量能不能取值在 枚舉值之外 依賴于編譯器是否對枚舉類型值 進行嚴格的檢驗?

? ? ?printf("data----->%d",ik);

? ? ? printf("data----->%d",day); ? ? ?//能夠當常量使用 ? 直接可以打印出 day的值 ? day初始值為0

? ? ?return 0;

}

一般情況下 我們需要將值取在 ?enum java{ ?} 范圍內 ?以為這樣是一定不會報錯的

初始化枚舉k 同時聲明a 變量

enum k {day=1,day1,day2} a;

2.4 聲明

所有變量都必須進行聲明,然后才能使用,一個聲明指定一種變量類型,后面跟的變量表可以包含一個或者多個該類型變量比如 int ?a,b, c,d,e; 聲明了 五個int類型的變量

他也等價于 ?int a; int b; int c; int d; int e;

初始化

如果變量名后面緊跟一個等號 以及一個表達式,該表達式就充當對變量進行初始化的初始化表達式

char ?esc = '\\';

int i = 0;

int limit = MAXLINE+1;

float eps = 1.0e-5;

1.如果變量不是自動變量(局部變量),則只能進行一次初始化操作

2.同時初始化表達式只能是常量表達式

const 限定修飾符修飾的變量 ,其變量的值是不能修改的,如果限定符修飾的是數組 則數據中的所有值都不能被修改

const ?double ?e ?= ?2.718218245905;

const ?char ?msg[ ] = "warning: ?";

2.5 算術運算符

二元算術符包括: + ?- ?* ?/ ?%(取模運運算符) ?

表達式: x%y

的結果是 x 除以 y 的余數,當x能被y整除時,其值為0?

+ ? - ??* ? / ? % ?的計算優先級與我們課本上學習的優先級一致,從左到右 先乘除后加減

但是對于一元運算符 ? ?k++ ? k-- ? ++k ? --k ? ?他們的優先級是要高于 加減乘除

2.6 關系運算符與邏輯運算符

關系運算符包括下列幾個運算符:

> ? ? ? ? ? ? ? ?>= ? ? ? ? ? ?< ? ? ? ? ? ?<=

他們具有相同的優先級 ?優先級僅次于 == ?!=

關系運算符的優先級比算術運算符低 ? ?i< lim -1 ?等價于 ?i<( lim -1 )

邏輯運算符&&與||有一些較為特殊的屬性,由&&與||連接的表達式按從左到右的順序進行求值 ? ?

得到結果為真或假后立即停止計算

if(表達式1 || 表達式2){

? ? ? ? ? xxxxxxx;

}

如果表達式1 為真 ? ?表達式2 就不進行判斷了 ?直接執行 xxxxx

if(表達式1 && 表達式2){

? ? ? ?xxxxxxxx;

}

YYYYYYY;

如果表達式1為假 ?表達式2 就不知行了 ? 直接跳過if的{} 執行下面的代碼 YYYYYY

優先級 : ? (k++ ? k-- ? ++k ? --k) 一元加減??> 乘除法 > ?加減法 ?>? (== ?!=) ?> ?(?> ? ? ? ? ? ? ? ?>= ? ? ? ? ? ?< ? ? ? ? ? ?<= ) ?> ?&& ?> ||

c語言中 邏輯表達式的值為1 表明關系為真 ? 如果值為0 則關系為假

2.7 類型轉換

包括 自動轉換 和 強制轉換

自動轉化: 一般來說 ?自動轉換 是指把 比較窄的 操作數轉換為 比較寬的操作數,

當然較寬的操作數也可以轉換為較窄的操作數,這可能會造成精度的缺失,編譯器會給我們發出警告,但這并不是非法的不可接受的

自動轉換不需要我們人為轉換,編譯器自動轉換

強制轉換:(類型名)表達式 ? ? ?比如 char a = 90; ? (int)a ?+ 1 =91;

如何正確理解強制轉換:表達式首先被賦值給類型名指定的類型的某個值,然后在用該變量替換上述整條語句

(int )a -----》 ? int ?w(強轉類型的某個變量) ?= (int)a (a轉型后的值)

w+1 = 91;

a自身的值是不改變的 ?而是 編譯器創建了一個新的變量來承接 a強轉的值

2.8 自增運算符與自減運算符

int n =5;

1. x ?= ?n++; //先賦值 后 ++ ?

2. x ?= ?++n; //先++ 后賦值

?1處的x值應該是 ?5

? 2處的x值應該是 6

最終n的值都為 6

2.9 按位運算符?

& ? ?按位與 ? ? ? ? ? ? ?----------------》規則 ? ?1&1 =1 ? 1&0 =0 ? ?0&0 = 0

| ? ? ?按位或 ? ? ? ? ? ? ? ----------------》規則 ? 1|1 = 1 ? ?1|0 = 1 ? ? 0|0 =0

^ ? ? 按位異或 ? ? ? ? ? ?----------------》規則 ? ?1^1 =0 ? ?1^0=1 ? ? 0^0 =0 ?相同為0 不同為1

<< ? 左移 ? ? ? ? ? ? ? ? ??

?---------------》規則 ? ?12<<3 ? ? 左邊轉換為二進制 0000 1100 ?<< 表示向左 ?3表示移動3位 ? 0000 1100和面補3個0? ?得到 0110 0000 ?= 96 ?

相當于 12*2^3 =96 ?一位為2倍

>> ? 右移

--------------》規則 ? ?12>>3 ? ?左邊轉換為二進制?0000 1100 >> 表示向右 3表示移動3位 ???0000 1100 ?砍掉右3位 ?

得 0000 0001 = 1 ? ? ?相當于 12/2^3=1

~ ? ? 按位求反(一元運算符) ------》規則 ? ?~1 = 0 ? ~0 =1 ? ?

~12 ?= ~(0000 1100)= 1111 0011 ? ?

要這些符號干什么用?

位運算主要是控制二進制時使用,目的是節約內存,運算速度更快,對內存要求極為苛刻的地方常會使用

這里有一句順口溜 :清零取反要用與 ? ?某位置1可用或

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 若要取反和交換 ? ?輕輕松松用異或

那么 &與運算 的作用 來看看

1.清零特定位 ? ? ? 對于0111 1111 我想是第3位(低位到高位算) 為0

0111 ?1111 ?& ?1111 ?1011 ? ---》0111 ?1011

&的這個值只要 其他位為 1 ?特定位為0 即可

2.取某數中指定位 ? ??對于0111 1111 我想是第3位(低位到高位算) 是啥

0111 1111 & 0000 0100 ?----》 0000 0100 ??

保證想要的位置為1 其他地方為0 即可

按位或 | 運算作用

將源操作數的特定位置轉換為1 ?其他位置不變 ? ? ?0011 0111 想將第4位 0 轉為1

0011 0111 | 0000 1000 ?---》0011 1111 ?

保證轉換位為1 ?其他位為0

3.異或運算作用 ^

1.使特定位取反 ? ?1變0 ? 0變1?

0111 1111 ?想使第3位 取反為0 ? ? ? ? ? ? ? ? ? ? ? ? ?0111 1011 ? ? ? ? ??

0000 0100 ? ----》 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??0000 0100

0111 ?1011 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0111 1111

只要特殊位置為 1 ?其他位置為0 即可

2.交換兩個變量的值

a = 3 = 0011 ?b = 4 = 0100 ? ? ? ? ? ? ? ? ? ? ? ? ??

1.a = a^b ? ? ? ? ? ? ? ? ? ?---> 0011 ^ 0100 = 0111 =a

2.b=b^a ? ? ? ? ? ? ? ? ? ? ?---->0100 ^ 0111 = 0011 =b

3.a = a^b =4 ? ? ? ? ? ? ? ----->0111 ^ 0011 = 0100 =a =4


2.10 賦值運算符 與 表達式

i = i+2; ? -----> ?i +=2;

+= 在運算中 就被成為賦值運算符

大多數二元運算符 ? (即有左 右兩個操作數的運算符 比如+)都有一個相應的復制運算符 op=,op可以試一下這些運算符之一

+ ?- ?* ?/ ?% ?<< ? >> ? & ?^?

如果 ?expr1 和 expr2 時表達式 ?那么 ??

expre1 ?op= expr2 ;?

等價于 ??

expr1 = (expr1) op (expr2)

x *=y+1; ? 轉化為

?x= x*(y+1);

賦值運算符的有點: 簡便 ? ?但我個人認為 i +=2; 并沒有 i=i+2;來的直觀

2.11 條件表達式

if(a>b)?

? ? ?z=a;

else

? ? z=b;

用來求ab中的最大值 并將結果保存在z中

三元表達式 ?

expr1 ? expr2 : expr3;

表達式expr1 ? ?如果成立執行expr2 ? ? 如果bu成立執行expr3

首先計算expr1的值是否不等于0 ? ? 等于1計算expr2 ? ? ? 等于0 計算expr3

z = ?(a>b)? a : b ? ?a是否大于b ?如果大于b ? ?則 z = a ? ? 如果不大于b ? z = b; ?z仍然去取 ab 間的最大值

關于類型轉化 ?(n > 0)? f : n;

如果f 為 float 類型 n是int 類型 ? 那么 ?表達式是float類型 , 它的類型與 n 無關

條件表達式的優點是:可以使代碼更加簡潔

2.12 運算符優先級與求職次序

& ? ^ ?| 的優先級低于運算符== 與 !=的 ?

所以 ? ?if((x&MASK)== 0) 必須使用( ) ?括起來才行 不然就會先執行判斷再執行&運算

c語言沒有指定同一運算符中多個操作數的計算順序(&& ? ?|| ? ? ?: ? 除外)

比如 ? x = ?f( ) + g( ); ? ? f() ?與 ?g() ?這兩個函數哪個先執行并不確定

c語言中也沒有指定函數個參數的求值順序

prinf(“%d%d\n”,++n,power(2,n));

對于先執行 ++n 還是先執行 powe(2,n) 這是不確定的 與 編譯器有關系

那么避免的方式就是 ?

n++;

prinf(“%d%d\n”,n,power(2,n));

一種令人感覺不舒服的表達方式

a[i] = i++; ? //這里存在一個問題 就是 i 使用的是 原來的值還是 i++ 后的值

這取決于編譯器的抉擇...

所以在我們編寫代碼時要盡量避免這樣的代碼設計,因為他存在極大的不確定性(在不同的編譯器中表現不相同)

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容