20160127.CCPP體系詳解(0006天)

尹成發表於2016-02-16

程式片段(01):msg.c
內容概要:執行緒概念

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <process.h>//執行緒函式標頭檔案宣告

//01.程式設計當中所涉及到的重要概念:
//  程式-->執行緒-->模組兒-->動態庫(Dll)-->靜態庫Lib)
//02.此單執行緒程式剖析:
//  1.main01這個函式作為主函式而言:
//      就是一個主執行緒任務程式碼塊兒,主執行緒從該程式碼塊兒的頭部
//      執行到該程式碼塊兒的尾部,每條程式碼語句就將會有機會被CPU
//      所執行
//  2.main01這個函式當中即使遇到順序&迴圈&分支語句,
//      依然會將其進行執行,不過這個都是在單執行緒的概念之上
//  3.執行緒執行到MessageBoxA();這段兒主函式當中的程式碼的時候
//      會一直執行MessageBoxA();這段兒程式碼,等待這段兒程式碼的執
//      行完畢,才會繼續執行main01這個主函式當中的其餘程式碼,否則
//      將會永久等待下去
int main01(void)
{
    for (int i = 0; i < 5; i++)
    {
        MessageBoxA(0, "Hello", "Haker", 0);//順序執行
    }

    system("pause");
}

//03.執行緒任務程式碼(函式塊兒的標準)
//  1.建議執行緒所執行的任務程式碼塊兒(函式)的形式引數用void *p描述
//      這樣有利於程式的可擴充套件性,可以處理任何型別的地址
//  2.void *p描述的是空型別指標,也就是沒有型別的地址,可以儲存任何
//      型別的地址俗稱乾地址
void run(void *p)//void *p:代表一個空地址,沒有任何型別描述
{
    MessageBoxA(0, "Hello", "Hacker", 0);
}

//04.建立執行緒的程式碼詳解:
//  1.另起一條輔助執行緒的程式碼(非主執行緒)
//      _beginthread(run, 0, NULL);
//      引數1:run---->函式地址|函式指標-->執行緒任務程式碼塊兒-->執行緒處理的程式碼
//      引數2:0------>為該執行緒執行任務程式碼塊兒所開闢的棧記憶體空間,也就是處理執行緒任務程式碼塊兒
//          所允許耗費的最大棧記憶體空間
//      引數3:NULL-->有執行緒任務程式碼塊兒(執行緒處理的函式的形式引數接收的資料)-->任務引數
//      返回值:執行緒的標號-->地址-->控制程式碼
//  2.不同語言當中的執行緒執行特點不同:
//      C語言當中:
//          主執行緒消失掉,那麼輔助執行緒也會消失掉
//      Java語言當中:
//          主執行緒消失掉,輔助執行緒不一定消失掉
//      iOS當中:
//          經常用主執行緒來處理與介面相關的任務程式碼,防止介面提前消失
int main02(void)
{
    for (int i = 0; i < 5; i++)
    {
        //run(NULL);//這種方程依然是單條執行緒在執行任務程式碼塊兒
        _beginthread(run, 0, NULL);//啟動執行緒,函式地址(函式指標),把函式當做某個執行緒的入口點
    }

    system("pause");
}
//05.執行緒理解技巧:
//      執行流-->線

程式片段(02):dll.c
內容概要:對話方塊

#include <stdlib.h>
#include <Windows.h>

int main(void)
{//彈出一個簡單的對話方塊內容(第一個引數:誰彈出的;第二個引數:窗體內容;第三個引數:窗體名稱)
    MessageBoxA(0, "李彥巨集哥哥請你喝茶!", "百度大廈不見不散", 0);

    system("pause");
}

程式片段(03):dlltest.c+baidu.c
內容概要:Dll(動態庫)開發

///dlltest.c
#include <Windows.h>

//01.程式設計流程:預編譯-->編譯-->連結-->執行
//  1.C語言當中實現靜態庫的連結方式:
//      (1).編譯器配置連結靜態庫(類似於外部依賴項的特點)
//      (2).通過程式碼實現靜態庫的手動連結(指明手動連結方式)
//  2.手動連結方式的程式碼說明和引數說明:
//      #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"");
//          命令:#pragma comment-->表示預編譯指令(註釋)
//          引數:linker-->手動宣告連結器內容
//          引數:subsystem-->表示宣告連結平臺(Windows模式平臺)
//          引數:entry--->入口:主建立引導
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"");

int main01(void)
{
    MessageBoxA(0, "李彥巨集請你喝茶!", "西二旗百度大廈不見不散!", 0);
}
///baidu.c
#include <Windows.h>

//01.匯出動態庫(Dll)的說明:
//  1.各種程式設計方式的不同特點:
//      程式:一個完整的(應用程式)
//      執行緒:一個執行緒處理的任務程式碼塊兒(任務函式)
//      模組兒:一個完整應用的某個獨立功能
//      動態庫(Dll):將一個功能動態的加入到程式當中
//          動態庫不能直接執行,只能間接執行-->可以通過注入方式實現
//      靜態庫(Lib):封裝函式庫,以便於日後的通用性
//          類似於系統預設生成的外部依賴項特點
//dll不需要main函式就可以被間接執行
//02.匯出介面-->只需要在普通函式的前面新增上匯出Dll動態庫的宣告就行了
//  匯出宣告格式;_declspec(dllexport);
_declspec(dllexport) void go()
{
    MessageBoxA(0, "來自百度的邀請!", "因為你的百度網盤存放了大量的島國大片兒,公安局要求你協助調查!", 0);
    //MessageBoxA(0, "李彥巨集請你百度喝茶!", "西二旗百度大廈不見不散!", 0);
    for (int i = 0; i < 200; i++)
    {
        malloc(1024*1024*10);
        Sleep(30);
    }
}

程式片段(04):lib.h+lib.c+test.c
內容概要:Lib(靜態庫)開發

///lib.h
//將要手動生成的靜態庫函式宣告
int add(int a, int b);
///lib.c
//將要生成的靜態庫函式實現
int add(int a, int b)
{
    return a + b;
}
///test.c
#include <stdio.h>
#include <stdlib.h>
#include "lib.h"

//01.標頭檔案的使用補充:
//  1.標頭檔案引入的特點:
//      沒有引入所需使用的靜態庫標頭檔案(不明確)
//      那麼系統會自動的進行靜態庫標頭檔案的查詢
//      所以建議手動引入自己手動編寫的標頭檔案(明確)
//  2.標頭檔案和原始檔的區別特點:
//      包含內容不一樣(兩點)
//          標頭檔案只能包含.h檔案
//              標頭檔案當中是函式的宣告(虛體)-->編譯之後的結果
//          原始檔只能包含.h檔案
//              原始檔當中是函式的實現(實體)-->連結之後的結果
//02.如何使用自定義的靜態庫?
//      第一步:將自定義靜態庫檔案放置於和原始碼相同的目錄當中
//          這樣可以在連結之後成功打包應用程式
//      第二步:載入自定義靜態庫
//          利用編譯註釋載入自定義靜態庫
//          利用專案配置載入自定義靜態庫
//      第二步:引入靜態庫當中函式宣告所在的標頭檔案
//      第四步:使用自定義靜態庫函式實體
//int add(int a, int b);
//03.利用編譯註釋載入自定義靜態庫:
//  引數1:lib-->表明載入自定義靜態庫
//  引數2:"01.Lib.lib"-->表明自定義靜態庫檔案的名稱
#pragma comment(lib, "01.Lib.lib")
int main01(void)
{
    printf("%d \n", add(1, 2));

    system("pause");
}

程式片段(05):迴圈總結.c
內容概要:迴圈總結

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

//01.如何求取一個整數共有多少位?
//      原理:逐步求模,直到模數為零,求模次數就是整數位數
//02.迴圈內容的總結:
//  1.forwhile完全可已經相互轉化:
//      最簡單的迴圈語句就是for,因為其結構較為清晰
//  2.for-while也可以與do-while進行轉化:
//      不過需要採用do-while+if-else語句處理無論如何
//      首先開頭就執行一次的異常
int main02(void)
{
    //12345-->1234-->123-->12-->1-->0
    //  12345-->執行
    //  1234--->執行
    //  123----->執行
    //  12------>執行
    //  1-------->執行-->整數位數
    //該資料一共有5位數-->是個五位整數
    int i = 0;
    int num = 0;

    scanf("%d", &num);

    //while (num)
    //{//while迴圈實現
    //  i++;
    //  num /= 10;
    //}

    /*for (; num;)
    {
        i++;
        num /= 10;
    }*/

    //for,while-->if-else+do-while,優先處理先執行一次的特殊異常性
    if (num == 0)
    {//處理do-while容易出現的先執行一次,也就是錯誤統計一次的情況
        i = 0;
    }
    else
    {
        do
        {
            i++;
            num /= 10;
        } while (num);
    }
    //do-while語句特點:
    //  1,2;大括號都可以用分號進行替換,但是隻能有一個
    //  語句,逗號不允許空語句的出現,多個語句採用逗號進行連結
    //while(1);
    printf("您所輸入的整數是%d位整數! \n", i);

    system("pause");
}

程式片段:for2.c
內容概要:九九乘法表

#include <stdio.h>
#include <stdlib.h>

//01.總結雙重for迴圈的列印規律
//  1.對規律做出分析,便於後續程式碼編寫
//  2.雙重for迴圈內含的規律分析:
//      (1).外層迴圈執行一次,記憶體迴圈執行一輪
//      (2).外層迴圈控制行數,內層迴圈控制列數
//      (3).外層迴圈控制列印出來的換行符
void show()
{
    for (int i = 1; i <= 9; i++)
    {//01次-->外層迴圈-->控制行
        for (int j = 1; j <= 9; j++)
        {//10次-->內層迴圈-->控制列
            printf("%2d*%2d=%2d", j, i, j*i);
        }
        printf("\n");//換行
    }
}

//02.列印左下三角:(左大三角)
//  觀察數字規律得出:j<=i
void leftDown()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j <= i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
        }
        printf("\n");
    }
}

void rightUp()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j >= i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
            else
            {
                printf("%8s", " ");
            }
        }
        printf("\n");
    }
}

//03.列印左小三角:
//  1.先確定左小三角屬於那塊兒大三角(左大三角||右邊大三角)
//      j<=i
//  2.再確定左小三角本身:觀察圖形規律得知
//      j<=10-i
//      (1).都是等於符號,則新增等於符號,否則就不新增
//      (2).從1開始,用最大數+1,再進行減去i
//      (3).進行比較的時候,j總是在關係運算子的左邊
//  3.總結規律:
//      凡是在左邊,都屬於是小於等於
//      凡是在右邊,都屬於是大於等於
//      原來是>=,那麼後來就是<=
void left()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j <= i && j <= 10 - i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
        }
        printf("\n");
    }
}

void right()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j >= i && j >= 10 - i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
            else
            {
                printf("%8s", " ");
            }
        }
        printf("\n");
    }
}

void up()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j >= i && j >= 10 - i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
            else
            {
                printf("%8s");
            }
        }
        printf("\n");
    }
}

void down()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j <= i && j >= 10 - i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
            else
            {
                printf("%8s", " ");
            }
        }
        printf("\n");
    }
}

//04.列印左上三角(大三角):
void leftUp()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j <= 10 - i)
            {
                printf("%2d*%2d=%2d", j, i, j *i);
            }
        }
        printf("\n");
    }
}

void rightDown()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j >= 10 - i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
            else
            {
                printf("%8s", " ");
            }
        }
        printf("\n");
    }
}

//05.列印九九乘法表
void printf99()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (j <= i)
            {
                printf("%2d*%2d=%2d", j, i, j*i);
            }
        }
        printf("\n");
    }
}

//06.對雙重for迴圈列印三角的大統一總結:
//  1.先確定所需要列印的三角是大三角還是小三角?
//      大三角:
//          左下三角:leftDown
//          右上三角:rightUp
//          左上三角:leftUp
//          右下三角:rightDown
//      小三角:
//          左三角:left
//          右三角:right
//          上三角:up
//          下三角:down
//  2.再確定所需要列印的三角在那塊兒區域?
//      大三角:
//          左下三角:leftDown
//              j<=i
//          右上三角:rightUp
//              j>=i
//          左上三角:leftUp
//              j<=10-i
//          右下三角:rightDown
//              j>=i
//      小三角:
//          左三角:left
//              左下三角與左上三角的交集
//              j<=i && j<=10-i
//          右三角:right
//              右上三角與右下三角的交集
//              j>=i && j>=10-i
//          上三角:up
//              右上三角除去右三角
//              j>=i && j <= 10 - i
//          下三角:down
//              左下三角除去左三角
//              j<=i && j >= 10 - i
//  3.關於關係運算子的準確適用:
//      要麼全部使用含有等於的符號
//      要麼全部使用不含等於的符號
//      母數等於最大數+1
//      左三角和右三角符號完全相同
//      上三角和下三角符號完全相反
int main(void)
{
    //show();

    //leftDown();

    //rightUp();

    //left();

    //right();

    //up();

    //down();

    //leftUp();

    //rightDown();

    system("pause");
}

//07.迴圈結構可以無限巢狀,但是企業開發不建議出現
int main02(void)
{
    for (;;)
    {
        for (;;)
        {
            while (1)
            {

            }
        }
    }
}

//08.將雙重for迴圈轉變成為雙重while迴圈
//  for迴圈和while迴圈可以進行完美轉換
int main03(void)
{
    int i = 1;
    while (i < 10)
    {
        int j = 1;
        while (j < 10)
        {
            if (j <= i)
            {
                printf("%d*%d=%2d\t", j, i, j*i);
            }
            j++;
        }
        printf("\n");
        i++;
    }

    system("pause");
}

程式片段(07):break.c
內容概要:break關鍵字

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main01(void)
{
    int num;

    scanf("%d", &num);
    for (int i = 1; i <= 100; i++)
    {
        if (num == i)
        {
            printf("i = %d \n", i);
            break;
        }
        else
        {
            printf("i != %d \n", i);
        }
    }

    system("pause");
}

//01.求解二元一次方程的解:
//  1.題目詳情:
//      13x+12y=100;
//      (13+12)*4=100
//      13i+12j=100;
//  2.窮舉法,列舉法,暴力破解法
//      規律:有N個元就需要N-1層迴圈結構
//  3.規律分析:
//      1.求解N元方程,就需要(N-1)層迴圈結構
//      2.選擇<=100/13作為迴圈條件的原因:
//          (1).迴圈體執行的次數為最小的情況
//          (2).小於等於是因為整數相除的結構一定有效
//              剛好整除-->剛好有效
//              不剛好整除-->由於省略了餘數進行取整,所以依然有效
//      3.由於兩個數比較特殊:
//          (13+12)*4=100-->所以求解方程也可進行特殊化處理
//          所以可以等效處理(因為只需要求取一個結果)
//                      (100 - 13*i) % 12 == 0
//          <==>  (100 - 12*i) % 13 == 0
int main02(void)
{
    for (int i = 0; i <= 100 / 13; i++)
    {
        if ((100 - 12 * i) % 13 == 0)
        {//這裡做了一個等效處理
            printf("13*%d+12*%d=100", i, i);
            break;//找到就進行退出
        }
    }

    system("pause");
}

//02.無限窮舉法,直到找到滿意的結果為止:
//  就可以使用break關鍵字
int main03(void)                
{
    for (int i = 0;; i++)
    {
        if (999 == i)
        { //break跳出包含break關鍵字的最內層迴圈,那麼
            break;//包含break關鍵字的最內層迴圈剩餘語句都將不會再次執行
        }
        printf("%d \n", i);
    }

    system("pause");
}

//11*x+13*y=316
//11*i+13*j=316
int main04(void)
{
    for (int i = 0;; i++)
    {
        if ((316 - 13 * i) % 11 == 0)
        {
            printf("11*%2d+13*%2d=316 \n", (316 - 13 * i) / 11, i);
        }
        if (13 * i > 316)
        {
            break;//break跳出死迴圈
        }
    }

    system("pause");
}

//03.百雞百錢問題:
//  已知:
//      小雞(1元3只),母雞(3元1只),公雞(5元一隻)
//  結果:
//      100元成功的購買了100只雞
//  分析:
//      x+y+z=100;
//      x*(1/3)+3*y+5*z=100;
//  規律:保證運算效率最高化
//      定z-->可以讓最外層迴圈次數最少
//          z
//      定y-->可以讓次外層迴圈次數最少
//          100-z=y+x;
//      不定x-->最高列舉遍歷效率
//          100-z-y=x;
//      利用兩個表示式求出結果進行比對
//          由於前面使用了求模運算子,所以這裡需要採用求與運算子進行確認
int main05(void)
{
    for (int i = 0; i <= 100 / 5; i++)
    {
        for (int j = 0; j <= (100 - i * 5) / 3; j++)
        {
            if (((100 - i - j) == ((100 - 5 * i - 3 * j) * 3)) && (100 - i - j) % 3 == 0)
            {
                printf("公雞:%2d只+母雞:%2d只+小雞:%2d只=100 \n", i, j, 100 - i - j);
            }
        }
    }

    system("pause");
}

程式片段(08):run.c
內容概要:continue關鍵字

#include <stdio.h>
#include <stdlib.h>

int main01(void)
{
    for (int i = 1; i <= 1000; i++)
    {
        if (i % 2 == 0)
        {//跳過偶數不進行列印
            //break;結束當前迴圈結構
            continue;//結束本次迴圈當中的剩餘執行體語句
        }
        printf("%3d \n", i);//只會具有列印奇數的機會
    }

    system("pause");
}

int main02(void)
{
    for (int i = 100; i <= 200; i++)
    {
        printf("%3d次! \n", i - 99);
        if (i % 3 == 0)
        {
            break;
            //continue;結束本次迴圈
        }
        printf("%d \n", i);
    }

    system("pause");
}

int main03(void)
{
    for (int i = 0; i < 10; i++)
    {
        if (3 == i)
        {
            break;
            //break;//break後面的任何語句都將不會再有被執行到的機會
        }

        for (int j = 0; j < 10; j++)
        {//縱向數字用i控制,橫向數字用j控制
            //十位用i控制,個位用j控制
            printf("%2d%2d \t", i, j);
        }
        printf("\n");
    }

    system("pause");
}

int main04(void)
{
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            if (j == 3)
            {//凡是個位為3的兩位數都將不會先進行列印
                continue;
                //continu;//本次迴圈執行體continue關鍵字後面的語句都將不會再有機會得到執行
                //break;//當前迴圈結構都將不會再有機會得到執行
            }
            printf("%2d%2d", i, j);
        }
        printf("\n");
    }

    system("pause");
}

int main05(void)
{
    if (1)
    {
        //continue;//只能用於迴圈結構當中
        //break;//只能用於迴圈結構以及switch選擇結構中
    }

    system("pause");
}

int main06(void)
{
    for (int i = 100; i < 200; i++)
    {
        if (i % 3 == 0)
        {
            printf("%d \n", i);
            //continue;
            break;//找到一個符合條件的就進行退出
        }
    }

    system("pause");
}

程式片段(09):goto.c+goto模擬.c
內容概要:goto語句

///goto.c
#include <stdio.h>
#include <stdlib.h>

int main01(void)
{//單執行緒處理
    system("notepad");
    main01();
}

//01.goto語句的執行特點:
//  1.從goto關鍵字直接跳至到語句標號的地方:
//      (1).無論在前還是在後,任意進行跳轉-->破壞結構化程式設計思想-->企業開發不常用-->幹壞事兒常用
//      (2).goto語句在當前函式的內部進行任意跳轉,不可跨函式跳轉
//      (3).goto語句不能對函式宣告標號,不能對程式碼塊兒識別符號"{}"進行標號,可以標識空行,可以標識程式碼
//  2.goto語句迴圈模擬特點:
//      每次從語句標號後面的冒號(":")開始執行,到goto關鍵字啊前端的g字母("g")結束
//      也就是說冒號(":")和字母("g")之間所描述的就是goto語句模擬的迴圈體內容
int main02(void)
{
Notepad: //printf("%d \n", 1);
    system("notepad");
    goto Notepad;//gotu只能用於當前函式體內部,不可跨函式訪問

    system("pause");
}

//02.遞迴迴圈的特點:
//  1.遞迴迴圈每次都會為函式開闢棧記憶體空間,佔用棧記憶體空間
//  2.遞迴迴圈的執行體範圍:
//      函式執行體的迴圈條件語句之後開始,一直到呼叫遞迴函式的第一個字母位置
//          這段兒叫做遞迴函式的真正執行體
//      這段區間如同goto語句當中的冒號(":")到g字母("g"),只不過goto
//          語句再次開闢額外的棧記憶體空間
//  3.遞迴迴圈當中如果需要使用到引數:
//      那麼需要在遞迴函式宣告的時候新增形參宣告,由此才能實現遞迴函式
//      之間的引數傳遞,儲存下來該引數
void go(int num)
{//先判斷條件,再決定是否執行的特點
    if (num >= 5)//退出
    {//遞迴出口-->相當於迴圈執行條件
        return;
    }
    system("notepad");

    num++;
    go(num);//自己呼叫自己
}

int main03(void)
{
    go(0);

    system("pause");
}

//03.採用goto語句模擬while迴圈結構:
//  1.實際上while和for兩種迴圈結構底層就是通過goto語句實現的
//      goto語句既可以實現whlie迴圈結構也可以實現for迴圈結構
//      區別在於迴圈初始條件放置在goto語句之內還是之外
//  2.goto語句模擬while迴圈結構體的方式:
//      (1).迴圈條件放置在語句標號前面
//      (2).迴圈條件判定放置在標號之內,因為每次都會進行判斷
//          所以需要迴圈判斷,也就是迴圈執行判斷
//      (3).在if語句的執行體之內,需要包含goto關鍵字,猶如模擬
//          while迴圈的執行體末尾,跳轉判斷條件
int main04(void)
{
    int i = 0;
AAA:if (i < 5)                                                               
    {
        system("notepad");
        i++;
        goto AAA;//順序執行
    }

    system("pause");
}

//04.goto語句可以用於跳出複雜迴圈結構:
//  由於其的任意跳轉特性,只要在一個函式體內部,那麼任意位置都可以
//      進行跳轉
//  通常情況之下,我們只能在本層迴圈結構當中控制本層迴圈結構的執行次數
//      但是,有了goto語句之後,我們可以實現在內層迴圈結構當中控制外層
//      迴圈的執行次數,但是外層迴圈不可以控制內層迴圈的執行次數
int main05(void)
{
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            if (i == 3)
            {//在內層迴圈當中控制外層迴圈的執行次數
                goto AAA;
            }
            printf("%d,%d", i, j);
        }
        printf("\n");
    }

AAA: system("notepad");//跳出複雜迴圈結構

    system("pause");
}

int main06(void)
{
    goto C;
    goto B;

A:  printf("AAA \n");
B:   printf("BBB \n");
C:   printf("CCC \n");
D:   printf("ATM \n");//一般複雜邏輯,不推薦使用goto語句,容易導致程式碼混亂,
    //破壞軟體程式設計原則-->容易出現廢話

    system("pause");
}
///goto模擬.c
#include <stdio.h>
#include <stdlib.h>

//01.goto語句可以實現模擬的情況:
//  1.迴圈結構:
//      for+while+do-while+遞迴迴圈
//  2.關鍵字:
//      continue+break;
int main07(void)
{
    for (int i = 100; i <= 200; i++)
    {
        if (i % 3 == 0)
        {
            printf("%d \n", i);
            break;
        }
    }

{//用於控制迴圈變數的作用域-->模擬for迴圈
        int i = 100;//迴圈初始化條件只會執行一次
    AAA:if (i <= 200)//迴圈條件判斷執行多次
    {//迴圈體內容
        if (i % 3 == 0)
        {
            printf("%d \n", i);
            goto DDD;//模擬break關鍵字的作用
        }
        i++;//迴圈區域終止的條件
        goto AAA;//迴圈體末尾的跳轉功能
    }
}
DDD:system("pause");

    system("pause");
}

int main08(void)
{
    for (int i = 100; i <= 200; i++)
    {
        if (i % 3 != 0)
        {
            continue;
        }
        printf("%d \n", i);
    }

{//控制迴圈變數的作用域
    int i = 100;//迴圈變數初始化條件
AAA:if (i <= 200)
    {
        if (i % 3 != 0)
        {
            i++;
            goto AAA;//等價於continue
        }
        printf("%d \n", i);
        i++;
        goto AAA;
    }
    printf("%d \n", i);
}

    system("pause");
}

程式片段(10):test.c
內容概要:Windows視窗訊息機制

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

//01.Windows窗體操作API介紹:
//  1.獲取窗體物件:
//      HWND win = FindWindowA("#32770", "message");
//          直接檢索父窗體物件
//          HWND win:窗體標號-->控制程式碼-->指標-->窗體物件
//          FindWindowA:檢索窗體物件;A表示使用窄字元
//              "#32770":窗體物件所在的描述類
//              "message":窗體物件的顯示標題
//      HWND ziwin = FindWindowExA(win, 0, "Button", "Button1"):
//          間接檢索子窗體物件
//          win:代表父窗體物件所在的控制程式碼
//          0:代表父窗體當中的第0個窗體
//          "Buttong"和"Button1"和上述描述一致
//  2.設定窗體物件:
//      SetWindowTextA:設定窗體標題
//      SendMessageA;給窗體發訊息
//          VM_CLOSE:關閉窗體
//          BM_CLICK:單擊窗體-->首次的時候相當於獲取焦點
//      ShowWindow:窗體顯示狀態
//          SW_HIDE:隱藏
//          SW_SHOW:顯示
//      EnableWindow:窗體啟用狀態
//          0:禁用
//          1:啟用
//      SetWindowPos:設定窗體座標
int main01(void)
{
    //win控制程式碼,操作視窗
    HWND win = FindWindowA("#32770", "message");
    if (win == NULL)
    {
        system("echo Window-玩兒失蹤! \n");
    }
    else
    {
        //SetWindowTextA(win, "3600-360流氓科技集團!");//控制程式碼,文字
        //SendMessageA(win, VM_CLOSE, 0, 0);//退出
        HWND zi = FindWindowExA(win, 0, "Button", "Button1");
        if (zi == NULL)
        {
            system("echo button-玩兒失蹤!");
        }
        else
        {
            SetWindowTextA(zi, "3600-360流氓科技集團!");

            //SendMessageA(zi, WM_CLOSE, 0, 0);//退出
            //SendMessageA(zi, BM_CLICK, 0, 0);//焦點-->第一次BM_CLICK等同於獲取焦點
            //Sleep(100);
            //SendMessageA(zi, BM_CLICK, 0, 0);//退出
            //SendMessageA(zi, BM_CLICK, 0, 0);//退出-->相當於雙擊效果

            //ShowWindow(zi, SW_HIDE);
            //Sleep(5000);

            //ShowWindow(zi, SW_SHOW);
            //EnableWindow(zi, 0);
            //Sleep(5000);
            //EnableWindow(zi, 1);//視窗啟用設定

            //for (int i = 0; i < 800; i++)
            //{
            //  //i,i 3,4設定 5,6大小 預設一定設定0
            //  SetWindowPos(win, NULL, i, i, 300, 500, SWP_SHOWWINDOW);
            //  Sleep(50);
            //}
        }
    }


    system("pause");
}

int main02(void)
{
    HWND win = FindWindowA("#32770", "message");
    if (NULL == win)
    {
        system("echo 父窗體-玩兒失蹤!");
    }
    else
    {
        HWND ziWin = FindWindowExA(win, 0, "Edit", "");
        if (NULL == ziWin)
        {
            system("echo 子窗體-玩兒失蹤!");
        }
        else
        {
            for (int i = 65; i < 130; i++)
            {
                //SendMessageA(ziWin, WM_CHAR, i, 0);//同步發訊息
                //PostMessageA(ziWin,WM_CHAR, i, 1);//非同步發訊息
                Sleep(500);
            }
        }
    }

    system("pause");
}

程式片段(11):變色龍.c
內容概要:變色龍

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <process.h>//程式操作相關函式的宣告標頭檔案
#include <time.h>

//01.作為執行緒的入口函式:
//  標準形參描述為乾地址
//      void *p
//  單條執行緒處理一個任務程式碼塊兒
//      任務程式碼塊兒內部依然是單執行緒
void timeset(void *p)
{//執行緒的main
    int i = 0;

    while (1)
    {
        char str[100] = { 0 };
        sprintf(str, "title 當前時間為第%03d秒", i);
        system(str);//執行指令
        Sleep(1000);//當前處理執行緒休眠1000毫秒
        i++;
    }

    system("color 3f");
}

//02.取餘運算子的使用技巧:
//  1.取餘任何整數,代表獲取比該整數小的任何整數
//  2.16進位制整數的組成元素只有16個0~F
//      0~1-->10個
//      A~F-->5個
void go()
{
    int num1 = rand() % 16;//取餘任何整數,代表獲取比其小的整數
    Sleep(10);
    int num2 = rand() % 16;
    char str[50] = { 0 };
    sprintf(str, "color %x%x", num1, num2);
    system(str);

    go();
}

void colorall(void *p)
{
    time_t ts;//獲取時間
    unsigned int num = (unsigned int)time(&ts);//獲取隨機數種子
    srand(num);//種植隨機數種子

    go();

    //for (;;)
    //{
    //  int num1 = rand() % 16;
    //  Sleep(10);//防止隨機數還未來得及變化
    //  int num2 = rand() % 16;
    //  char str[50] = { 0 };
    //  sprintf(str, "color %x%x", num1, num2);
    //  system(str);
    //}

    /*do
    {
        int num1 = rand() % 16;
        Sleep(10);
        int num2 = rand() % 16;
        char str[50] = { 0 };
        sprintf(str, "color %x%x", num1, num2);
        system(str);
    } while (1);*/

AAA:
    {
        int num1 = rand() % 16;
        Sleep(10);
        int num2 = rand() % 16;
        char str[50] = { 0 };
        sprintf(str, "color %x%x", num1, num2);
        system(str);
    }
    goto AAA;
}

int main01(void)
{
    //_beginthread(timeset, 0, NULL);

    //go();

    colorall(0);

    system("pause");
}

//03.多執行緒知識:
//  1.多執行緒任務程式碼塊兒:
//      多執行緒任務函式的編寫-->乾地址的使用
//  2.開啟輔助執行緒執行任務程式碼塊兒
//      _beginthread(timeset, 0, NULL);
//          開啟輔助執行緒
//          timeset:函式地址-->函式指標-->指向執行緒任務程式碼塊兒
//          0:出傳遞給執行緒任務程式碼塊兒的內容,通常是乾地址
//              用於跨函式訪問記憶體塊兒
//          NULL:為執行緒任務程式碼塊兒所開闢的棧記憶體空間
int main02(void)
{
    //system("color 3f");

    _beginthread(timeset, 0, NULL);
    _beginthread(colorall, 0, NULL);


    system("pause");
}

程式片段(12):Test.c
內容概要:資料分離與疑難

#include <stdio.h>

//01.程式碼塊兒可以無限巢狀:
//      但是函式巢狀,只能遞迴呼叫
//      函式不能巢狀定義
//      函式可以巢狀使用
int main01(void)
{
    //可以無限巢狀
    {
        {
            {
                {
                    {}
                }
            }
        }
    }

    system("pause");
}

//02.列印100~999之間的所有水仙花數:
//  水仙花數:個位的立方+十位的立方+百位的立方=其本身
//  舉例說明:479
int main02(void)
{
    //987
    //for (int i = 100; i <= 999; i++)
    //{
    //  int a = i % 10;//個位
    //  int b = i / 10 % 10;//十位
    //  int c = i / 10 / 10 % 10;//百位
    //  if (a*a*a + b*b*b + c*c*c == i)
    //  {//條件判斷
    //      printf("%d^3+%d^3+%d^=%d \n", a, b, c, i);
    //  }
    //}

{
    int i = 100;//迴圈初始化條件
AAA:if (i <= 999)
    {
        int a = i % 10;
        int b = i / 10 % 10;
        int c = i / 10 / 10 % 10;
        if (a*a*a + b*b*b + c*c*c == i)
        {
            printf("%d^3+%d^3+%d^3=%d \n", a, b, c, i);
        }

        i++;//迴圈趨於終止的條件
        goto AAA;
    }
}

    system("pause");
}

程式片段(13):斐波那契數列.c
內容概要:斐波那契數列

#include <stdio.h>
#include <stdlib.h>

//01.斐波那契數列:
//  規律:從第三位開始的每一個資料等於前兩個資料之和
//  總結:只需要建立一個後續的推導規律就行了
//      剩下的重複操作+數值推導就讓計算機去進行+計算過程
//      依照兩個初始化資料,不斷的丟掉舊資料,建立新的資料
//      依次方便於計算機的後續推導流程
//02.輪替的特點:
//  就是讓第一個資料不斷的丟失掉,讓後續資料不斷的跟上來
int main01(void)
{
    int f1 = 1;//初始化計算機推導條件
    int f2 = 2;
    int f3 = 0;

    printf("%d \n", f1);
    printf("%d \n", f2);

    for (int i = 3; i <= 40; i++)
    {//待推導的位數為40
        f3 = f1 + f2;//只要建立了這個關係-->就行了-->剩下的計算機去完成所有的關係計算-->與資料推導
        printf("%d \n", f3);
        f1 = f2;//輪替-->丟掉第一個資料,將資料不斷的進行遷移操作
        f2 = f3;
    }

    system("pause");
}

程式片段(14):go.c
內容概要:質數相關

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//01.質數窮舉法:
//  質數:
//      除去1和其本身之外,沒有其它的約數
//      1之後的資料不是質數就是合數
//  特殊資料:
//      1既不是質數也不是合數
//      1和2的情況需要排除開來    
int isit(int num)//1,0
{
    if (num <= 1)
    {
        return 0;
    }
    else if (num == 2)
    {
        return 1;
    }
    else
    {//將多數情況設定為一個變數,一旦不成立,就將其給否定
        int flag = 1;//預設標記為是質數,只要找到一個約數,就將其給否定
        for (int i = 2; i < num; i++)
        {//遍歷從2到其本身-1的整數
            if (num % i == 0)
            {
                return 0;
            }
        }
        return 1;
    }
}

int main01(void)
{
    //printf("%d \n", isit(33));

    for (int i = 100; i < 150; i++)
    {
        if (isit(i))
        {
            printf("%d \n", i);
        }
    }

    system("pause");
}

//4=2+2,8=3+5,10=5+5
//7=2+2+3,9=3+3+3,11=3+3+5
int main02(void)
{
    int num = 0;

    scanf("%d", &num);
    printf("%d \n", num);

    for (int i = 2; i <= num / 2; i++)
    {
        if (isit(i) && isit(num - i))
        {
            printf("\n num = %d + %d \n", i, num - i);
        }
    }

    system("pause");
}

int main03(void)
{
    int num = 0;

    scanf("%d", &num);
    printf("%d \n", num);

    for (int i = 2; i <= num / 2; i++)
    {//減少判斷次數
        for (int j = 2; j <= num / 2; j++)
        {//減少判斷次數
            if (isit(i) && isit(j) && isit(num - i - j))
            {//三個條件一起進行判斷
                printf("num=%2d+%2d+%2d \n", i, j, num - i - j);
            }
        }
    }

    system("pause");
}

程式片段(15):run.c
內容概要:整數逆轉

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

//01.整數逆置的原理:
//1234567解析位數為8位:
//  規律解析:
//      1234567---->
//      123456----->
//      12345------->
//      1234-------->
//      123--------->
//      12----------->7個對映對
//      1------------->7位數-->先判斷再執行的方案
//  數字統計:
//      %10-->取出個位
//      /10--->去除個位
//  判斷條件:
//      整個資料為0就不需要再次逆置
//02.整數逆置的方式一:
//  for迴圈實現
int main01(void)
{
    int num = 0;
    int newnum = 0;

    scanf("%d", &num);
    printf("%d \n", num);

    for (; num; num /= 10)//去除個位
    {//判斷整數是否整個都已經為0了
        int temp = num % 10;//取出個位
        newnum = newnum * 10 + temp;//新數以前各位進行提升,後來的數作為個位補充
    }
    printf("newnum = %d \n", newnum);

    system("pause");
}

//03.整數逆置的方式二:
//  while迴圈實現
int main02(void)
{
    int num = 0;
    int newnum = 0;

    scanf("%d", &num);
    printf("%d \n", num);

    while (num)//迴圈條件判斷:待逆置的整數不能整個資料都為0,允許中間位為0
    {
        int temp = num % 10;//不斷的取出個位的操作
        newnum = newnum * +temp;//新數的原來所有位不斷的進行向高位提升,後來的位作為個位的補充
        num /= 10;//不斷的進行去除個位的步驟
    }
    printf("newnum=%d \n", newnum);

    system("pause");
}

//04.整數逆置的方式三:
//  do-while迴圈實現
//  排除for+while當中的0進入現象就行了
//  for和while會自動剔除0進入的現象
//  但是do-while迴圈不會排除這種情況,因為先執行,再判斷的特點
int main03(void)
{
    int num = 0;
    int newnum = 0;

    scanf("%d", &num);
    printf("%d \n", num);

    if (num != 0)
    {
        do
        {
            int temp = num % 10;//不斷的取出待逆置資料的個位
            newnum = newnum * 10 + temp;//逆置之後的資料不斷的向高位提升,剩下一個個位,用當前獲取的個位進行補充
            //取出一次個位,去除一次個位
            num /= 10;//不斷的去除待逆置資料的個位
        } while (num);
    }
    printf("newnum = %d \n", newnum);

    system("pause");
}

//05.整數逆置的方式四:
//  goto語句模擬迴圈實現整數逆置
int main04(void)
{
    int num = 0;
    int newnum = 0;

    scanf("%d", &num);
    printf("%d \n", num);

AAA:if (num)
    {
        int temp = num % 10;//不斷的取出待逆置整數的個位
        newnum = newnum * 10 + temp;//不斷的將逆置之後的整數向高位進行提升,提升之後空餘的個位採用剛取出的個位補上

        num /= 10;//不斷的去除待逆置整數的個位
        goto AAA;//回到迴圈判斷條件
    }
    printf("%d \n", newnum);

    system("pause");
}

//06.整數逆置的方式五:
//  遞迴迴圈模擬整數逆置
int revInt(int num, int newnum)
{//待逆置的資料,逆置之後的資料-->如果迴圈之間需要不斷的使用到資料,就需要進行傳遞(在遞迴當中)
    if (num == 0) {//迴圈條件判斷
        return newnum;//一層一層的將資料給帶出-->資料帶出
    }
    else
    {
        int temp = num % 10;//不斷的取出待逆置整數的個位
        newnum = newnum * 10 + temp;//不斷的將逆置之後的整數向高位進行提升,提升之後的個位空餘就採用個位補上
        revInt(num /= 10, newnum);//迴圈結構裡面所涉及到的每次將要使用到的兩個資料
    }
}

int main05(void)
{
    int num = 0;
    int newnum = 0;

    scanf("%d", &num);
    printf("%d \n", num);
    newnum = revInt(num, newnum);
    printf("%d \n", newnum);

    system("pause");
}

程式片段(16):go.c
內容概要:解決習題

#include <stdio.h>
#include <stdlib.h>

#define 尊嚴上的安全感 15
#define 經濟上的安全感 22
#define 情感上的安全感 28

#define 帥 98
#define 富 88
#define 高 97

int main01(void)
{
    if (帥 > 尊嚴上的安全感)
    {
        printf("%d-->%d \n", 尊嚴上的安全感, 帥);
    }
    if (富 > 經濟上的安全感)
    {
        printf("%d-->%d \n", 經濟上的安全感, 富);
    }
    if(高 >情感上的安全感)
    {
        printf("%d-->%d \n", 情感上的安全感, 高);
    }

    system("pause");
}

#define 吸引力 80
#define 高價值 80

int main02(void)
{
    if (吸引力 > 50 && 高價值 > 50)
    {

    }

    system("pause");
}

double get100(int n, double num)
{
    if (0 == n)
    {
        return 1.0;
    }
    else
    {
        return num * get100(n - 1, num);
    }
}

int main03(void)
{
    printf("%lf", get100(420, 1.01));
    printf("%lf, %lf, %lf, %lf \n", get100(365, 0.99), get100(365, 0.98), get100(365, 1.01), get100(365, 1.02));

    system("pause");
}

相關文章