20160130.CCPP體系詳解(0009天)

尹成發表於2016-02-16

程式片段(01):hanoi.c+漢諾塔.c
內容概要:漢諾塔

///hanoi.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main01(void)
{
    //int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };//一維陣列,程式碼塊兒初始化方式(指定)
    //for (int i = 0; i < 10; i++)
    //{
    //  printf("%5d", a[i]);//陣列的索引都是從0開始的
    //}

    int a[10][3] = { 0 };//二維陣列,程式碼塊兒初始化方式(統一)
    for (int i = 0; i < 10; i++)
    {//行
        for (int j = 0; j < 3; j++)
        {//列
            printf("%5d", a[i][j]);
        }
        printf("\n");
    }

    system("pause");
}

int main02(void)
{
    int n = 0;
    int a[10][3] = { 0 };//二維陣列,程式碼塊兒初始化方式(統一)

    scanf("%d", &n);
    for (int i = 0; i < n; i++)//控制
    {//-1的原因是因為,索引最大為9,索引最大,賦值卻最小-->索引逆向賦值i=0-->index=10-1-i-->sequence=10-0
        a[10 - 1 - i][0] = n - i;//佈局
    }
    for (int i = 0; i < 10; i++)//控制行
    {
        for (int j = 0; j < 3; j++)//控制列
        {
            printf("%5d", a[i][j]);
        }
        printf("\n");
    }

    system("pause");
}
///漢諾塔.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int hanoiTower[10][3] = { 0 };//二維陣列,程式碼塊兒初始化(統一形式)

//01.將二維陣列的操作採用圖形化方式模擬出來:
//  1.設計操作流程:
//      漢諾塔邏輯實現-->顯示漢諾塔流程-->補充函式說明
//  2.所涉及到的設計模式:
//      MVC設計模式(簡化版本)

//漢諾塔輔助程式
void movehanoiTower(char x, char y);//移動漢諾塔的過程當中,保留移動痕跡到二維陣列(邏輯&資料-->連結起來)
//漢諾塔邏輯實現
void hanoiTowerLogic(unsigned int n, char i, char j, char k);//漢諾塔主邏輯
//顯示漢諾塔流程
void showHanoiTower(int hanoiTower[10][3]);//顯示漢諾塔資料

void moveHanoiTower(char x, char y)
{
    //實質:就是陣列當中兩個位置的字元資料之間的交換
    //hanoiTower[imove][m]<--->hanoiTower[jmove][n];
    int m = x - 65;//字元形式轉換為整數相差形式(間接記憶字元)
    int n = y - 65;
    int imove = -1;
    int jmove = -1;

    for (int i = 0; i < 10; i++)
    {
        if (0 != hanoiTower[i][m])
        {//檢索第一個不為0的
            imove = i;
            break;
        }
    }

    if (0 == hanoiTower[9][n])
    {
        jmove = 9;
    }
    else
    {
        jmove = 10;
        for (int i = 0; i < 10; i++)
        {
            if (0 != hanoiTower[i][n])
            {
                jmove = i;
                break;
            }
        }
        jmove -= 1;
    }

    //將用於間接記憶字元的整數形式進行交換
    int temp = hanoiTower[imove][m];
    hanoiTower[imove][m] = hanoiTower[jmove][n];
    hanoiTower[jmove][m] = temp;
}

void hanoiTowerLogic(unsigned int n, char i, char j, char k)
{
    if (0 == n)
        return;
    else if (1 == n)
    {
        //printf("%c-->%c \n", i, k);
        moveHanoiTower(i, k);
        showHanoiTower(hanoiTower);
        return;
    }
    hanoiTowerLogic(n - 1, i, k, j);
    //printf("%c-->%c \n", i, k);
    moveHanoiTower(i, k);
    showHanoiTower(hanoiTower);
    hanoiTowerLogic(n - 1, j, i, k);
}

void showHanoiTower(int hanoiTower[10][3])
{
    printf("%5c%5c%5c \n", 'A', 'B', 'C');
    printf("---------------\n");
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            printf("%5d", hanoiTower[i][j]);
        }
        printf("\n");
    }
}

int main(void)
{
    int n = 0;

    scanf("%d", &n);
    for (int i = 0; i < n; i++)//控制
    {
        hanoiTower[n - 1 - i][0] = n - i;//佈局
    }
    hanoiTowerLogic(n, 'A', 'B', 'C');
    showHanoiTower(hanoiTower);


    system("pause");
}

程式片段(02):QQ.c
內容概要:調戲妹子上QQ

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

int main01(void)
{
    //HWND win = FindWindowA("TXGuiFoundation", "QQ");
    HWND    win = FindWindowA("StandardFrame", "阿里旺旺");

    int i = 0;
    POINT point;
    point.x = point.y = 0;
    time_t te;
    unsigned int seed = (unsigned int)time(&te);
    srand(seed);
    int rnum = 0;

    while (1)
    {
        GetCursorPos(&point);
        rnum = rand() % 4;
        switch (rnum)
        {
        case 0:
            SetWindowPos(win, NULL, point.x - 500, point.y - 500, 0, 0, 1);//1:禁止修改窗體尺寸
            break;
        case 1:
            SetWindowPos(win, NULL, point.x + 500, point.y - 500, 0, 0, 1);
            break;
        case 2:
            SetWindowPos(win, NULL, point.x - 500, point.y + 500, 0, 0, 1);
            break;
        case 3:
            SetWindowPos(win, NULL, point.x + 500, point.y + 500, 0, 0, 1);
            break;
        }

        Sleep(1000);
        ++i;
        if (1000 == i)
            //break;//跳出
            return;//結束
    }
    system("taskkill /f /im iexplore.exe");
    MessageBoxB(0, "發現病毒", "提示資訊", 0);

    system("pause");
}

程式片段(03):模組.c
內容概要:鬼哭神嚎

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <time.h>
#include <process.h>//多執行緒

//01.如何將一個控制檯應用程式轉換成為Windows應用程式:
//      控制檯-->Windows:實質就是去掉黑視窗
//      控制檯應用程式-->連結為-->Windows應用程式(可有Windows視窗,也可以沒有)
#pragma comment (linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

void setDktopBkgroundPicture(char *path)
{
    SystemParametersInfoA(20, 0, path, 3);
}

void setBkgroundMusic(char *path)
{
    ShellExecuteA(0, "open", path, 0, 0, 0);//0:代表隱藏(最後一個)
}

void setFegroundText(int x, int y, char * text)
{
    HWND win = GetDesktopWindow();//獲取系統窗體(當前程式執行時所顯示的整個窗體)
    HDC dc = GetWindowDC(win);//獲取裝置的上下文(以待用於進行設定)
    SetTextColor(dc, RGB(255, 0, 0));
    SetBkColor(dc, RGB(0, 0, 255));

    while (1)
    {
        TextOutA(dc, 300, 400, text, strlen(text));//顯示文字
        Sleep(2000);
    }
}

void bgJpgPicture(void *p)
{
    int rnum = 0;
    char *path[200] = { 0 };
    time_t te;
    unsigned int seed = (unsigned int)time(&te);
    srand(seed);


    while (1)
    {
        rnum = rand() % 9;
        sprintf(path, "C:\\Users\\ZHEN\\Desktop\\TestPictore\\%d.jpg", rnum);
        setDktopBkgroundPicture(path);
        Sleep(1000);
    }
}

void bgMp3Music(void *p)
{
    int rnum = 0;
    char *path[200] = { 0 };
    time_t te;
    unsigned int rseed = (unsigned int)time(&te);
    srand(rseed);

    while (1)
    {
        system("taskkill /f /im mediaplayer.exe");
        rnum = rand() % 4;
        sprintf(path, "C:\\Users\\ZHEN\\Desktop\\TestMp3\\%d.mpe", rnum);
        setBkgroundMusic(path);
        Sleep(10000);
    }
}

void feFontText(void *p)
{
    setFegroundText(50, 50, "i love you!!!");
}

int main01(void)
{
    setDktopBkgroundPicture("C:\\Users\\ZHEN\\Desktop\\TestPicture\\3.jpg");
    setBkgroundMusic("C:\\Users\\ZHEN\\Desktop\\TestMusic\\3.mp3");
    setFegroundText(30, 40, "測試文字");

    //02.開啟多執行緒執行某一段兒執行緒任務程式碼:
    //  _beginthread(arg1, arg2, arg3);
    //      arg1:執行緒任務程式碼
    //      arg2:棧記憶體尺寸
    //      arg3:執行緒任務引數
    _beginthread(bgJpgPicture, 0, NULL);
    _beginthread(bgMp3Music, 0, NULL);
    _beginthread(feFontText, 0, NULL);

    system("pause");
}

程式片段(04):位運算.c
內容概要:列印整數原碼補碼反碼

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

//01.位運算使用注意事項:
//  1.位運算只是適用於整數的,不適用於實數
//  2.由於兩者的儲存方式不一樣:
//      整數採取的是補碼進行儲存
//      實數採取的是階碼進行儲存
//02.如何不斷的獲取一個整數的二進位制形式的最高位?
//      舉例:原理圖
//          10101010010100      
//      &   10000000000000      
//      ----------------------
//          10000000000000
//      步驟:執行體
//          0.不斷的判斷是否將整數的32位全部移完
//          1.不斷的將整數進行左移位(<<)運算
//          2.不斷的用1進行按位與(&)運算
//03.如何確定兩個二進位制位進行加法運算之後的對應的二進位制位數是多少?
//      舉例:原理圖
//          00      0       0^0-->0
//          01      1       0^1-->1
//          10      1       1^0-->1
//          11      0       1^1-->0
//      異或運算子特性
//          可以模擬兩個二進位制位加法運算之後,所對應的具體二進位制位是多少.
//04.正負整數的原碼反碼補碼使用規律:
//  1.記憶體當中所有的整數都是按照補碼進行儲存的!
//      所以列印所有整數的補碼就等同於直接列印整數的記憶體儲存形式
//  2.正整數的原碼反碼和補碼相同(就是直接的記憶體儲存形式)
//  3.負整數的原碼反碼和補碼不相同:
//      補碼:就是直接的記憶體儲存形式,可以進行直接列印
//      反碼:就是補碼-1
//      原碼:補碼-->對補碼(求反,再+1)-->得到原碼(符號位丟失,需要補充符號位)
int main01(void)
{//正整數的原碼
    int inum = 0;
    int num1L31 = 1 << 31;

    scanf("%d", &inum);
    for (int i = 1; i <= 32; i++)
    {
        if (inum & num1L31)
            putchar('1');
        else
            putchar('0');

        if (0 == i % 4)
            printf(" ");

        inum <<= 1;
    }

    system("pause");
}

int main02(void)
{//正負整數的原碼
    int inum = 0;
    int num1L31 = 1 << 31;

    scanf("%d", &inum);
    if (inum < 0)
    {
        //0000 0000 0000 0110   +6:原碼
        //1000  0000     0000 0110   -6:原碼
        //1111 1111 1111 1001    -6:反碼(取反)
        //1111 1111 1111 1010    -6:補碼(加一)
        //0000 0000 0000 0101    -6:補碼(再取反)
        //0000 0000 0000 0110    -6:補碼(再加一)
        //1000 0000 0000 0110    -6:補碼(補符號)
        inum = ~inum + 1;//負數的原碼(符號位丟失)
        inum = inum | num1L31;//補充符號位
    }
    for (int i = 1; i <= 32; i++)
    {
        if (inum & num1L31)
            putchar('1');
        else
            putchar('0');
        if (i % 4 == 0)
            printf(" ");
        inum <<= 1;
    }

    system("pause");
}

int main03(void)
{//正負整數的反碼
    int inum = 0;
    int num1L31 = 1 << 31;

    scanf("%d", &inum);
    if (inum < 0)
    {
        inum = inum - 1;//負整數的反碼
    }
    for (int i = 1; i <= 32; i++)
    {
        if (inum & num1L31)
            putchar('1');
        else
            putchar('0');
        if (0 == i % 4)
            printf(" ");
        inum <<= 1;
    }

    system("pause");
}

程式片段(05):補碼原碼反碼.c
內容概要:補碼原碼反碼轉換工具

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

//獲取整數(正負整數)的補碼(機器儲存形式)
void binBCode(int inum, char binStr[33])
{
    int num1L31 = 1 << 31;
    for (int i = 1; i <= 32; i++)
    {//1:進來的哪一次就是1-->1~32-->共32個對映對
        if (inum & num1L31)
            binStr[i - 1] = '1';
        else
            binStr[i - 1] = '0';
        inum <<= 1;
    }
}

//獲取整數(正負整數)的反碼
void binFCode(int inum, char binStr[33])
{
    int num1L31 = 1 << 31;

    if (inum < 0)
    {
        --inum;
    }
    for (int i = 1; i <= 32; i++)
    {
        if (inum & num1L31)
            binStr[i - 1] = '1';
        else
            binStr[i - 1] = '0';
        inum <<= 1;
    }
}

//陣列的副本(實體資料)拷貝浪費記憶體,所以陣列預設採用傳址(地址)
//獲取整數(正負整數)的原碼
void binYCode(int inum, char binStr[33])
{
    int num1L31 = 1 << 31;

    if (inum < 0)
    {
        inum = ~inum + 1;//負整數的原碼(丟失符號位)
        inum = inum | num1L31;//(補充符號位)
    }
    for (int i = 1; i <= 32; i++)
    {
        if (inum & num1L31)
            binStr[i - 1] = '1';
        else
            binStr[i - 1] = '0';
        inum <<= 1;
    }
}

int main(void)
{
    int inum = 0;
    char strBinY[33] = { 0 };
    char strBinF[33] = { 0 };
    char strBinB[33] = { 0 };

    scanf("%d", &inum);
    binYCode(inum, strBinY);
    printf("%s \n", strBinY);
    binFCode(inum, strBinF);
    printf("%s \n", strBinF);                                                   
    binBCode(inum, strBinB);
    printf("%s \n", strBinB);


    system("pause");
}

程式片段(06):進位制.c
內容概要:進位制轉換工具

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

//01.十進位制轉任意進位制的原理:
//  十進位制     二進位制     八進位制     十六進位制
//  10   /2=5   %2=0        %8=2       %16=10
//    5  /2=2   %2=1       %8=1       0xA
//    2  /2=1   %2=0        012
//    1  /2=0   %2=1
//                   1010
//  原理解析完畢:
//02.二進位制轉任意進位制的原理:
//  十進位制:每個位進行運算
//  八進位制:將二進位制當中的每3個二進位制位當中一個8進位制位處理
//  十六進:將二進位制當中的每4個二進位制位當中一個16進位制位處理
void decToBin(int inum, char binStr[33], int i)
{
    if (0 == inum)
        return;
    binStr[i] = inum % 2;
    decToBin(inum / 2, binStr, ++i);
}

int main(void)
{
    char binStr[33] = { 0 };
    decToBin(10, binStr, 1);
    printf("%s", binStr);

    system("pause");
}

//void to2str(int num, int i, char str2[32])
//{
//      to2str(num / 2,i+1,str2);//位數向前
//      //printf("%d", num % 2);
//      str2[i] = (num % 2) + '0';//字元整數的轉換
//  }
//
//}
//void to8str(int num, int i, char str8[32])
//{
//  if (num == 0)
//  {
//      return;
//  }
//  else
//  {
//      to8str(num / 8,i+1,str8);
//      str8[i] = (num % 8) + '0';//字元整數的轉換
//  }
//}
//
//void to16str(int num, int i, char str16[32])
//{
//  if (num == 0)
//  {
//      return;
//  }
//  else
//  {
//
//      to16str(num / 16,i+1,str16);
//      //printf("%x", num % 16);
//      if (num % 16<10)
//      {
//          str16[i] = (num % 16) + '0';//字元整數的轉換
//      } 
//      else
//      {
//          //10,11,12,13,14,15
//          str16[i] = (num % 16) - 10 + 'A';
//      }
//
//  
//      //'A' 10
//  }
//
//}
//
//void main()
//{
//
//  int num = 0;
//  char str2[32] = { 0 };
//  char str8[32] = {0};
//  char str16[32] = {0};
//
//
//  scanf("%d", &num);
//
//
//  to2str(num,0,str2);
//  _strrev(str2);
//  printf("\n%s", str2);
//
//
//  to8str(num, 0, str8);
//  _strrev(str8);
//  printf("\n%s", str8);
//
//  to16str(num, 0, str16);
//  _strrev(str16);
//  printf("\n%s", str16);
//
//
//  getchar();
//  getchar();
//}
//
//void to2(int num)
//{
//  if (num==0)
//  {
//      return;
//  } 
//  else
//  {
//
//      to2(num / 2);
//      printf("%d", num % 2);
//  }
//
//}
//
//void to8(int num)
//{
//  if (num == 0)
//  {
//      return;
//  }
//  else
//  {
//
//      to8(num / 8);
//      printf("%d", num % 8);
//  }
//
//}
//
//void to16(int num)
//{
//  if (num == 0)
//  {
//      return;
//  }
//  else
//  {
/**重點內容**/
//      to16(num / 16);
//      printf("%x", num % 16);
//  }
//
//}
//
//
//void main1()
//{
//  int num = 0;
//  scanf("%d", &num);
//  to2(num);
//  printf("\n");
//  to8(num);
//  printf("\n");
//  to16(num);
//  getchar();
//  getchar();
//}

程式片段(07):add.c
內容概要:時間程式設計

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

//01.register&volatile關鍵的使用:
//  1.使用意義不同:
//      register:標識暫存器變數
//      volatile:標識記憶體變數,強制讀取記憶體變數
//      特點:register暫存器變數運算較快於volatile記憶體變數
//          因為其減少了不必要的讀取記憶體時間(讀取過程時間)
//  2.編譯器的優化特點不同:
//      如果一個記憶體變數被頻繁的進行使用,那麼:
//      VC編譯器:會自動進行優化操作
//      GCC編譯器:不會進行自動優化操作
//      特點:register對GCC有效,對VC可能無效,VC不聽話
//  3.內容總結:
//      (1).在程式執行過程當中,根據需要到記憶體中的相應變數儲存
//          單元中進行呼叫,如果一個變數在程式中頻繁使用,例如迴圈變數
//          那麼,系統就必須多次訪問該記憶體中的變數單元,影響程式的執行效率
//          因此,CCPP語言當中還定義了一種變數,不是儲存在記憶體之中的變數
//          而是直接儲存於CPU內部的暫存器當中,這種變數被稱之為暫存器變數
//      (2).暫存器變數的定義形式為:
//          register 型別識別符號 變數名;
//      (3).暫存器與機器硬體密切相關,不同型別的計算機,暫存器的數目是不一樣的
//          通常為2到3個,對於在一個函式中說明的多餘2到3個的暫存器變數,C編譯
//          程式會自動的將暫存器變數變為自動變數
//      (4).暫存器說明符只能用於說明函式中的區域性變數和函式中的形參變數,因此
//          不允許將全域性變數或者靜態變數說明為"register"形式.
//              VC會自動進行暫存器變數的優化,不可以對暫存器變數進行取記憶體地址操作
//              GCC需要手動指定,MINGW是GCC編譯器移植到Windows的版本
//                  C語言暫存器變數不可以進行取記憶體地址操作,C++可以,因為C++會
//                  在記憶體當中給C語言暫存器變數儲存一個副本
//  4.特殊特點總結:
//      某些情況之下的變數必須強制讀記憶體,因為暫存器變數如果隨時都在變化,而多執行緒
//          情況之下每條執行緒訪問的都是同一個記憶體變數,如果遲遲不進行讀取記憶體的操作
//          那麼,暫存器變數的變數不會被對映到記憶體變數當中,導致資料變化不能及時生效
int main01(void)
{
    time_t start, end;
    time(&start);//獲取開始時刻的時間

    //進行浮點數運算的模擬
    volatile double result = 0;
    //VC會自動將頻繁使用的記憶體變數優化為暫存器變數
    for (volatile double i = 0; i < 100000000; i++)
    {
        result += i*1.0;
    }

    time(&end);//獲取結束時刻的時間
    printf("消耗的時間為:%f \n", difftime(end, start));
}

int main02(void)
{
    time_t start, end;
    time(&start);

    register double result = 0;
    for(register double i = 0; i < 100000000; i++)
    {
        result += i *1.0;
    }

    time(&end);
    printf("消耗時間為:%f \n", difftime(end, start));
}

//02.測試暫存器變數和記憶體變數的最佳方式:是通過相同階段的CPU進行測試才能最準確:
//      原理:讓一條執行緒通過一條執行流處理記憶體變數和暫存器變數-->這樣的誤差最小
//          免得CPU運算赫茲忽高忽低
int main03(void)
{
    main01();
    main02();//同樣的程式碼段兒被載入進記憶體,如果執行相同的操作CPU也會進行優化操作

    system("pause");
}

程式片段(08):main.c
內容概要:TestTime

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

int main01(void)
{
  time_t start, end;
  time(&start);

  volatile double result = 0.0;
  volatile int i;//GCC當中的迴圈變數必須申明在for迴圈外部
  for (i = 0; i < 100000000; i++)
  {//沒有優化double是記憶體變數,13s;採取優化double是暫存器變數,3s
    result+=i*1.0;
  }

  time(&end);
  printf("消耗時間為:%f \n", difftime(end, start));
}

int main02(void)
{
  time_t start, end;
  time(&start);

  register double result = 0.0;
  register int i;
  for (i = 1; i < 100000000; i++)
  {
    result += i*1.0;
  }

  time(&end);
  printf("消耗時間為:%f \n", difftime(end, start));
}

int main(void)
{
  main01();
  main02();
}

程式片段(09):run.c+test.c
內容概要:dll呼叫

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

_declspec(dllexport)  void go()
{
    MessageBoxA(0, "World", "Hello", 0);
}

_declspec(dllexport) int add(int a, int b)
{
    return a + b;
}
///test.c
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

//01.如何獲取函式指標型別?
//  將函式宣告頭的函式名稱替換為(*函式指標名稱)
//  舉例:void fp();-->void (*fp)();
//      fp的型別就是void (*)();
//  void go()---->void (*fp1)();
// int add(int a, int b)---->int (*fp2)(int a, int b);
//02.如何使用動態庫?
//  動態庫載入LoadLibraryA();
//  動態庫函式GetProcAddress();
//  動態庫釋放FreeLibrary();

int main01(void)
{
    HMODULE hmod = LoadLibraryA("01.DLL呼叫.dll");//動態庫載入
    if (NULL == hmod)
    {
        system("echo error load! \n");
    }
    void(*fp1)() = (void(*)())GetProcAddress(hmod, "go");
    int(*fp2)(int a, int b) = (int(*)(int a, int b))GetProcAddress(hmod, "add");
    if (NULL == fp1 || NULL == fp2)
    {
        system("echo error find! \n");
    }
    else
    {
        fp1();
        printf("%d \n", fp2(10, 20));
    }
    FreeLibrary(hmod);//動態庫釋放

    system("pause");
}

程式片段(10):add.c
內容概要:計算器

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

//01.規律說明:
//  100%7=2
//      100求餘7之後為2
//  100-(100/7)*7=2
//      100減去整除數*7=2
//  5%3=2
//  73%4=1  73%5=3
//  74%4=2  74%5=4
//  75%4=3  75%5=0
//      73---->0100 1001
//  %     4---->0000 0100
//------------------------
//        1         0000 0001

//      74---->0100 1010
//  %     4---->0000 0100
//------------------------
//        2         0000 0010

//10-->2
//100-->4
//1000-->8
//10000---16

//      73---->0100 1001
//  %   5---->0000 0101
//------------------------
//        3---->0000 0011
int main(void)
{
    unsigned int num = 73;//餘數
    printf("%d \n", num - (num & ~3));

    system("pause");
}

////11  0  1
////10  1  0
////01  1  0
////00  0  0
//
////0011  3      15
////0101  5      16
//             //21  +10
////0010  進位
//
////0110   ^ 6
//
////1000  8
//
//int add(int a,int b)
//{
//  int wei = 0;
//  int jinwei = 0;
//
//  do 
//  {
//      wei = a^b;//處理位加法
//      jinwei = (a&b) << 1;//進位
//
//      a = wei;//沒有進位的加法
//      b = jinwei;//進位
//  } while (b!=0);
//      return a;
//}
//
//
//int  dadd(int a, int b)
//{
//  if (b==0)
//  {
//      return a;
//  } 
//  else
//  {
//      int wei = a^b;
//      int jinwei = (a&b) << 1;
//      dadd(wei, jinwei);
//  }
//}
//
//
//void main1()
//{
//  printf("%d", dadd(113, 15));
//  getchar();
//}

程式片段(11):go.c
內容概要:最小公倍數最大公約數

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

//01.最小公倍數和最大公約數:
//  條件:現有兩個整數num1和num2
//  那麼:num1*num2=minGB*maxGY;
//  程式設計:
//      方式一:
//          假設num1<num2
//          最小公倍數:
//              從兩個整數當中較大的那個整數開始向大數遍歷
//              如果(0==num/num2)&&(0==num/num1)
//          最大公約數:
//              從兩個整數當中較小的那個整數開始向小數遍歷
//              如果(0==num1/num)&&(0==num2/num)
//      方式二:
//          利用:num1*num2=minGB*maxGY

//02.舉例說明特點:
//  num1=10;num2=25;
//      10      25      50-->minGB
//      10      25      5--->maxGY
//  原理:輾轉相除法
//      10 % 25 = 10;   //被除數/除數=餘數
//      25 % 10 = 5;    //除數/餘數
//      10 % 5 = 0;     //除數/餘數
int maxGY(int i, int j)
{
    if (0 == i % j)
        return j;//跳出
    else
        return maxGY(j, i % j);//遞迴
}

int main01(void)
{
    int a = 25;
    int b = 110;

    printf("%d, %d \n", maxGY(25, 110), 25 * 110 / maxGY(25, 110));

    system("pause");
}

程式片段(12):猜數字.c
內容概要:猜數字

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

//01.健壯的應用程式當中經常使用abort提示錯誤:
//  1.相當於其它語言當中的異常處理機制模擬
//  2.區分編譯錯誤和執行時異常
//      編譯錯誤:程式碼本身存在語法錯誤
//      執行時異常:實在編譯沒有錯誤的情況之下發生的
int main01(void)
{
    int a, b;

    scanf("%d%d", &a, &b);
    if (b == 0)
    {
        abort();//提示錯誤
    }
    else
    {
        int c = a / b;
    }

    system("pause");
}

int main02(void)
{
    time_t te;
    unsigned int rseed = (unsigned int)time(&te);
    srand(rseed);
    int rnum = rand() % 100 + 1;//1~100
    int gnum = 0;

    while (1)
    {
        scanf("%d", &gnum);
        if (rnum > gnum)
            puts("小了");
        else if (rnum < gnum)
            puts("大了");
        else
        {
            puts("小夥子才對了! ");
            break;
        }
    }

    //這後面的程式碼需要放置於多執行緒當中執行才行
    int i = 0;//否則限時功能不會生效
    while (1)
    {

        Sleep(1000);
        ++i;
        if (5 == i)
            //abort();//提示錯誤
            //break;//終止迴圈
            exit(0);//結束程式
    }

    system("pause");
}

程式片段(13):type.cpp
內容概要:typedef

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

#include <iostream>//CPP輸入輸入
using namespace std;//使用名稱空間

//01.給任意型別取別名的方式:typedef使用
//  規律:在宣告變數的基礎之上前置typedef關鍵字
//      為已經存在的型別另起一個別名(原名和別名都有進行使用)
//      只不過typedef具有簡化型別名稱的作用,而且某些地方必須
//      為型別定義別名,否則無法進行後續操作
typedef unsigned short int USI;
typedef unsigned long int ULI;

//02.C語言重要知識點概括:
//  補碼-->遞迴-->邏輯
//  陣列-->二維陣列地圖-->排序
//  指標-->外掛(函式指標)
//  字串-->結構體-->記憶體四區-->檔案
//03.CPP語言當中獲取型別的方式:
//  typeid(var).name();
//  根據變數名稱獲取變數的所屬型別;
//  並且將該資料型別以字串的形式列印出來
int main01(void)
{
    unsigned long int num = 10;
    ULI ulinum = 10;
    printf("%s \n", typeid(ulinum).name());//typedef(x).name();根據變數名稱獲取變數所屬的資料型別(字串表現形式)

    system("pause");
}

相關文章