20180605qzd
1. C與數(shù)據(jù)
1.1 11種數(shù)據(jù)類型
- 整型類:int,short(短整型),long(長整型),unsigned(無符號(hào)),char(字符整型)
- 浮點(diǎn)類:float(單精度),double(雙精度)
- C90新增:signed(有符號(hào)),void(空)
- C99新增:_Bool(布爾值),_Complex(復(fù)數(shù)),_Imaginary(虛數(shù))
1.2 存儲(chǔ)單元
- 位:最小的存儲(chǔ)單元,存儲(chǔ)0或1
- 字節(jié):常用存儲(chǔ)單位,幾乎所有機(jī)器有1字節(jié)等于8位,即1字節(jié)可以表示0-255之間的整數(shù)
- 字:自然存儲(chǔ)單位:8位的微型計(jì)算機(jī)一字為8位,16,32位的為即一字為16位或32位
1.3 基本整型類型
- int型:儲(chǔ)存要占1個(gè)機(jī)器字長,16位機(jī)器,范圍-32768 ~ 32767目前大多數(shù)機(jī)器32位,即占4個(gè)字節(jié),存儲(chǔ)數(shù)字范圍為:-2147483648 ~ 2147483647
- short型:存儲(chǔ)小于等于int,-32768 ~ 32767
- long型:儲(chǔ)存大于等于int,-2147483648 ~ 2147483647
- long long型:存儲(chǔ)至少64位,即8個(gè)字節(jié)
- unsigned型:無符號(hào),只能存儲(chǔ)正整數(shù),能存儲(chǔ)比signed更大的整數(shù)
- 目前普遍設(shè)置:long long 64位8字節(jié),long 32位4字節(jié),short 16位2字節(jié),int 16/32位 2/4字節(jié)
- 常量:超出int范圍,視為long,超出long范圍,視為unsigned long,繼續(xù)long long, unsigned long long
- 用H/h作為short,用L/l作為long, 用LL/ll作為long long,用U/u作為unsigned,例如343H,3234L,35455LL,435345U,534546467ULL
- char型:一個(gè)字節(jié),-128 ~ 127,ASCII編碼0~127,存儲(chǔ)綽綽有余,C語言將字符常量視為int型非char型,是否有符號(hào)看編譯器
- 整型可以表示10,8,16進(jìn)制,如32,032,0x32/0X32
1.4 基本浮點(diǎn)類型
- float:至少6位有效數(shù)字,取值至少10的-37到+37次方。通常浮點(diǎn)占32位,8位指數(shù)的值和符號(hào),剩下的24位非指數(shù)的值和符號(hào)。
浮點(diǎn)最大:999999961690316250000000000000000000.000000
超過:1.#INF00 - double,至少13位有效數(shù)字。通常64位,剩下的32位給非指數(shù)部分。
- long double 更高的精確要求,至少比double精確
1.5 復(fù)數(shù)和虛數(shù)類型
- 復(fù)數(shù):float_Complex,double_Complex,long double_Complex
- 虛數(shù):float_Imaginary,double_Imaginary,long double_Imaginary
1.6 類型大小
sizeof()函數(shù)
sizeof(int),sizeof(char)等等……
1.7 問題
整型,浮點(diǎn)的上溢出,下溢出?
2. 字符串與格式化輸出輸入
2.1 字符串 string
- 字符串?dāng)?shù)組(變量)來存儲(chǔ),char name[40];
- 輸入scanf(“%s”,name) name是數(shù)組首地址
- 輸出printf(“%s”,name)
- 數(shù)組大小sizeof(name) => 40,可以寫成 sizeof name
- 字符串長度 strlen(name) =>字符實(shí)際長度
- 空字符結(jié)尾(\n)
2.2 預(yù)處理 define
- 格式 #define NAME ‘shaosuo’
- 注意是簡單的替換,沒有其他操作
2.3 限定符 const
- 明示常量:limits.h float.h
- imits/h:包含INT_MAX, INT_MIN 等預(yù)處理常量數(shù)值h
- float.h:包含FLT_MAX, FLT_MIN..
2.4 輸出函數(shù) printf()
2.4.1轉(zhuǎn)換格式
- %a/A 浮點(diǎn),16進(jìn)制,p計(jì)數(shù)
- %g/G 自動(dòng)選擇%f,%e
- %i 有符號(hào)10進(jìn)制整數(shù)
- %u 無符號(hào)10進(jìn)制整數(shù)
- %% 打印百分號(hào)
- %p 指針
- %o 無符號(hào)8進(jìn)制
- %x 無符號(hào)16進(jìn)制
2.4.2 轉(zhuǎn)換修飾符
- 標(biāo)記:-(左對(duì)齊),+(添加符號(hào)),空格(空格覆蓋正號(hào)),#(防止0被刪除),0(0填充符號(hào)位)
- 寬度:數(shù)字(最小字段寬度)(用于字段對(duì)齊,右對(duì)齊)
- 精度:.數(shù)字
- 類型:h(short),hh(char),j,l,ll,L(long double),t,z
2.4.3 返回值
#include <stdio.h>
int main(){
int a = 0, b =0;
int pn1 = printf("ok!\n"); // pn1 = 4
int pn2 = printf("ok!,%d,%d\n",a, b); // pn2 = 8
int sn1 = scanf("%d", &a, &b); // sn1 = 1
int sn2 = scanf("%d%d", &a, &b); // sn2 = 2
printf("pn1=%d, sn1=%d, pn2=%d, sn2=%d\n", pn1, sn1, pn2, sn2);
return 0;
}
- printf()返回正確按照格式變量個(gè)數(shù),即打印字符的數(shù)
- scanf()返回正確按照指定格式接收的變量個(gè)數(shù)
3. 運(yùn)算符表達(dá)式和語句
3.1 基本運(yùn)算符
- 算數(shù):(),+(取正),-(取負(fù)),+,-,*,/,%(取模),=(賦值)
- sizeof:如果對(duì)象是類型,必須加括號(hào),是變量可以不加,返回字節(jié)大小
- %取模運(yùn)算符:如13%5=3,只能用于整數(shù),不能用于浮點(diǎn)數(shù)
- 遞增(減)運(yùn)算符++(–):前綴與后綴區(qū)別,i++ => 先使用 i,再遞增,++ i => 先遞增 i,再使用
3.2 類型自動(dòng)轉(zhuǎn)換
- 普遍:較小類型轉(zhuǎn)換為較大類型
- 運(yùn)算時(shí):兩個(gè)值被分別兩種;類型的更高級(jí)別
- 高低:long double,double,float,unsigned long long,long long,unsigned long, long,unsigned int,int(int和long大小可能相同
) - 參數(shù)傳遞時(shí),char,short轉(zhuǎn)換成int,float轉(zhuǎn)化成double
- 賦值語句可能導(dǎo)致類型的升級(jí)和降級(jí)
3.3 類型強(qiáng)制轉(zhuǎn)化
- 格式:(double)a = (double)1 + (double) 1;
- 顯示使用類型轉(zhuǎn)化比較好,避免不必要的錯(cuò)誤
4. 控制語句
4.1 循環(huán)
- 關(guān)系運(yùn)算符,表達(dá)式:<,<=,==,>=,>,!=
- 真假:非0 即為真
- 注意:= 賦值,== 比較
- 優(yōu)先級(jí)關(guān)系:x > y + 2 => x = ( y + 2 )
- while語句:非計(jì)數(shù)循環(huán)
#include <stdio.h>
int main(){
char a[27] = "abcdefghijklmnopqrstuvwxyz";
int i = 0;
while( i++ < 26){
printf("%c\n", a[i-1]); //前面+1 ,-1即為真實(shí)元素
}
return 0;
}
- for語句:計(jì)數(shù)循環(huán)
- 逗號(hào)運(yùn)算符:結(jié)果為右邊的值
- 入口,出口條件:while,do while
- 嵌套循環(huán)
#include <stdio.h>
int main(){
char lets[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i, j;
for (i = 0; i < 6; i++)
{
for (j = 0; j <= i; j++)
{
printf("%c", lets[i*(i+1)/2+j]);
}
printf("\n");
}
return 0;
}
- 示例:倒序打?。╰est47.c)
#include <stdio.h>
#include <string.h>
#define MAX_LEN 255
int main(){
char a[MAX_LEN];
scanf("%s", a);
int len = strlen(a);
while(len-- > 0){
printf("%c", a[len]);
}
return 0;
}
- 示例:冒泡排序(test43.c)
void bb(int a[]){
int i, j;
for (i = 0; i < LEN -1; ++i)
{
for (j = 0; j < LEN - i - 1; ++j)
{
if(a[j] < a[j+1])
{
swap(&a[j], &a[j+1]);
}
}
}
}
4.2 分支與跳轉(zhuǎn)
- 選擇語句 if……:執(zhí)行或者跳過這條語句
- 雙選語句 if ……else:在兩條語句中進(jìn)行選擇
if(n == 0)
s = 1;
else
s = -1;
- 字符輸入輸出函數(shù):getchar(),putchar(),它們是#include中的預(yù)處理,不是真正的函數(shù)
ch = getchar(); //scanf("%c", &ch);
putchar(ch); //printf("%c", ch);
- ctype.h系列的字符函數(shù):使用時(shí)別忘記頭文件
| 函數(shù)名 | 作用 |
|---|---|
| isalnum() | 字母或數(shù)組 |
| isalpha() | 字母 |
| isblank() | 空白符 |
| isdigit() | 數(shù)字 |
| islower() | 小寫字母 |
| isupper() | 大寫字母 |
| isxdigit() | 16進(jìn)制字母 |
| tolower() | 返回小寫字母 |
| toupper() | 返回大寫字母 |
- 多重選擇if …… (else if) …… else:在多條語句中選擇,完全等價(jià)與if else多重嵌套模式
if (score <= 60)
score = 6;
else if(score <= 70 )
score = 7;
else if(score <= 80)
score = 8;
else
score = 10;
- 邏輯運(yùn)算符:&&(與), ||(或),?。ǚ牵?/li>
- 替代iso664.h:and,or,not
- 優(yōu)先級(jí):!與遞增運(yùn)算符一樣,&&大于||
- 條件運(yùn)算符: ?:
max = a > b ? a : b;
- 配對(duì):else 與最近的 if 配對(duì)
- 循環(huán)輔助continue:程序循環(huán)到一部分,可以跳過剩余部分,進(jìn)行下一輪循環(huán)
- 循環(huán)輔助break:程序循環(huán)到一部,直接跳出該層循環(huán),進(jìn)入下一階段
- 多重選擇switch ……break:可用來替代ifelse,使用break跳出,不往下繼續(xù)執(zhí)行
switch (整型表達(dá)式)
{
case 常量1:
語句
case 常量2:
語句
default:
語句
}
- 多重case標(biāo)簽
- 跳轉(zhuǎn)語句goto:避免使用goto
- 注意:“==” 不要寫成“=”,不要忘記打印結(jié)果
#include <stdio.h>
int main(){
char ch, pre;
int n = 0;
while( (ch = getchar()) != '#' ){
if(pre == 'e' && ch == 'i') //切記
n++;
pre = ch;
}
printf("%d\n", n); //切記
return 0;
}
- 綜合訓(xùn)練:注意,getchar連續(xù)輸入要去掉\n,菜單要過濾字符,退出寫在循環(huán)條件中
#include <stdio.h>
int main(){
char choice;
float fweight = 0, sweight = 0, tweight = 0;
float fcharge = 0, scharge = 0, tcharge = 0;
float weight, price, charge, orderCharge, orderWeight, account, extCharge, pay;
printf("enter a, b, c chooce your goods, q is quit:\n");
while ( (choice = getchar()) != 'q' )
{
if('\n' == choice)
continue;
if( choice == 'a' || choice == 'b' || choice == 'c' )
{
switch (choice)
{
case 'a':
price = 2.05;
printf("please enter want to buy yangli weight:\n");
scanf("%f", &weight); ;
fweight += weight;
fcharge += fweight * price;
printf("%.2f\n", fweight);
break;
case 'b':
price = 1.15;
printf("please enter want to buy taincai weight:\n");
scanf("%f", &weight);
sweight += weight;
scharge += sweight * price;
printf("%.2f\n", sweight);
break;
case 'c':
price = 1.09;
printf("please enter want to buy hulubo weight:\n");
scanf("%f", &weight);
tweight += weight;
tcharge += tweight * price;
printf("%.2f\n", tweight);
break;
default: ;
}
}
else
{
printf("pleae enter 'a', 'b', 'c' !\n");
}
printf("enter a, b, c chooce your goods, q is quit:\n");
}
orderWeight = fweight + sweight + tweight;
orderCharge = fcharge + scharge + tcharge;
account = orderCharge > 100 ? orderCharge * 0.05 : 0;
if( orderWeight <= 5 )
extCharge = 6.5;
else if( orderWeight <= 20)
extCharge = 14;
else
extCharge = 14 + (orderWeight-14) * 0.5;
pay = orderCharge + extCharge - account;
printf("******************* order ******************\n");
printf("*name-------price------weight-------charge*\n");
printf("*yang-------$2.05--------%9.2f---------$%9.2f*\n", fweight, fcharge);
printf("*tian-------$1.15--------%9.2f---------$%9.2f*\n", sweight, scharge);
printf("*hulobo-----$1.09--------%9.2f---------$%9.2f*\n", tweight, tcharge);
printf("totalWeight:%.2f, orderCharge:$%.2f", orderWeight, orderCharge);
printf("account:$%.2f, extCharge:$%.2f, pay:$%.2f\n", account, extCharge, pay);
printf("*************************************************\n");
return 0;
}
4.3 友好的交互
- 緩沖區(qū):字符被收集存儲(chǔ)的臨時(shí)存儲(chǔ)區(qū)(是否有無緩沖輸入取決于系統(tǒng))正常的都是有緩沖輸入
graph LR
typeHI!-->|無緩沖區(qū)程序立即使用| HI!
typeHI!-->|緩沖區(qū)| HI!
- 結(jié)束鍵盤輸入:文件,流,鍵盤輸入
#include <stdio.h>
int main(){
char ch;
while( (ch =getchar()) != '#')
{
putchar(ch);
}
}
使用的#字符可能會(huì)被我們用到,使用#退出并不一定起作用
c語言把輸入輸出設(shè)備,視為文件,stdin流表示鍵盤輸入,stdout流表示顯示輸出
使用文件的形式來結(jié)束鍵盤的輸入
- 文件結(jié)尾:Ctrl+Z(曾經(jīng)操作系統(tǒng)),存儲(chǔ)文件大小信息,EOF(C語言)
#define EOF -1 //stdio.h定義的
while( (ch =getchar()) != EOF)
- getchar()返回int,可能會(huì)報(bào)信息,但不影響putchar()輸出字符
- 正確的使用是找到操作系統(tǒng),文件終止符識(shí)別方案,大多數(shù)是Ctrl+D,有些是Ctrl+Z
- EOF不要加字符的‘’
- 重定向和文件:把stdin流重新賦給文件,主要問題與操作系統(tǒng)有關(guān)
testFileIO < words // UNIX與DOS 輸入重定向
testFileIO > mywords //輸出重定向 DOS Ctrl+Z結(jié)束,UNIX Ctrl+D結(jié)束
testFileIO < words > mywords //組合重定向
不能讀多個(gè)文件,也不能寫多個(gè)文件,空格不是必須的,寫入的會(huì)把之前的覆蓋掉
- 友好的用戶界面
丟棄換行符兩種方式比較
if (ch == '\n') //當(dāng)輸入的字符為換行符時(shí),直接跳入下一輪循環(huán)
continue;
while( getchar() != '\n' ) //只要輸入的字符不為換行符進(jìn)入下一輪循環(huán)
continue;
問題來了?為什么用第二種不用第一種?
- 混合字符數(shù)字輸入:
1.驗(yàn)證輸入正確性2.丟棄換行符
if(2 != scanf("%d%d", &a, &b))
break;
- 輸入驗(yàn)證:
事先預(yù)測可能輸入,檢測和處理
while( scanf("%ld", &n) == 1 && n > 0 ) //驗(yàn)證正整數(shù)
- 模塊化編程:用單獨(dú)的函數(shù),驗(yàn)證輸入和管理顯示
#include <stdio.h>
void count();
int get_int();
char get_first();
char get_choice();
int main(){
char choice;
count();
while( (choice = get_choice()) != 'q' ){
switch (choice){
case 'a':
printf("buy low, sell high\n");
break;
case 'b':
printf("\a\n");
break;
case 'c':
count();
break;
default:
printf("error!!!\n");
break;
}
}
return 0;
}
//計(jì)數(shù)
void count(){
int n, i;
printf("Count how far?\n");
n = get_int();
for (int i = 0; i <= n; ++i)
{
printf("%d\n", i);
}
while( getchar() != '\n' )
continue;
}
//異常處理
int get_int(){
int n;
char ch;
while( scanf("%d", &n) != 1 ){
while( getchar() != '\n')
putchar(ch);
printf("is not a integer!!!\n");
}
return n;
}
//過濾換行符
char get_first(){
char choice;
choice = getchar();
while( getchar() != '\n' )
continue;
return choice;
}
//刪選合適的字符
char get_choice(){
char choice;
printf("please enter a, b, c\n");
choice = get_first();
while( (choice < 'a' || choice > 'c') && choice != 'q'){
printf("please enter correct code!!\n");
choice = get_first();
}
return choice;
}
- 實(shí)戰(zhàn)例子(test57.c):統(tǒng)計(jì)文件字符數(shù)
#include <stdio.h>
#include <ctype.h>
int main(){
char ch;
int count = 0;
while( (ch = getchar()) != EOF )
{
if(isblank(ch) || ch == '\n')
continue;
count++;
}
printf("count : %d\n", count);
return 0;
}
- 實(shí)戰(zhàn)例子(test61.c):二分查找找1-100中的數(shù)
#include <stdio.h>
int main(){
int ran, lower = 1, upper = 100, i = 0;
int smart = (lower + upper) / 2;
printf("please enter 1 ~ 100 a integer:");
scanf("%d", &ran);
while( ran != smart){
if(ran < smart)
upper = smart;
else
lower = smart;
i++;
printf("though %d times = %d\n", i, smart);
smart = (lower + upper) / 2;
}
printf("though %d times = %d\n", i+1, smart);
return 0;
}