日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

逆向基础之C语言 第一篇

發(fā)布時(shí)間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 逆向基础之C语言 第一篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

逆向之C語言

  • 00_C語言概述
    • 知識(shí)點(diǎn)1 【寫代碼的過程】
      • Visual C++ 6.0
        • 安裝VC6.0
        • 配置兼容性
        • 創(chuàng)建c工程
        • 添加源文件
    • 知識(shí)點(diǎn)2 【完整的C代碼分析】
      • 1、案例1:hello iot
      • 2、案例2:求圓的面積
      • 3、案例3:用分函數(shù)的方式求兩個(gè)數(shù)的和
  • 01_C語言的基本語法
    • 知識(shí)點(diǎn)1【數(shù)據(jù)類型】
      • 案例:驗(yàn)證數(shù)據(jù)類型的長(zhǎng)度
    • 知識(shí)點(diǎn)2【unsigned和signed】(重要)
      • 1、無符號(hào)數(shù)unsigned
      • 2、有符號(hào)數(shù)signed 默認(rèn)一般省略
    • 知識(shí)點(diǎn)3 【結(jié)構(gòu)體struct 和 共用體union】
      • 1、struct 結(jié)構(gòu)體中的 成員擁有 獨(dú)立的空間
      • 2、union 共用體中的成員 共享同一份空間
    • 知識(shí)點(diǎn)4【enum枚舉 和 void無類型】
    • 知識(shí)點(diǎn)5【其他關(guān)鍵字】(了解)
      • 1、register 寄存器變量
      • 2、typedef 為已有的類型取一個(gè)別名
      • 3、volatile 防止編譯器優(yōu)化 強(qiáng)制訪問內(nèi)存操作
    • 知識(shí)點(diǎn)6 【常量與變量】(重要)
      • 1、常量 值不能被修改 (千萬不能反過來說:值不能被修改的就是常量X)
      • 2、變量 系統(tǒng)根據(jù)變量的類型 開辟對(duì)應(yīng)的空間 其值可以被修改
    • 知識(shí)點(diǎn)7【八進(jìn)制 十進(jìn)制 十六進(jìn)制】
    • 知識(shí)點(diǎn)9 【整型變量的操作 - 讀(取值)、寫(賦值)】
      • 1、取值與賦值——讀寫操作
      • 2、整型的輸出形式
    • 知識(shí)點(diǎn)10 【實(shí)型 常量】
    • 知識(shí)點(diǎn)11 【字符常量和變量】(重要)
      • 1、字符常量char
        • 案例: 鍵盤輸入“abc”,只取‘a(chǎn)’和‘c’
    • 知識(shí)點(diǎn)12 【轉(zhuǎn)義字符】
    • 知識(shí)點(diǎn)13 【字符串】“”雙引號(hào)作用
    • 知識(shí)點(diǎn)14 【輸出的格式回顧】(了解)
    • 知識(shí)點(diǎn)15 【typedef】
  • 02_C語言的基本語句
    • 知識(shí)點(diǎn)1【數(shù)據(jù)類型轉(zhuǎn)換】
      • 1、自動(dòng)類型轉(zhuǎn)換(保證精度不丟失)
        • **轉(zhuǎn)化的方向**
        • 案例:有符號(hào)和無符號(hào)的轉(zhuǎn)換
        • 案例:int和double的轉(zhuǎn)換
        • 案例:char和short的類型轉(zhuǎn)換
      • 2、強(qiáng)制類型轉(zhuǎn)換
    • 知識(shí)點(diǎn)2 【運(yùn)算符】
      • 1、算術(shù)運(yùn)算符(+、-、*、/、%)
        • 案例:鍵盤輸入一個(gè)數(shù) ,是否能被3整除
      • 2、邏輯運(yùn)算符(!、&&、||)
        • ① 邏輯非 ——!0 == 真 、 !真 == 假
        • ② 邏輯與 &&(重要)
        • ③邏輯或 ||
        • 綜合案例:
    • 知識(shí)點(diǎn)3 【位運(yùn)算符】二進(jìn)制位操作(<< 、>> 、& 、| 、~ 、^)
      • &:按位與
      • |:按位或
        • 案例:將1010 1010的第2、3位變成1,其他不變
      • ~:按位取反
      • ^:按位異或 (重要)
        • 案例:將1010 1010的第0位發(fā)生翻轉(zhuǎn)(要將哪位翻轉(zhuǎn),就將它與1異或)
      • <<:左移運(yùn)算符(左邊丟棄,右邊補(bǔ)0)
      • >>:右移運(yùn)算符
    • 知識(shí)點(diǎn)4【三目運(yùn)算符】?:
      • 案例
    • 知識(shí)點(diǎn)5【逗號(hào)運(yùn)算符】
      • 案例:逗號(hào)運(yùn)算符
    • 知識(shí)點(diǎn)6【符合運(yùn)算符】
      • 案例
    • 知識(shí)點(diǎn)7【自增自減 運(yùn)算符】
    • 知識(shí)點(diǎn)7【優(yōu)先級(jí)】分析已有的代碼
    • 知識(shí)點(diǎn)8【if 語句】
      • 1、如果只在乎項(xiàng)目的一個(gè)結(jié)果,選擇if
      • 2、如果項(xiàng)目只有**兩種結(jié)果**,且**不會(huì)同時(shí)出現(xiàn)**。請(qǐng)選擇if....else....
      • 3、如果一個(gè)項(xiàng)目 有多個(gè)結(jié)果 且不同時(shí)出現(xiàn)。選擇if....else if...else if...else
      • 4、一個(gè)項(xiàng)目有多個(gè)結(jié)果,不確定是否同時(shí)出現(xiàn)
    • 知識(shí)點(diǎn)9【switch 選擇語句】
      • 案例:有時(shí)候break可以省略
  • 03_循環(huán)語句及數(shù)組
    • 知識(shí)點(diǎn)1 【for循環(huán)】
      • 案例: 求1~100的和
      • 案例:
      • 案例:break只能跳出離它最近的一層循環(huán)
      • continue
      • 案例:求出0~100的所有偶數(shù)的和
      • break和continue的區(qū)別
      • 循環(huán)嵌套循環(huán)
    • 知識(shí)點(diǎn)2【while 循環(huán) 和 do...while 循環(huán)】
      • 案例:
      • 案例
    • 知識(shí)點(diǎn)3【goto 跳轉(zhuǎn)】(慎用!)
    • 知識(shí)點(diǎn)4【數(shù)組的概述】
    • 知識(shí)點(diǎn)5【一維數(shù)值數(shù)組】
      • 1、數(shù)組的定義
        • 案例1:遍歷數(shù)組
        • 案例2:數(shù)組的初始化
          • 全部初始化:
          • 部分初始化:
          • 拓展:特殊初始化
      • 2、數(shù)組的空間大小(重要)
        • 遍歷數(shù)組
        • 案例:
      • 3、數(shù)組元素的操作
        • 案例:定義一個(gè)數(shù)組 5個(gè)元素,每個(gè)元素int類型,獲取鍵盤輸入
        • 作業(yè):定義一個(gè)數(shù)組 5個(gè)元素,每個(gè)元素int類型,獲取鍵盤輸入,請(qǐng)求出數(shù)組的最大值,最小值,平均值。
    • 知識(shí)點(diǎn)6【二維數(shù)組】
      • 1、二維數(shù)組的定義
        • 二維數(shù)組的遍歷:
        • 案例:
      • 2、二維數(shù)組的初始化
        • 分段初始化:用大括號(hào)里面的大括號(hào),明確的表示一行
        • 連續(xù)初始化:放滿一行才能放下一行
        • 案例:
  • 04_數(shù)組與函數(shù)
    • 知識(shí)點(diǎn)1 【作業(yè)講解】
        • **作業(yè):定義int arr[3][4]的二維數(shù)組,獲取鍵盤輸入,并求出每一行的平均值。**
        • 案例:求每一列的平均值
    • 知識(shí)點(diǎn)2 【字符數(shù)組】(重要)
      • 字符數(shù)組的初始化
      • 字符數(shù)組的遍歷
        • 逐個(gè)字符初始化和字符串初始化的區(qū)別
      • 字符數(shù)組獲取鍵盤的字符串
        • scanf和%s使用的時(shí)候有個(gè)缺點(diǎn),遇到**空格**會(huì)結(jié)束輸入
        • **gets()缺點(diǎn):獲取鍵盤輸入的時(shí)候,不會(huì)管buf的大小,容易造成內(nèi)存污染**
        • fgets():既可以獲取帶空格的字符串,也可以保證buf的不越界
          • 案例:
          • 提高案例:字符串的大小寫的轉(zhuǎn)換
    • 知識(shí)點(diǎn)3【二維字符數(shù)組】(了解)
      • 二維字符數(shù)組獲取鍵盤輸入的字符串:
    • 知識(shí)點(diǎn)4 【函數(shù)概述】
      • 1、函數(shù)的定義
      • 2、函數(shù)的聲明
      • 3、函數(shù)的調(diào)用
    • 知識(shí)點(diǎn)5 【函數(shù)的參數(shù)】
      • 1、如果函數(shù)的形參什么都不寫 在調(diào)用的時(shí)候可以傳實(shí)參,只是實(shí)參得不到使用
      • 2、如果函數(shù)沒有參數(shù),請(qǐng)將形參寫成void
      • 3、函數(shù)參數(shù)的傳遞

00_C語言概述


知識(shí)點(diǎn)1 【寫代碼的過程】

編輯器:程序員寫代碼的過程(記事本、VC6.0、vim…)(讓程序員看懂)
編譯器:查看代碼的語法錯(cuò)誤,生成匯編語言。
匯編器:將生成好的匯編語言生成二進(jìn)制語言(也叫做目標(biāo)文件)
連接器:將生成好的二進(jìn)制語言+用到的庫(kù)+啟動(dòng)代碼=====>可執(zhí)行文件

  • Windows開發(fā)特點(diǎn):
    • 在電腦上裝一個(gè)VC或者其他集成開發(fā)環(huán)境
    • 編輯程序——》編譯程序——》看現(xiàn)象——》有問題——》修改程序——》調(diào)試程序 ——》看現(xiàn)象
  • Linux開發(fā)特點(diǎn):
    • Linux下程序開發(fā)大多數(shù)通過在本地安裝虛擬機(jī)、物理機(jī)或者網(wǎng)絡(luò)連接到服務(wù)器完成
    • 出于效率、遠(yuǎn)程開發(fā)、嵌入式開發(fā)的考慮:開發(fā)方式太多 是在命令行下完成,沒有很好的集成開發(fā)環(huán)境供我們使用

Visual C++ 6.0

安裝VC6.0

Visual C++6.0下載地址:https://pan.baidu.com/s/1UoyJD6FUARS2EvDdC9l7qA 提取碼: 1314.
解壓?jiǎn)螕舭惭b即可,默認(rèn)下一步

配置兼容性

  • 鼠標(biāo)右鍵點(diǎn)擊桌面生成的快捷方式,選擇屬性
  • 點(diǎn)擊兼容性,找到兼容模式的位置,在“以兼容模式運(yùn)行這個(gè)程序”前打勾,在下方下拉菜單中選擇Windows XP(Service Pack3),點(diǎn)擊確定即可
    -

創(chuàng)建c工程

打開VC6.0,關(guān)閉每日提示
文件——》新建——》工程——》win32 console Application控制臺(tái)程序——》確定

從0開始學(xué),選擇一個(gè)空工程——》完成

單擊FileView就可以看到工程的目錄結(jié)構(gòu)

添加源文件

文件——》新建——》文件——》C++ Source File——》寫文件名(后綴名為.C,若不寫則默認(rèn)為.cpp為C++源文件)——》確定



知識(shí)點(diǎn)2 【完整的C代碼分析】

1、案例1:hello iot

# include<stdio.h> //std是標(biāo)準(zhǔn)的意思 i表示輸入 o表示輸出(標(biāo)準(zhǔn)的輸入輸出頭文件) // 雙斜杠//是行注釋 /**/是塊注釋,注意塊注釋不能嵌套//()里面的是函數(shù)的形參(函數(shù)外部將數(shù)據(jù)傳遞到函數(shù)內(nèi)部的橋梁) int main(int argc, char *argv[]) //main主函數(shù) 是程序的入口,有且僅有一個(gè)主函數(shù) //main左邊的int代表的是函數(shù)的返回類型 {// 使用任何東西 必先存在printf("hello iot\n");// printf來自系統(tǒng)庫(kù)文件,printf:將雙引號(hào)的字符串輸出(o)到終端上return 0;//0是一個(gè)int類型 } //{}函數(shù)的功能都在大括號(hào)里面實(shí)現(xiàn),每敲一行代碼記得用tab縮進(jìn),不要用空格 //分號(hào)是C語言的結(jié)束標(biāo)記 //如果你的代碼一閃而過 可以用帶阻塞的代碼 getchar(); // int char return都是關(guān)鍵字

總結(jié):
1、main有且只有一個(gè)
2、printf的頭文件是stdio.h
3、注釋 行注釋和塊注釋(塊注釋不能嵌套)

調(diào)整VC6.0字體大小:工具——》選項(xiàng)——》三角符號(hào)往后點(diǎn)有個(gè)格式——》選擇原窗口——》選擇合適大小

2、案例2:求圓的面積

知道的條件:半徑r
算法:面積=πrr
解析步驟:
①r通過鍵盤輸入或者用特定的值
②定義一個(gè)面積變量 area=πrr
③將圓的面積輸出到終端上

# include <stdio.h> # define PI 3.14 //定義一個(gè)宏 建議用大寫表示(和普通變量區(qū)分開)int main(int argc,char *argv[]) {float r=0.0f;//定義一個(gè)r變量 系統(tǒng)給r開辟4字節(jié)的空間float area=0.0f;//定義一個(gè)面積變量//獲得半徑 從鍵盤獲得scanf(要使用必先存在)printf("請(qǐng)輸入圓的半徑r:");scanf("%f",&r); //對(duì)r變量取地址 scanf是帶阻塞的//測(cè)試//printf("r=%f\n",r);//測(cè)試有沒有得到r//算法:計(jì)算面積 area=PI * r * r 要使用面積就要先存在//float area=0.0f; //在VC6.0中不能這樣定義(必須在語句的前方),在visual studio就沒有這個(gè)問題area=PI*r*r;//將面積輸出 %.2f中的.2表示小數(shù)部分保留兩位printf("area=%.2f\n",area);return 0; } //不同的代碼之間一定要空個(gè)行,這樣代碼更整潔


運(yùn)行結(jié)果

3、案例3:用分函數(shù)的方式求兩個(gè)數(shù)的和

步驟分析:
1、定義兩個(gè)變量data1、data2 獲取鍵盤輸入

2、定義一個(gè)函數(shù) 去計(jì)算上面兩個(gè)變量data1、data2的和
在函數(shù)內(nèi)部計(jì)算計(jì)算(怎么將數(shù)據(jù)傳遞到函數(shù)內(nèi)部?)
需要用形參 將data1 data2傳遞到函數(shù)內(nèi)部

3、得到函數(shù)的計(jì)算結(jié)果(怎么得到呢?)
通過函數(shù)的返回值 得到函數(shù)的計(jì)算結(jié)果

#include<stdio.h>int add_fun(int a,int b) //ret是整型 data1和data2也是整型 {return a+b; } int main(int argc, char *argv[]) {//定義兩個(gè)變量 獲取鍵盤輸入//int data1=0;//int data2=0;int data1=0,data2=0;int ret=0; //定義一個(gè)ret去存放函數(shù)結(jié)果printf("請(qǐng)輸入兩個(gè)int變量:");scanf("%d %d",&data1,&data2);//門牌號(hào)?//函數(shù)的調(diào)用ret=add_fun(data1,data2);// a=data1 b=data2//輸出ret的結(jié)果printf("ret=%d\n",ret);return 0; }

運(yùn)行結(jié)果:

01_C語言的基本語法


知識(shí)點(diǎn)1【數(shù)據(jù)類型】

數(shù)據(jù)分為不同類型 是為了 更加合理的利用內(nèi)存空間
計(jì)算機(jī)存儲(chǔ)的是二進(jìn)制,一位二進(jìn)制只能存放0或者1(低電平或高電平)
1byte=8bit (0000 0000~ 1111 1111)
1kb=1024byte 10月24日是程序員節(jié)
1MB=1024kb
1GB=1024MB
1TB=1024GB
1PB=1024TB
1EB=1024PB

-----------------------------------在32位平臺(tái)-----------------------------------------
char 字符類型 占1個(gè)字節(jié) (8個(gè)二進(jìn)制位)
short 短整型 占2個(gè)字節(jié) (16個(gè)二進(jìn)制位)
int 整型 占4個(gè)字節(jié)(32個(gè)二進(jìn)制位)
long 長(zhǎng)整型 占4字節(jié)空間(32個(gè)二進(jìn)制位)
float 單精度浮點(diǎn)型 占4字節(jié)空間(32個(gè)二進(jìn)制位)
double 雙精度浮點(diǎn)型 占8字節(jié)空間(64個(gè)二進(jìn)制位)

-----------------------------------在64位平臺(tái)-----------------------------------------
char 字符類型 占1個(gè)字節(jié) (8個(gè)二進(jìn)制位)
short 短整型 占2個(gè)字節(jié) (16個(gè)二進(jìn)制位)
int 整型 占4個(gè)字節(jié)(32個(gè)二進(jìn)制位)
long 長(zhǎng)整型 占8字節(jié)空間(64個(gè)二進(jìn)制位)
float 單精度浮點(diǎn)型 占4字節(jié)空間(32個(gè)二進(jìn)制位)
double 雙精度浮點(diǎn)型 占8字節(jié)空間(64個(gè)二進(jìn)制位)

案例:驗(yàn)證數(shù)據(jù)類型的長(zhǎng)度

sizeof是測(cè)量類型的長(zhǎng)度

#include<stdio.h> int main(int argc,char *argv[]) {printf("sizeof(char)=%d\n",sizeof(char));printf("sizeof(short)=%d\n",sizeof(short));printf("sizeof(int)=%d\n",sizeof(int));printf("sizeof(long)=%d\n",sizeof(long));printf("sizeof(float)=%d\n",sizeof(float));printf("sizeof(double)=%d\n",sizeof(double));return 0; }

運(yùn)行結(jié)果:


知識(shí)點(diǎn)2【unsigned和signed】(重要)

1、無符號(hào)數(shù)unsigned

數(shù)據(jù)沒有符號(hào)位,自身所有二進(jìn)制位都是數(shù)據(jù)位
比如:unsigned char ——》 0000 0000~ 1111 1111

2、有符號(hào)數(shù)signed 默認(rèn)一般省略

二進(jìn)制的最高位為符號(hào)位,其他為是數(shù)據(jù)位
signed char ——》 xxxx xxxx(x為0或1)
最高位為1表示負(fù)數(shù),最高位為0表示正數(shù)
比如:一個(gè)字節(jié): -10==1000 1010

案例:

#include<stdio.h> int main(int argc,char *argv) {//定義一個(gè)有符號(hào)intsigned int num1=10; //系統(tǒng)給num1開辟4字節(jié)的空間(這個(gè)4字節(jié)的最高位是符號(hào)位)// signed 默認(rèn)是省略的(推薦)int num2=10; //num2也是有符號(hào)數(shù)//unsigned表示無符號(hào)數(shù) 不能省略unsigned int num3=10;return 0; }

知識(shí)點(diǎn)3 【結(jié)構(gòu)體struct 和 共用體union】

1、struct 結(jié)構(gòu)體中的 成員擁有 獨(dú)立的空間

struct data1{char a;short b;int c; }; a b c就是結(jié)構(gòu)體data1中的成員

2、union 共用體中的成員 共享同一份空間

union data2{ char a; short b; int c; };



知識(shí)點(diǎn)4【enum枚舉 和 void無類型】

1、enum枚舉 將變量要賦值的值一一列舉出來
enum BOOL(false,true);
enum BOOL bool=false;

2、void 無類型 (重要)
不能用void定義變量
int num; // √
void num; //X 系統(tǒng)不能確定給num開辟多大的空間


知識(shí)點(diǎn)5【其他關(guān)鍵字】(了解)

auto 自動(dòng)類型 ,register 寄存器變量,static 靜態(tài)變量,const 只讀變量
sizeof 測(cè)類型的大小
typedef 為已有的類型 重新取一個(gè)別名
volatile 防止編譯器優(yōu)化

1、register 寄存器變量


總結(jié):
1、如果沒有顯示表明register,就類似int num,如果num被高頻繁使用系統(tǒng)也會(huì)放入寄存器中。
2、register int num; //顯示的將num放入寄存器中
3、寄存器的變量不能取地址 &num(X)

#include<stdio.h> int main(int argc,char *argv[]){register int num=10;// %p輸出地址printf("%p\n",&num); //**錯(cuò)誤**,不能對(duì)寄存器變量 取地址//我們講的是內(nèi)存地址,寄存器已經(jīng)不在內(nèi)存中,怎么取地址?return 0; }

2、typedef 為已有的類型取一個(gè)別名

#include<stdio.h> void test01() { register int num=10;// %p輸出地址//printf("%p\n",&num); //**錯(cuò)誤**,不能對(duì)寄存器變量 取地址 }typedef int INT32; //給已有的int類型 取了一個(gè)別名叫INT32 void test02() {int num1=10;INT32 num=20;printf("num1=%d\n",num1);printf("num2=%d\n",num2); }int main(int argc,char *argv[]){test02();//想運(yùn)行那個(gè)就寫哪個(gè)return 0; }

3、volatile 防止編譯器優(yōu)化 強(qiáng)制訪問內(nèi)存操作



知識(shí)點(diǎn)6 【常量與變量】(重要)

1、常量 值不能被修改 (千萬不能反過來說:值不能被修改的就是常量X)

10 20 4.14 ‘a(chǎn)’ “abv”

2、變量 系統(tǒng)根據(jù)變量的類型 開辟對(duì)應(yīng)的空間 其值可以被修改

變量名num代表的是空間的內(nèi)容
操作變量名就是對(duì)空間 內(nèi)容 的操作

變量名的命名規(guī)則:由數(shù)字字母下劃線組成,但是不能以數(shù)字開頭

建議:小寫英文字母 + "_"線 構(gòu)成(C語言命名風(fēng)格)
C++一般用小駝峰法命名:numName

知識(shí)點(diǎn)7【八進(jìn)制 十進(jìn)制 十六進(jìn)制】

十進(jìn)制: 0~9
八進(jìn)制:0~7
十六進(jìn)制:0 ~ 9 ,a ~ f

八進(jìn)制 十進(jìn)制 十六進(jìn)制都是整型的輸出形式
十進(jìn)制輸出 %d %u %ld %lu
八進(jìn)制輸出 %o
十六進(jìn)制輸出 %x

八進(jìn)制是以0開頭

printf("八進(jìn)制:num=%#o\n",num); //0144

十六進(jìn)制是以0x開頭

printf("十六進(jìn)制:num=%#x\n",num); //0x64

不同的進(jìn)制僅僅是數(shù)據(jù)的表現(xiàn)形式, 并不能修改數(shù)據(jù)本身


知識(shí)點(diǎn)9 【整型變量的操作 - 讀(取值)、寫(賦值)】

1、取值與賦值——讀寫操作

void test01() {//在大括號(hào)內(nèi)部定義的變量叫局部變量(局部變量不初始化,內(nèi)容隨機(jī))int data=0;int num=0;printf("num=%d\n",num);// 讀操作 取值//寫操作 賦值 num=100;printf("num=%d\n",num);data=num; //將右邊的值賦值給左邊 ,對(duì)于num來說是讀取它的值100(讀操作),賦值給data(寫操作)printf("data=%d\n",data);//獲取鍵盤輸入printf("請(qǐng)輸入一個(gè)int數(shù)據(jù):");scanf("%d",&data); //&data 代表的是data空間的起始地址printf("data=%d\n",data); }

運(yùn)行結(jié)果:

2、整型的輸出形式

void test02() {int num1=0;//%d 有符號(hào)int數(shù)據(jù)輸出printf("num1=%d\n",num1);unsigned int num2=0;//%u 無符號(hào)int數(shù)據(jù)輸出 (u是unsigned的簡(jiǎn)寫)printf("num2=%u\n",num2)long num3=0;//%ld 有符號(hào)long型數(shù)據(jù)輸出printf("num3=%ld\n",num3);unsigned long num4=0;//%lu 無符號(hào)long型數(shù)據(jù)輸出printf("num3=%lu\n",num4);long long num5=0;//%ld 有符號(hào)long long型數(shù)據(jù)輸出printf("num3=%lld\n",num3);unsigned long long num6=0;//%lu 無符號(hào)long long型數(shù)據(jù)輸出printf("num3=%llu\n",num4);//注意:VC6.0不支持long long但在其他集成環(huán)境支持short num7=0; //short本來就是整型,所以一般不寫int// %hd是有符號(hào)short數(shù)據(jù)輸出printf("num7=%hd\n",num7);short num8=0; //short本來就是整型,所以一般不寫int// %hu是無符號(hào)short數(shù)據(jù)輸出printf("num8=%hu\n",num8); }

unsigned short num6=0;
scanf(“num6=%hu\n”,num6); //輸入
x

知識(shí)點(diǎn)10 【實(shí)型 常量】

注意:賦值語句 等號(hào) 兩邊類型盡量保證一致
%lf double型浮點(diǎn)型

加f的是float類型,不加f的是double類型

void test03() {//不以f結(jié)尾的實(shí)型常量 為double類型printf("sizeof(3.14)=%d\n",sizeof(3.14));//8byte//sizeof針對(duì)于變量可以不加小括號(hào),針對(duì)類型要加小括號(hào)//為了通用 最好都加小括號(hào)//以f結(jié)尾的實(shí)型常量 為float類型printf("sizeof(3.14)=%d\n",sizeof(3.14f));//4bytefloat f=3.14; //有沒有問題? 賦值語句要保證兩邊類型相同// f是float類型4字節(jié) 3.14是double類型 8字節(jié)//把8字節(jié)賦值給4字節(jié)(這樣賦值是有問題的) float f=3.14f;(√)//%f輸出 float數(shù)據(jù)printf("f=%f\n",f);//%lf 輸出 double數(shù)據(jù)double d=3.14;printf("%d=%lf\n",d)scanf("%f",&f);scanf("%lf",&d);}

float類型占四個(gè)字節(jié)
double類型占八個(gè)字節(jié)


知識(shí)點(diǎn)11 【字符常量和變量】(重要)

直接常量:用單引號(hào)括起來,如:‘a(chǎn)’ 、 ‘b’ 、‘12’等
轉(zhuǎn)義字符:以反斜杠\開頭,后面跟一個(gè)或者幾個(gè)字符,如’\n’ '\t’等,分別代表?yè)Q行、橫向跳格

1、字符常量char

void test01() {// %c輸出的是字符 printf("%c\n",'a');//字符常量//字符變量//ch存儲(chǔ)的是'a'的ASCII值char ch='a';// %c 輸出的是符號(hào)本身printf("ch=%c\n",ch);// ch=a// %d 輸出的是字符的ASCII值printf("ch=%d\n",ch);// ch=97// 'a' 單引號(hào)表示取字符的ASCII// 'a'==97是完全等價(jià)ch=97;printf("ch=%c\n",ch); //ch=aprintf("ch=%d\n",ch); //ch=97ch=ch+1;printf("ch=%c\n",ch); //ch=bprintf("ch=%d\n",ch); //ch=98}

ASCII碼表:


總結(jié):
1、‘a(chǎn)’ 單引號(hào)表示取a的ASCII值
2、字符在計(jì)算機(jī)中存儲(chǔ)的是ASCII
3、‘a(chǎn)’==97

思考:

char ch='a'; printf("%d\n",sizeof('a'));//4byte sizeof測(cè)量的是小括號(hào)里面類型的長(zhǎng)度 printf("%d\n",sizeof(char));//1byte 為什么?

‘a(chǎn)’,單引號(hào)是取字符的ASCII值——》97,本質(zhì)是sizeof(97); 97是int類型,所以是4byte。

字符類型如何去獲取鍵盤輸入呢?

void test03() {char ch;printf("請(qǐng)輸入一個(gè)字符");//字符變量獲取鍵盤輸入scanf("%c",&ch);//scanf中%c只能**提取一個(gè)字符**printf("ch=%c\n",ch);//輸出字符用%cprintf("ch=%d\n",ch);//輸出ASCII用%d//ch=getchar();//這也是獲取一個(gè)字符,把值賦給變量ch//getchar是一個(gè)函數(shù)調(diào)用,其實(shí)scanf也是一個(gè)函數(shù)調(diào)用 }

運(yùn)行結(jié)果:

案例: 鍵盤輸入“abc”,只取‘a(chǎn)’和‘c’

char ch1,ch2;printf("請(qǐng)輸入abc:");//提取ach1=getchar();getchar();//丟棄一個(gè)字符ch2=getchar();//提取cprintf("ch1=%c\n",ch1);printf("ch2=%c\n",ch2);

運(yùn)行結(jié)果:

知識(shí)點(diǎn)12 【轉(zhuǎn)義字符】

// '\n'換行 '\t' tab//printf("##%c##\n",'\\');//兩個(gè)反斜杠輸出一個(gè)反斜杠//printf("#%%90#\n");//兩個(gè)百分號(hào)輸出一個(gè)百分號(hào)//ABCD中哪兩個(gè)相等?BC//判斷哪兩個(gè)相等,其實(shí)就是查看這兩個(gè)在計(jì)算機(jī)中存放的ASCII值是不是一樣printf("A:%d\n",'0');//字符0的ASCII是48 字符本質(zhì)存放的就是ASCIIprintf("B:%d\n",'\0');//’\0‘的ASCII值是0printf("C:%d\n",0); //0printf("D:%d\n","0");//字符串0 取的是字符0的地址



知識(shí)點(diǎn)13 【字符串】“”雙引號(hào)作用


%s的本質(zhì)作用就是:從字符串的首元素地址開始,逐個(gè)字符輸出,遇到’\0’自動(dòng)結(jié)束輸出(重要)

void test06() {//%s就是輸出字符串//''取的是字符的ASCII值,雙引號(hào)取的是字符串的首元素的地址//%s的本質(zhì)作用就是:從字符串的首元素地址開始,逐個(gè)字符輸出,遇到'\0'自動(dòng)結(jié)束輸出(重要)printf("%s\n","hello world");//系統(tǒng)會(huì)在字符串末尾自動(dòng)添加一個(gè)結(jié)束字符'\0'printf("%d\n",sizeof("hello world"));//12byte 因?yàn)樽址J(rèn)以反斜杠0結(jié)尾printf("%s\n","hello\0world");//只能輸出helloprintf("##%s##\n","\0hello\0world");//#### }int main(int argc,char *argv[]){test06(); return 0; }

請(qǐng)描述‘a(chǎn)’和“a”的區(qū)別:

1、單引號(hào)a只占一個(gè)字節(jié),雙引號(hào)a占2個(gè)字節(jié)(一個(gè)字節(jié)存放字符a,一個(gè)字節(jié)存放\0)
2、'a’取的是字符a的ASCII值,雙引號(hào)a取的是字符串a(chǎn)的首元素的地址

printf("%d\n",sizeof("ab"));//3byte ——》‘a(chǎn)’‘b’‘\0’

"ab"作為類型代表的的字符串占空間的大小
“ab”作為地址 代表的是字符串 首元素 的地址


知識(shí)點(diǎn)14 【輸出的格式回顧】(了解)

格式化輸出字符:
%d 十進(jìn)制有符號(hào)整數(shù)
%x 以十六進(jìn)制表示的整數(shù)
%f float型浮點(diǎn)數(shù)
%e 指數(shù)形式的浮點(diǎn)數(shù)
%c 單個(gè)字符
%u 十進(jìn)制無符號(hào)整數(shù)
%o 一八進(jìn)制表示的整數(shù)
%lf double型浮點(diǎn)數(shù)
%s 字符串
%p 指針的值
特殊應(yīng)用:
%3d , %03d , %-3d , %5.2f

void test07() {printf("##########\n");//%5d表示占五個(gè)終端位寬 右對(duì)齊printf("##%5d##\n",123);//%-5d表示占五個(gè)終端位寬 左對(duì)齊printf("##%-5d##\n",123);//%05d表示占五個(gè)終端位寬 右對(duì)齊 不足補(bǔ)0printf("##%05d##\n",123);//千萬不能寫 %-05d(不起作用)printf("##%-05d##\n",123);//%5.2f 5表示總位寬為5 .2表示小數(shù)位保留兩位printf("%5.2f\n",3.14159f); }

運(yùn)行結(jié)果:


知識(shí)點(diǎn)15 【typedef】

已有的類型重新取個(gè)別名

步驟:

1、用已有的類型定義一個(gè)變量
2、用別名替換變量名
3、在整個(gè)表達(dá)式的前方加上typedef

案例1 int INT32 typedef int INT32;案例2:給int arr[5]取個(gè)別名 int arr[5] //用已有的類型定義一個(gè)變量 typedef int ARR[5];//用別名替換變量名 ARR arr;//arr就是一個(gè)擁有5個(gè)int元素的數(shù)組

02_C語言的基本語句


知識(shí)點(diǎn)1【數(shù)據(jù)類型轉(zhuǎn)換】

1、自動(dòng)類型轉(zhuǎn)換(保證精度不丟失)

轉(zhuǎn)化的方向

案例:有符號(hào)和無符號(hào)的轉(zhuǎn)換

int data1=-20; unsigned int data2=10;//有符號(hào)數(shù)data1和無符號(hào)數(shù)data2進(jìn)行轉(zhuǎn)換的時(shí)候//會(huì)先將data1轉(zhuǎn)換為無符號(hào)(-20的補(bǔ)碼——》很大的正數(shù))//很大的數(shù) + 10 必然 >0if(data1+data2>0){printf(">0\n");// √}else if(data1+data2<0){printf("<0\n");}

運(yùn)行結(jié)果是:大于0

案例:int和double的轉(zhuǎn)換

int data1=10;//int和double轉(zhuǎn)換時(shí),會(huì)將int轉(zhuǎn)換為doubleprintf("%d\n",sizeof(data1+3.14));// double是8字節(jié)

案例:char和short的類型轉(zhuǎn)換

char ch='a';short data=20;//由于char,short自身字節(jié)數(shù)過小,很容易溢出//所以,只要char,short參與運(yùn)算,都會(huì)將自身轉(zhuǎn)換成intprintf("%d\n",sizeof(ch+ch));//4printf("%d\n",sizeof(data+ch));//4printf("%d\n",sizeof(data+data));//4

2、強(qiáng)制類型轉(zhuǎn)換

(類型說明符)(表達(dá)式)
例如:
(float)a;
(int)(x+y);

void test11() {float x=3.14f;int j=0; //j=x;//賦值時(shí),等號(hào)左右兩邊類型要匹配, j只能拿x的整數(shù)部分//強(qiáng)制類型轉(zhuǎn)換,只是臨時(shí)的轉(zhuǎn)換,當(dāng)前語句有效 在后面的語句中不會(huì)更改x的值j=(int)x;printf("j=%d,x=%f\n",j,x); //3 }


注意:無論是強(qiáng)制轉(zhuǎn)換還是自動(dòng)轉(zhuǎn)換,都只是為了本次運(yùn)算的需要,而對(duì)變量的數(shù)據(jù)長(zhǎng)度進(jìn)行臨時(shí)性轉(zhuǎn)換,而不改變數(shù)據(jù)定義的類型。


知識(shí)點(diǎn)2 【運(yùn)算符】

運(yùn)算對(duì)象:常量、變量、函數(shù)(返回值)等

1、算術(shù)運(yùn)算符(+、-、*、/、%)

a/b (a,b都為整數(shù)) 取整
%取余

printf("%d\n",5/2);//2 取整 (5和2都為整數(shù))printf("%d\n",5%2);//1 取余

案例:鍵盤輸入一個(gè)數(shù) ,是否能被3整除

int num=0;//鍵盤輸入一個(gè)整數(shù)printf("請(qǐng)輸入一個(gè)整型數(shù)據(jù):");scanf("%d\n",&num);//判斷能否被3整除if(num%3==0){printf("ok\n");}else{printf("no\n");}

printf("%d\n",5/2);//如果反斜杠兩邊都是整數(shù),就是單純的取整 2printf("%f\n",5/2.0f);//如果有浮點(diǎn)型,就是真正的除法 2.5

運(yùn)行結(jié)果:

2、邏輯運(yùn)算符(!、&&、||)

① 邏輯非 ——!0 == 真 、 !真 == 假

printf("%d\n",!1);//0printf("%d\n",!0);//1//C中0為假,其他都為真 -1也是真printf("%d\n",!-1);//0

② 邏輯與 &&(重要)

A&&B —— A、 B同時(shí)為真 則 整個(gè)表達(dá)式,AB只要有一個(gè)為假,結(jié)果就為假。

if((3>2) && (5>4)){printf("ok\n");//ok}else{printf("no\n");}

邏輯與有短路特性
A&&B ——》如果發(fā)現(xiàn)A為假,系統(tǒng)不會(huì)判斷執(zhí)行B,這就是短路特性

③邏輯或 ||

A||B 只要AB任意一個(gè)為真,整個(gè)表達(dá)式都為,AB同時(shí)為假的時(shí)候,結(jié)果才為

邏輯非也有短路特性:只要A為真,編譯器不會(huì)判斷B的真假

int num=10;printf("比較之前num=%d\n",num);//10(3>2) || (num=100);printf("比較之后num=%d\n",num);//10 num=100得不到執(zhí)行

綜合案例:


知識(shí)點(diǎn)3 【位運(yùn)算符】二進(jìn)制位操作(<< 、>> 、& 、| 、~ 、^)


&:按位與

語法:全1為1,其他為0

1010 1010 & 1111 0000 -------------------1010 0000

特點(diǎn):和1相與 保持不變,和0相與 清零

應(yīng)用場(chǎng)景:將固定位清零


|:按位或

語法:有1就為1,全0才為0

1010 1010 | 1111 0000 -------------------1111 1010

特點(diǎn):和0相或 保持不變,和1相或置1
應(yīng)用場(chǎng)景:將固定位置1

案例:將1010 1010的第2、3位變成1,其他不變

1010 1010 | 0000 1100 -------------------1111 1010

~:按位取反

語法:0變1,1變0

~ 1010 1010=0101 0101

應(yīng)用場(chǎng)景:配合&|操作


^:按位異或 (重要)

語法:相同為0,不同為1

1010 1010 ^ 0000 1111 -------------------1010 0101

特點(diǎn):和0異或保持不變,和1異或 取反
應(yīng)用場(chǎng)景:將固定的位 發(fā)生高低電頻翻轉(zhuǎn)

案例:將1010 1010的第0位發(fā)生翻轉(zhuǎn)(要將哪位翻轉(zhuǎn),就將它與1異或)

1010 1010 ^ 0000 0001 -------------------1010 1011

<<:左移運(yùn)算符(左邊丟棄,右邊補(bǔ)0)

(將二進(jìn)制位向左移動(dòng))

注意:移動(dòng)的位數(shù)不要超過自身長(zhǎng)度

1010 1100 << 2(左移2位)

>>:右移運(yùn)算符


右移分為:邏輯右移和算術(shù)右移

邏輯右移:右邊丟棄,右邊補(bǔ)0

算術(shù)右移
①無符號(hào)數(shù):右邊丟棄,左邊補(bǔ)0
②有符號(hào)數(shù):
<1>正數(shù):右邊丟棄,左邊補(bǔ)0
<2>負(fù)數(shù):右邊丟棄,左邊補(bǔ)1

右移基本上是右邊丟棄,左邊補(bǔ)0
只有負(fù)數(shù)且算術(shù)右移,才會(huì)左邊補(bǔ)1

邏輯右移和算術(shù)右移是編譯器決定,但是我們可以檢測(cè)。

作業(yè):自己寫代碼,判斷你的編譯器是邏輯右移還是算術(shù)右移

char ch=0x85; // 1000 0101>>4//邏輯右移:1000 0101>>4 == 0000 1000 ==0x08//算術(shù)右移:1000 0101>>4 == 1111 1000 ==0xf8ch=ch>>4;printf("ch=%#x\n",ch);//0xf8是算術(shù)右移//邏輯右移、算術(shù)右移是編譯器決定的,我們只能測(cè)試,不能改變

綜合案例:將data第1,5位清零(按位與),3、4位置1,其他位保持不變
unsigned char data=0xaa; //1010 1010
//將data第1,5位清零
data = data & 1101 1101;// 與 完之后要賦值為data,才能更新它的值
1101 1101= ~(0010 0010)取反= ~(0010 0000 | 0000 0010

0010 0000= 0000 0001 <<5
0000 0010= 0000 0001 <<1

所以:1101 1101= ~(0x01 <<5 | 0x01<<1)

data=data & ~(0x01<<5 | 0x01 <<1);//很清楚的能看出是第一位和第五位清零

第3、4位 置1
data=data | 0001 1000;
0001 1000 = 0001 0000 | 0000 1000=0x01<<4 | 0x01<<3
data = data | (0x01<<4 | 0x01<<3);

規(guī)律:只有按位與有取反,清零就 與、取反,后面第幾位就寫左移第幾位;要置1,只寫或,不寫取反,里面第幾位,就寫左移第幾位,每一位用或或上


知識(shí)點(diǎn)4【三目運(yùn)算符】?:

表達(dá)式1 ? 值1:值2
語法:如果表達(dá)式1為真,那么整個(gè)表達(dá)式的值為“值1”,反之為“值2”

案例

int ret=0;//最好先初始化再去賦值ret=3>2 ? 5:6;printf("ret=%d\n",ret);//ret=5

知識(shí)點(diǎn)5【逗號(hào)運(yùn)算符】

案例:逗號(hào)運(yùn)算符

int data1=0;int data2=0;//賦值運(yùn)算符和逗號(hào)運(yùn)算符,逗號(hào)運(yùn)算符優(yōu)先級(jí)其實(shí)是最低的data1=3,4,5,6;//先執(zhí)行data1=3data2=(3,4,5,6);//小括號(hào)優(yōu)先級(jí)最高,逗號(hào)運(yùn)算符結(jié)合性是從左往右,所以data2=6printf("data1=%d\n",data1);//3printf("data2=%d\n",data2);//6



知識(shí)點(diǎn)6【符合運(yùn)算符】

+= 、 -= 、 = 、 /= 、%= 等等

a+=b ===》a=a+b
a * =b ===》a= a * b
注意:等號(hào)的右邊必須看成一個(gè)整體

案例

int data = 3;//將等號(hào)右邊看成一個(gè)整體data *= 3+5;//data=data * (3+5);printf("data=%d\n",data);//24

知識(shí)點(diǎn)7【自增自減 運(yùn)算符】

++i 或者 --i :先加、減 ,后使用
i++或者i–:先使用,后加、減

int i=3;int j=0;j=++i;//先加,后使用//先執(zhí)行i=i+1,i變?yōu)?;后執(zhí)行j=i,4賦值給j,所以j也變成4printf("i=%d,j=%d\n",i,j);//4,4


注意:i++或者++i作為單獨(dú)的指令,是沒有區(qū)別的


知識(shí)點(diǎn)7【優(yōu)先級(jí)】分析已有的代碼

優(yōu)先級(jí)高的先執(zhí)行,同級(jí)別的優(yōu)先級(jí)要看結(jié)合性
C語言運(yùn)算符的優(yōu)先級(jí)
自己寫代碼,盡量加小括號(hào)



知識(shí)點(diǎn)8【if 語句】

1、如果只在乎項(xiàng)目的一個(gè)結(jié)果,選擇if

if(表達(dá)式)
{
????語句1;
}
表達(dá)式為真,才會(huì)執(zhí)行語句1;

void test21() {int data=0;printf("請(qǐng)輸入一個(gè)int數(shù)據(jù):");scanf("%d",&data);//判斷能被2整除if(data%2==0)//注意:這里不能寫分號(hào)!{printf("能被2整除");} }

2、如果項(xiàng)目只有兩種結(jié)果,且不會(huì)同時(shí)出現(xiàn)。請(qǐng)選擇if…else…

if(表達(dá)式)
{
????語句1;
}
else
{
????語句2;
}
表達(dá)式為真執(zhí)行語句1,否則執(zhí)行語句2

void test22() {int data=0;printf("請(qǐng)輸入一個(gè)int數(shù)據(jù):");scanf("%d",&data);//判斷data對(duì)2的余數(shù)(只有0,1兩種情況)if(data % 2==0){printf("余數(shù)為0\n");}else{printf("余數(shù)為1\n");} }

3、如果一個(gè)項(xiàng)目 有多個(gè)結(jié)果 且不同時(shí)出現(xiàn)。選擇if…else if…else if…else

if(表達(dá)式1)
{
????語句1;
}
else if(表達(dá)式2) //if后面要加表達(dá)式
{
????語句2;
}
else //可以省略
{
????語句n;
}
只有表達(dá)式1位真,執(zhí)行語句1,;只有表達(dá)式2位真,執(zhí)行語句2;所有表達(dá)式都為假,才執(zhí)行語句n。

void test22() {int data=0;printf("請(qǐng)輸入一個(gè)int數(shù)據(jù):");scanf("%d",&data);//判斷data對(duì)3的余數(shù)(有0,1,2三種情況)if(data % 3==0){printf("余數(shù)為0\n");}else if(data % 3==1){printf("余數(shù)為1\n");}else if(data % 3==2)//其實(shí)這條語句可以直接寫else,但是為了增加代碼可讀性,還是寫else if吧{printf("余數(shù)為2\n");} }

注意:只有前面的條件不滿足,才會(huì)判斷后面的條件,如果前面的條件滿足,后面的條件不管真假都不會(huì)執(zhí)行。

4、一個(gè)項(xiàng)目有多個(gè)結(jié)果,不確定是否同時(shí)出現(xiàn)

if(表達(dá)式1)
{
????語句1;
}
if(表達(dá)式2)
{
????語句2;
}
if(表達(dá)式3)
{
????語句3;
}
每個(gè)if語句都是獨(dú)立的。

作業(yè):鍵盤輸入一個(gè)數(shù),能否被3和7同時(shí)整除

知識(shí)點(diǎn)9【switch 選擇語句】

switch(表達(dá)式)
{
case 值1: // 不能是實(shí)型、字符串,只能是整型和字符(本質(zhì)是ASCII)
????????語句1;
????????break;

case 值2:
????????語句2;
????????break;

case 值3:
????????語句3;
????????break;

default: //可以省略
????????語句n;
????????break;
}

switch就是判斷表達(dá)式的值是否和值1,值2,值3相等,來找到接下來程序的進(jìn)入點(diǎn)。

int data=0;printf("請(qǐng)輸入一個(gè)int數(shù)據(jù):");scanf("%d",&data);//判斷data對(duì)3的余數(shù)(有0,1,2三種情況)switch(data%3){case 0:printf("余數(shù)為0\n");break;case 1:printf("余數(shù)為1\n");break;case 2:printf("余數(shù)為2\n");break;}

案例:有時(shí)候break可以省略

void test23() {char ch=0;printf("請(qǐng)輸入你的方向:wasd\n");ch=getchar();switch(ch){case 'w':case 'W':printf("向上移動(dòng)\n");break;case 'a':case 'A':printf("向左移動(dòng)\n");break;case 's':case 'S':printf("向下移動(dòng)\n");break;case 'd':case 'D':printf("向右移動(dòng)\n");break;}}

03_循環(huán)語句及數(shù)組


知識(shí)點(diǎn)1 【for循環(huán)】

for(初始語句; 循環(huán)條件 ; 步進(jìn)條件) {//循環(huán)語句 } //初始語句:只在循環(huán)開始時(shí)執(zhí)行一次 //循環(huán)條件:每次循環(huán)都要執(zhí)行,如果循環(huán)條件為真,進(jìn)入循環(huán)體 如果為假,退出循環(huán)體 //步進(jìn)條件:每次循環(huán)結(jié)束的時(shí)候要執(zhí)行的語句

案例: 求1~100的和

//1~100的和 1+2+3+4+...+100int i =0;int sum=0;for(i=1;i<=100;i++)// i++ ==> i=i+1{sum=sum+1}printf("sum=%d\n",sum);

案例:

//1~100的和 1+2+3+4+...+100int i =1;int sum=0;//如果變量提前初始化了,for循環(huán)的初始化語句可以省略for(;;)//建議不要這么做{//如果for省略循環(huán)條件,必須在循環(huán)語句中實(shí)現(xiàn)退出循環(huán)的條件if(i>100)break;//跳出循環(huán)sum=sum+i;i++;//如果for省略步進(jìn)條件,必須在循環(huán)語句中實(shí)現(xiàn)步進(jìn)動(dòng)作}printf("sum=%d\n",sum);

案例:break只能跳出離它最近的一層循環(huán)

void test26(){for(;;){for(;;){break;//只能跳出離他最近的一層循環(huán)}}}

continue

continue:結(jié)束本次循環(huán),立即從當(dāng)前位置直接進(jìn)入下一次循環(huán)

作業(yè):
1、求出1~100中能被7整除的數(shù)。

案例:求出0~100的所有偶數(shù)的和

//求0 2 4 6...100的和int i=0;int sum=0;for(;i<=100;i=i+2)//步進(jìn)條件不是單純的i++{if(i==50)continue;//結(jié)束本次循環(huán),立即從當(dāng)前位置直接進(jìn)入下一次循環(huán)sum+=i;}printf("sum=%d\n",sum);//2550

break和continue的區(qū)別

break語句用于跳出本層循環(huán)
continue用于結(jié)束本次循環(huán)

循環(huán)嵌套循環(huán)

//外層循環(huán)的次數(shù) * 內(nèi)層循環(huán)的次數(shù) == 總循環(huán)次數(shù) void test28(){int i=0;int j=0;for(i=0;i<10;i++)// 0~9=10{for(j=0;j<10;j++)// 0~9=10{printf("i=%d,j=%d\n",i,j);//輸出幾次?100次}} }

知識(shí)點(diǎn)2【while 循環(huán) 和 do…while 循環(huán)】

while(循環(huán)條件) {//循環(huán)語句 }//如果循環(huán)條件為真就進(jìn)入循環(huán)體執(zhí)行循環(huán)語句

注意:
1、while沒有初始化語句 ,用戶要提前初始化
2、while沒有步進(jìn)語句, 用戶必須在循環(huán)語句中寫好步進(jìn)語句。

案例:

int i=1;int sum=0;//注意初始化while(i<=100)//1~100和{sum+=i;i++;}printf("sum=%d\n",sum);//5050


注意:局部變量如果不初始化,內(nèi)容不確定


do {//循環(huán)語句 }while(循環(huán)條件);

先執(zhí)行循環(huán)語句,在判斷循環(huán)條件是否滿足, 如果為真,進(jìn)行下一次循環(huán),如果為假,直接退出循環(huán)

案例

int num=0;do{printf("ok\n");}while(num>0);//先進(jìn)do再去判斷條件,所以會(huì)將ok打印出來

知識(shí)點(diǎn)3【goto 跳轉(zhuǎn)】(慎用!)

void test31(){printf("---------001---------\n");printf("---------002---------\n");goto here;//注意這里是分號(hào)printf("---------003---------\n");printf("---------004---------\n");printf("---------005---------\n"); here://注意這里是冒號(hào)printf("---------006---------\n");printf("---------007---------\n"); }int main(int argc,char *argv[]){test31(); return 0; }


作業(yè):
重復(fù)輸入1~7的數(shù)字判斷星期幾,注意輸入0,就結(jié)束程序,如果是0或1 ~7以外的數(shù),請(qǐng)?zhí)崾尽罢?qǐng)重新輸入有效數(shù)值“

總結(jié):
for 和 while 我們?nèi)绾芜x擇呢?
for和while低位一樣
建議:
如果循環(huán)次數(shù)是確定的,建議選擇for。
如果循環(huán)次數(shù)不確定,只知道退出的條件,建議選擇while


知識(shí)點(diǎn)4【數(shù)組的概述】



知識(shí)點(diǎn)5【一維數(shù)值數(shù)組】

1、數(shù)組的定義

需求:請(qǐng)定義一個(gè)數(shù)組,該數(shù)組有十個(gè)元素,每個(gè)元素為int類型

在定義的時(shí)候:(按照步驟來,因?yàn)橐院蟮臄?shù)組很復(fù)雜)
a、arr[ ] arr和中括號(hào)結(jié)合時(shí)就是數(shù)組
b、將確定的元素的個(gè)數(shù)放入中括號(hào)中
c、用元素的類型定義一個(gè)普通變量
d、從上往下整體替換(變量名)

arr[10]
int num;
用arr[10]整體替換num——》int arr[10];

需求:請(qǐng)定義一個(gè)數(shù)組,該數(shù)組有十個(gè)元素,每個(gè)元素為地址,每個(gè)地址為int變量的地址。

arr[10]
*p //每個(gè)元素為地址,地址就是指針
int num;
//從上往下依次替換
arr[10]替換p——》 * arr[10]
星花 * arr [10]替換num——》int * arr [10]

注意:
1、數(shù)組名arr不能和其他變量名同名
2、數(shù)組的元素下標(biāo)是從0開始的:0~9
3、數(shù)組的元素分別是:arr[0]、arr[1]…arr[9],如果訪問arr[10]數(shù)組越界
4、數(shù)組的元素等價(jià)于普通變量
5、在定義數(shù)組的時(shí)候,中括號(hào)里面的值必須為常量,不能是變量。

案例1:遍歷數(shù)組

//局部數(shù)組(變量)如果不初始化,內(nèi)容也是不確定的int arr[10];//遍歷數(shù)組——》for循環(huán)int i=0;for(i=0;i<10;i++){printf("%d ",arr[i]);//輸出的都是不確定的值}printf("\n");

案例2:數(shù)組的初始化

初始化:定義的時(shí)候給變量或者數(shù)組元素賦值的動(dòng)作,叫做初始化

全部初始化:
int arr[5]={10,20,30,40,50}; //如果是全部初始化,數(shù)組元素的個(gè)數(shù)可以省略,實(shí)際元素個(gè)數(shù)由初始化個(gè)數(shù)決定 int arr[]={10,20,30,40,50};//少用//錯(cuò)誤演示: int arr[];//沒有初始化,不知道開辟多大空間
部分初始化:
int arr[5]={10,20,30};//部分初始化,未被初始化的部分補(bǔ)0(重要)//初始化數(shù)字常見操作(將數(shù)組所有元素清零) int arr[5]={0};//初始化arr[0]=0,未被初始化部分自動(dòng)補(bǔ)0 int arr[5]={2};//2 0 0 0 0
拓展:特殊初始化
//了解 int arr[5]={[2]=3,[4]=7}; // 0 0 3 0 7 //[2]=3 將數(shù)組的第二個(gè)元素 初始化為 3 //[4]=7 將數(shù)組的第四個(gè)元素 初始化為 7

2、數(shù)組的空間大小(重要)

//arr數(shù)組名 作為數(shù)組類型 代表的是數(shù)組空間的總大小int arr[5]={10,20,30,40,50};int n=0;printf("數(shù)組的總大小:%d\n",sizeof(arr));//20個(gè)字節(jié)//數(shù)組的總大小=元素的個(gè)數(shù)*每個(gè)元素的大小// 20 = 5 * 4//數(shù)組元素的大小 arr[0]是數(shù)組第0個(gè)元素,數(shù)組的每個(gè)元素都是相同類型printf("數(shù)組元素的大小=%d\n",sizeof(arr[0]));//4//數(shù)組元素的個(gè)數(shù)=數(shù)組的總大小 / 每個(gè)元素的大小n= sizeof(arr) / sizeof(arr[0]);printf("數(shù)組元素的個(gè)數(shù)為:%d\n",n)//5;

遍歷數(shù)組

//arr數(shù)組名 作為數(shù)組類型 代表的是數(shù)組空間的總大小int arr[5]={10,20,30,40,50};int n= sizeof(arr) / sizeof(arr[0]);//是求數(shù)組的元素個(gè)數(shù)int i=0;//遍歷數(shù)組for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");

案例:

int arr1[5]={1,2,3};int arr2[]={1,2,3};char arr3[5]={1,2,3};int arr4[]={[5]=7};//VC6.0不支持printf("%d\n",sizeof(arr1));//20printf("%d\n",sizeof(arr2));//12printf("%d\n",sizeof(arr3));//5printf("%d\n",sizeof(arr4));//6*4=24

3、數(shù)組元素的操作

數(shù)組元素等價(jià)于普通變量

int arr[5]={1,2,3,4,5};int n=sizeof(arr)/sizeof(arr[0]);int i=0;//給數(shù)組元素賦值arr[0]=100;//num++arr[1]++; //arr[1]=arr[1]+1;//scanf("%d",&num)scanf("%d",&arr[2]);for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");

案例:定義一個(gè)數(shù)組 5個(gè)元素,每個(gè)元素int類型,獲取鍵盤輸入

//數(shù)值數(shù)組只能逐個(gè)元素操作 不能整體操作int arr[5]={0};int n=sizeof(arr)/sizeof(arr[0]);int i=0;printf("請(qǐng)輸入%d個(gè)int型數(shù)據(jù)\n",n);for(i=0;i<=n;i++){scanf("%d",&arr[i]);//中括號(hào)[]的優(yōu)先級(jí)高于&//&arr[i] 表示取第i個(gè)元素的地址}for(i=0;i<n;i++){printf("%d ",arr[i]);//arr[i]訪問數(shù)組的第i個(gè)元素 }

作業(yè):定義一個(gè)數(shù)組 5個(gè)元素,每個(gè)元素int類型,獲取鍵盤輸入,請(qǐng)求出數(shù)組的最大值,最小值,平均值。


知識(shí)點(diǎn)6【二維數(shù)組】

1、二維數(shù)組的定義



二維數(shù)組也叫數(shù)組的數(shù)組。

int arr[3][4]; //第一個(gè)中括號(hào)里面的值表示行數(shù) //第二個(gè)中括號(hào)里面的值表示列數(shù) //arr數(shù)組有三行四列 //三行:0~2行 //四列:0~3列

二維數(shù)組的遍歷:

//先寫內(nèi)層循環(huán),再把它粘貼到外層循環(huán)中去 int i=0; for(i=0;i<3;i++) {//遍歷第i行int j=0;for(j=0;j<4;j++){printf("%d ",arr[i][j])} }

案例:

#include<stdio.h> void test01() {int arr[3][4];//局部數(shù)組不初始化,內(nèi)容不確定int i=0,j=0;for(i=0;i<3;i++)//行的變化{//先寫內(nèi)層循環(huán),再寫外層循環(huán),將內(nèi)層循環(huán)復(fù)制到外層循環(huán)for(j=0;j<4;j++)//列的變化{printf("%d ",arr[i][j]);}printf("\n");} } int main(int argc,char *argv[]) {test01();return 0; }

2、二維數(shù)組的初始化

分段初始化:用大括號(hào)里面的大括號(hào),明確的表示一行

int arr[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

連續(xù)初始化:放滿一行才能放下一行

int arr[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

案例:

int arr1[3][4]={{1,2},{3},{4,5}};int arr2[3][4]={1,2,3,4,5};

04_數(shù)組與函數(shù)

知識(shí)點(diǎn)1 【作業(yè)講解】

作業(yè):定義int arr[3][4]的二維數(shù)組,獲取鍵盤輸入,并求出每一行的平均值。

//作業(yè):定義int arr[3][4]的二維數(shù)組,獲取鍵盤輸入,并求出每一行的平均值。 void test03() {int arr[3][4]={0};//將整個(gè)數(shù)組初始化為0//獲取鍵盤輸入int i=0,j=0;for(i=0;i<3;i++){for(j=0;j<4;j++){scanf("%d",&arr[i][j]);}}for(i=0;i<3;i++){//求每一行的平均值float sum=0; for(j=0;j<4;j++){sum+= arr[i][j];}printf("第%d行的平均值為%.2f\n",i,sum/4.0);}

運(yùn)行結(jié)果:

案例:求每一列的平均值

void test03() {int arr[3][4]={0};//將整個(gè)數(shù)組初始化為0//獲取鍵盤輸入int i=0,j=0;for(i=0;i<3;i++){for(j=0;j<4;j++){scanf("%d",&arr[i][j]);}}for(i=0;i<3;i++){//求每一行的平均值float sum=0; for(j=0;j<4;j++){sum+= arr[i][j];}printf("第%d行的平均值為%.2f\n",i,sum/4.0);}for(j=0;j<4;j++){int sum=0;for(i=0;i<3;i++){sum+=arr[i][j];}printf("第%d列的平均值為%d\n",j,sum/3);}// 計(jì)算第0列}int main(int argc,char *argv[]) {test03();return 0; }



知識(shí)點(diǎn)2 【字符數(shù)組】(重要)

字符數(shù)組:本質(zhì)是數(shù)組,只是數(shù)組的美國(guó)元素是字符。

//定義一個(gè)數(shù)組有五個(gè)元素,每個(gè)元素為char
arr[5]
char ch;
從上往下替換======>
char arr[5];

字符數(shù)組的初始化

//初始化:逐個(gè)字符初始化(不推薦) char str[6]={'h','e','l','l','o'}; //str[0]== 'h'的ASCII碼值//初始化:以字符串的形式初始化(推薦) char str[6]="hello";//初始化更加簡(jiǎn)潔

字符數(shù)組的遍歷

char str[6]="hello";//逐個(gè)字符遍歷(不推薦)int i=0;for(i=0;i<6;i++){printf("%c",str[i]);}printf("\n---------\n");//字符數(shù)組可以整體遍歷(推薦)printf("%s\n",str);//%s: 從給定字符串的首元素地址開始逐個(gè)字符遍歷,直到遇到\0結(jié)束//%s加數(shù)組名str

運(yùn)行結(jié)果:

%s:只要告訴字符串第0個(gè)元素的地址,那么就可以逐個(gè)元素打印,直到遇到\0結(jié)束

非常重要:一維數(shù)組名代表的是 數(shù)組第0個(gè)元素的地址。(必須記住)

char str[6]="hello";//%p是十六進(jìn)制輸出地址printf("第0個(gè)元素的地址:%p\n",&str[0]);printf("數(shù)組名:%p\n",str);

逐個(gè)字符初始化和字符串初始化的區(qū)別

char str1[]={'h','e','h','e'};//逐個(gè)元素初始化,系統(tǒng)不會(huì)給它添加‘\0’char str2[]="hehe";//以字符串初始化,系統(tǒng)會(huì)給字符串添加'\0'//以上情況的前提條件是中括號(hào)里面沒給數(shù)組長(zhǎng)度//開辟的空間大小printf("sizeof(str1)=%d\n",sizeof(str1));//4printf("sizeof(str2)=%d\n",sizeof(str2));//5


數(shù)組中括號(hào)里面沒有給定元素的個(gè)數(shù)那么元素的實(shí)際個(gè)數(shù)由初始化情況決定

%s輸出的內(nèi)容
%s的作用是:從數(shù)組的第0個(gè)元素開始,逐個(gè)元素輸出,直到遇到\0結(jié)束

//%s輸出的內(nèi)容//%s的作用是:從數(shù)組的第0個(gè)元素開始,逐個(gè)元素輸出,直到遇到\0結(jié)束printf("str1=##%s##\n",str1);printf("str2=##%s##\n",str2);

★★★運(yùn)行結(jié)果:

字符數(shù)組獲取鍵盤的字符串

定義一個(gè)字符數(shù)組,有足夠大的空間

char buf[128]="";printf("請(qǐng)輸入一個(gè)字符串\n");scanf("%s",buf);//不能獲取帶空格的字符printf("buf=%s\n",buf);

運(yùn)行結(jié)果

scanf和%s使用的時(shí)候有個(gè)缺點(diǎn),遇到空格會(huì)結(jié)束輸入


解決方法:用gets()——》把鍵盤輸入的大小全搬給你
案例:

char buf[128]="";printf("請(qǐng)輸入一個(gè)字符串\n");//scanf("%s",buf);//不能獲取帶空格的字符串gets(buf);//能獲取帶空格的字符串 缺點(diǎn):不會(huì)管buf的大小,容易造成內(nèi)存污染printf("buf=%s\n",buf);

gets()缺點(diǎn):獲取鍵盤輸入的時(shí)候,不會(huì)管buf的大小,容易造成內(nèi)存污染

fgets():既可以獲取帶空格的字符串,也可以保證buf的不越界

#include<stdio.h> char *fgets(char *s, int size, FILE *stream) //s表示存放字符串的空間地址 //size表示能提取字符串的最大長(zhǎng)度 size-1(留一個(gè)給'\0') //stream stdin表示標(biāo)準(zhǔn)輸入設(shè)備 返回值:就是獲取到的字符串的首元素地址
案例:
void test07() {char buf[10]="";printf("請(qǐng)輸入一個(gè)字符串\n");fgets(buf,sizeof(buf),stdin);printf("buf=%s\n",buf); }int main(int argc,char *argv[]) {test07();return 0; }


提高案例:字符串的大小寫的轉(zhuǎn)換
//'a' 97 'b' 98 'c'99 ~ 'z'122//'A' 65 'B' 66 'C'67 ~ 'Z'90//規(guī)律:小寫字母的ASCII值比大寫字母的ASCII值相差32//printf("%d %d\n",'a','z');//printf("%d %d\n",'A','Z');char ch='a';//小寫變大寫 -32ch=ch-32; //其實(shí)也可以寫:ch=ch-('a'-'A');printf("ch=%c\n",ch);//大寫變小寫 +32ch=ch+32;//其實(shí)也可以寫:ch=ch+('a'-'A');printf("ch=%c\n",ch);

作業(yè):鍵盤獲取一個(gè)字符串,大小自定義,將字符串的大寫字母變小寫,小寫字母變大寫,其他符號(hào)保持不變
思路如下:
1、獲取一個(gè)字符串
2、用for循環(huán)將字符串的逐個(gè)字符進(jìn)行大小寫轉(zhuǎn)換


知識(shí)點(diǎn)3【二維字符數(shù)組】(了解)

一維字符數(shù)組是存放多個(gè)字符的

二維字符數(shù)組是存放多個(gè)字符串的 ,每個(gè)字符串占一行

//不管是數(shù)值還是字符的二維數(shù)組,在初始化的時(shí)候是庫(kù)省略行標(biāo)的,行數(shù)又具體初始化決定 char str[3][16]={"hehe","haha","heihei"};//要保證每個(gè)字符串小于16個(gè)字節(jié) str[0]="hehe"; str[1]="haha"; str[2]="heihei";

char str[3][16]={"hehe","haha","heihei"};//對(duì)整體字符串輸出,只需要使用行標(biāo)printf("%s\n",str[0]);//heheprintf("%s\n",str[1]);//hahaprintf("%s\n",str[2]);//heihei//輸出的是 字符串中某個(gè)字符 必須用行標(biāo)和列表printf("%c\n",str[1][3]);//a

二維字符數(shù)組獲取鍵盤輸入的字符串:

應(yīng)用場(chǎng)景:當(dāng)鍵盤需要輸入多個(gè)獨(dú)立的字符串,用戶必須單獨(dú)存儲(chǔ)好,請(qǐng)選擇二維字符數(shù)組

輸入的字符串個(gè)數(shù),決定了二維數(shù)組的行數(shù)輸入字符串中最大長(zhǎng)度,決定了二維字符數(shù)組的列數(shù)

//hehe haha xixi heihei char buf[4][16]={""};//二維字符數(shù)組初始化為0int i=0;//獲取鍵盤的字符串for(i=0;i<4;i++){scanf("%s",buf[i]);//buf[i]已經(jīng)代表是第i行的首元素地址,所以這時(shí)候不要取地址}//輸出鍵盤的字符串for(i=0;i<4;i++){printf("buf[%d]=%s\n",i,buf[i]);}


作業(yè):
1、鍵盤輸入十個(gè)int數(shù)據(jù),對(duì)其從小到大排序
2、鍵盤輸入一個(gè)字符串“abcdef”進(jìn)行前后的顛倒(逆置)——》“fedcba”

知識(shí)點(diǎn)4 【函數(shù)概述】

1、函數(shù)的定義:實(shí)現(xiàn)函數(shù)的功能,確定函數(shù)體、返回值、形參類型。讓函數(shù)存在
2、函數(shù)的聲明:不是實(shí)現(xiàn)函數(shù)功能,僅僅是說明函數(shù)該函數(shù)有返回值類型,形參類型,函數(shù)名。
3、函數(shù)的調(diào)用:函數(shù)的執(zhí)行

1、函數(shù)的定義

// 返回值類型:函數(shù)將來返回值的類型 //函數(shù)名:函數(shù)的入口地址 //形參類型:函數(shù)外部數(shù)據(jù) 傳遞到函數(shù)內(nèi)部的橋梁 //函數(shù)體:具體的函數(shù)功能代碼 返回值類型 函數(shù)名(形參類型 形參) {函數(shù)體; }

2、函數(shù)的聲明

返回值類型 函數(shù)名(形參類型 形參);

3、函數(shù)的調(diào)用

//函數(shù)外部的實(shí)際數(shù)據(jù) 函數(shù)名(實(shí)參);//沒有函數(shù)返回值類型

案例:

#include<stdio.h> //函數(shù)聲明(必須在函數(shù)調(diào)用的前方聲明才有作用)//編譯器是從上往下執(zhí)行的 void my_fun();//函數(shù)聲明:告訴編譯器,該函數(shù)存在,請(qǐng)通過編譯。int main(int argc,char *argv[]) {//函數(shù)的調(diào)用:函數(shù)名+()my_fun();return 0; }//函數(shù)的定義 void my_fun() {printf("my fun\n");return;//void沒有返回值,return后面什么都不寫//return功能:1、返回函數(shù)結(jié)果 2、結(jié)束函數(shù) }

可以省略函數(shù)聲明:函數(shù)的調(diào)用在函數(shù)定義的下方,就可以省略函數(shù)聲明

#include<stdio.h> //函數(shù)聲明(必須在函數(shù)調(diào)用的前方聲明才有作用)//編譯器是從上往下執(zhí)行的 //void my_fun();//函數(shù)聲明:告訴編譯器,該函數(shù)存在,請(qǐng)通過編譯。//函數(shù)的定義 void my_fun() {printf("my fun\n");return;//void沒有返回值,return后面什么都不寫 }int main(int argc,char *argv[]) {//函數(shù)的調(diào)用:函數(shù)名+()my_fun();return 0; }

建議:
往往建議將主函數(shù)寫在上方,將函數(shù)定義寫在下方。(通過主函數(shù),一眼就能看出大致框架)

知識(shí)點(diǎn)5 【函數(shù)的參數(shù)】

1、如果函數(shù)的形參什么都不寫 在調(diào)用的時(shí)候可以傳實(shí)參,只是實(shí)參得不到使用

#include<stdio.h>void my_fun(10,20);int main(int argc,char *argv[]) {my_fun();return 0; }//如果函數(shù)的形參什么都不寫 在調(diào)用的時(shí)候可以傳實(shí)參,只是實(shí)參得不到使用 void my_fun() {printf("my fun\n");return; }

2、如果函數(shù)沒有參數(shù),請(qǐng)將形參寫成void

#include<stdio.h>void my_fun(void);int main(int argc,char *argv[]) {//my_fun(10,20);//errormy_fun();return 0; }//如果函數(shù)的參數(shù)為void,在調(diào)用的時(shí)候就不要給函數(shù)傳遞實(shí)參 void my_fun(void) {printf("my fun\n");return; }

3、函數(shù)參數(shù)的傳遞

總結(jié)

以上是生活随笔為你收集整理的逆向基础之C语言 第一篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。