---------------------------------------------------------------------------------
【C語言的類型】
整數:
char, short, int, long, long long
浮點數:
float,double,long double
邏輯:
bool
指針
自定義類型
【類型有什麼不同】
類型名稱:int,long,double
輸入輸出時的格式化:%d,%ld,%lf
所表達的數的范圍:char < short < int < float < double
內存中所占據的大小:1個字節到16個字節,使用sizeof()得到大小,sizeof是靜態運算符,它的結果在編譯時刻就決定了,sizeof的運算不會計算。
內存中的表達形式:二進制數(補碼),編碼
【整數類型】
// main.c
// Created by weichen on 15/3/25.
// Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>
int main(int argc, const char * argv[]) {
printf("sizeof(char)=%ld\n", sizeof(char)); //1 字節(8bite)
printf("sizeof(short)=%ld\n", sizeof(short)); //2 字節
printf("sizeof(int)=%ld\n", sizeof(int)); //4 取決於編譯器(cpu),通常的意義是“1個字”
printf("sizeof(long)=%ld\n", sizeof(long)); //8 取決於編譯器(cpu),通常的意義是“1個字”
printf("sizeof(long long)=%ld\n", sizeof(long long));//8 8字節
//gcc ./test.c -o -m32 #以32平台架構編譯顯示
char c = 255;
int i = 255;
printf("c=%d, i=%d\n", c, i); //c=-1, d=255
unsigned char d = 255; //用來表示整數不以補碼的形式表示,看做純二進制
printf("d=%d\n", d); //d=255
char e = 127;
e = e + 1;
printf("e=%d\n", e); //-128
unsigned char f = 127;
f = f + 1;
printf("f=%d\n", f); //128
return 0;
}
//int 是用來表達寄存器的
/*
計算機以二進制表達正整數,表達負數用補碼:
0 -> 00000000
1 -> 00000001
11111111 + 00000001 -> 1000000000 \
|
00000000 - 00000001 -> (負1) |
|
(1)00000000 - 00000001 -> 11111111 /
① 11111111被當做純二進制時,是255,被當作補碼時,是-1
② 同樣,對於-a,實際是(2^n - 1),n是這種類型的位數;補碼是0-a
③ 補碼的意思是拿補碼和原碼可以加出一個溢出的“零”
*/
//數的范圍
/*
一個字節(8位),表達的是:
00000000 - 11111111
其中,00000000 -> 0
11111111 ~ 10000000 -> -1 ~ -128 //用補碼表示
00000001 ~ 01111111 -> 1 ~ 127 //純二進制表示
*/
//unsigned
/*
如果一個字面量常數想要表達自己是unsigned,可以在後面加u或U
255U
用l或L表示long(long)
unsigned的初衷並非擴展數能表達的范圍,而是為了做純二進制運算,主要是為了移位。
*/
//整數越界
/*
整數是以純二進制方式進行計算的,所以:
11111111 + 1 -> 100000000 -> 0
01111111 + 1 -> 10000000 -> -128
10000000 - 1 -> 01111111 -> 127
*/
//整數的輸入輸出
/*
只有兩種形式:int或long long
%d:int
%u:unsigned
%ld:long long
%lu:unsigned long long
*/
//8進制和16進制
/*
一個以0開始的數字字面量是8進制
一個以0x開始的數字字面量是16進制
%o用於8進制,%x用於16進制
8進制和16進制只是如何把數字表達為字符串,與內部如何表達數字無關
16進制很適合表達二進制數據,因為4位二進制正好是一個16進制位
8進制的一位數字正好表達3位二進制
因為早期計算機的字長是12的倍數,而非8
*/
//選擇整數類型
/*
為什麼整數要有那麼多種?
為了准確表達內存,做底層程序的需要
沒有特殊需要,就選擇int
現在的CPU的字長普遍是32位或64位,一次內存讀寫就是一個int,一次計算也是一個int,選擇更短的類型不會更快,甚至可能更慢
現代的編譯器一般會涉及內存對齊,所以更短的類型實際在內存中有可能也占據一個int的大小(雖然sizeof告訴你更小)
unsigned與否只是輸出的不同,內部計算是一樣的,所以現代高級語言大多已不區分非負。
*/
【浮點類型】
// main.c
// Created by weichen on 15/4/6.
// Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>
int main(int argc, const char * argv[]) {
// 浮點類型
/*
類型 字長 范圍 有效數字
float 32 ±(1.20*10^-38 ~ 3.40*10^38), 0, ±inf(無窮大), nan(非數字) 7(准確的位數)
double 64 ±(2.2*10^-308 ~ 1.79*10^308),0, ±inf, nan 15
類型 scanf printf
float %f %f,%e(科學計數法)
double %lf %f,%e
*/
double ff = 12.345;
printf("%e, %f\n", ff, ff); //1.234500e+01, 12.34500
printf("%E\n", ff); //1.234500E+01
//在%和f之間加上.n可以指定輸出小數點後幾位,這樣的輸出是做四捨五入的
printf("%.3f\n", -0.0049); //-0,005 小數點後保留三位
printf("%.30f\n", -0.0049); //-0.004899999999999999841793218991
printf("%.3f\n", -0.00049); //0.000
printf("%f\n", 1.0/0.0); //inf
printf("%f\n", -1.0/0.0); //-inf
printf("%f\n", 0.0/0/0); //nan
//printf("%d\n", 12/0); //無法編譯通過,無窮大無法用整數表達,可以用浮點數表達
float a, b, c;
a = 1.34f;
b = 1.22f;
c = a + b;
if( c == 2.56) {
printf("a = b\n");
} else {
printf("a != b, c=%.10f 或 %f\n", c, c); //a != b, c=2.5599999428 或 2.560000(七位有效數字四捨五入而來)
}
//浮點運算的精度
/*
帶小數點的字面量是double而非float
float需要用f或F後綴來表明身份
float1 == float2 可能失敗
fabs(f1-f2) < 1e^-12 #計算絕對值與最小誤差比較,來判斷是否相等
*/
//浮點數的內部表達
/*
浮點數在計算時是由專用的硬件部件實現的
計算double和float所用的部件是一樣的
*/
//選擇浮點類型
/*
如果沒有特殊需要,只使用double
現代CPU能直接對double做硬件運算,性能不會比float差,在64位的機器上,數據存儲的速度也不比float慢
*/
return 0;
}
【邏輯類型】
// main.c
// Created by weichen on 15/4/8.
// Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>
#include <stdbool.h>
int main(int argc, const char * argv[]) {
// bool
/*
C語言本沒有邏輯類型,在內部計算中使用整數表達關系運算和邏輯運算的結果,0表示false,而非0的值表示true。
在C99中,也沒有固定的邏輯類型,但是通過一個頭文件定義了可以直接使用的true和false這兩個值,以及bool這個類型。
邏輯運算則是C語言固有的成分。
#include <stdbool.h>
之後就可以使用bool和true、false
*/
bool a = 6 < 5;
bool b = true;
printf("%d\n", a); //0
printf("%d\n", b); //1
//邏輯運算
/*
邏輯運算是對邏輯量進行的運算,結果只有0或1
邏輯量是關系運算或邏輯運算的結果
! 邏輯非
&& 邏輯與
|| 邏輯或
如果要表達數學中的區間,如:x∈(4,6) 或 x∈[4,6] 應該如何寫C的表達式?
像 4 < x < 6 這樣的式子,不是C能正確計算的式子,因為 4 < x 的結果是一個邏輯值(0或1),
應該寫成 (x > 4 && x < 6) 或 (x >= 4 && x <= 6)
判斷一個字符a是否是大寫字母? a >= 'A' && a <= 'Z'
優先級 運算符 結合性
1 () 從左到右
2 ! + - ++ -- 從右到左(單目+和-)
3 * / % 從左到右
4 + - 從左到右
5 < <= > >= 從左到右
6 == != 從左到右
7 && 從左到右
8 || 從左到右
9 = += -= *= /= %= 從右到左
*/
return 0;
}
【類型轉換與條件運算】
// main.c
// Created by weichen on 15/4/8.
// Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>
int main(int argc, const char * argv[]) {
//自動類型轉換
//當運算符的兩邊出現不一致的類型時,會自動轉換成較大的類型,能表達范圍更大的數
//char -> short -> int -> long -> long long
//int -> float -> double
//對於printf,任何小於int的類型會被轉換成int;float會被轉換成double
//但是sachf不會,要輸入short,需要%hd,要輸入long long,需要%ld。
// 強制類型轉換的優先級高於四則運算
//1. (類型)值
double a = 1.0;
double b = 2.0;
int i = (int)a/b;
int j = (int)(a/b);
int c = 5;
int d = 6;
double e = (double)(c/d);
printf("%d\n", i);
printf("%d\n", j);
printf("%lf\n", e);
//2. 小的變量不總能表達大的量
printf("%d\n", (short)32768); //-32768,short最多能表示32767
printf("%d\n", (char)32768); //0
//3. 強制類型轉換只是從那個變量計算出了一個新的類型的值,它並不改變那個變量,無論是值還是類型都不改變
int k = 32768;
short kk = (short)k;
printf("%d\n", k); //32768
//條件運算符
//c = (count > 20) ? count - 10 : count + 10;
//條件運算符的優先級高於賦值運算符,但是低於其他運算符
//逗號運算符
//逗號用來連接兩個表達式,並以其右邊的表達式的值作為它的結果。逗號的優先級是所有的運算符中最低的,所以它兩邊的表達式會先計算;逗號的組合關系是自左向右,所以左邊的表達式會先計算,而右邊的表達式的值就留下來作為逗號運算的結果。
//在for中使用, for(i=0,j=0;i<j;i++,j--){},這裡逗號劃分兩個表達式。
int n;
int m;
n = 1+2,3+4; //n=1+2是一個表達式,3+4沒有用到,最終結果是3
m = (1+2,3+4); //組合關系,右邊表達式的值作為結果
printf("%d\n", n); //3
printf("%d\n", m); //7
return 0;
}
Link:http://www.cnblogs.com/farwish/p/4382543.html
@黑眼詩人 <www.farwish.com>