20160205.CCPP體系詳解(0015天)

尹成發表於2016-02-16

程式片段(01):01.楊輝三角.c
內容概要:楊輝三角

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

#define N 10

//01.楊輝三角:
//  1.圖形轉換:將標準楊輝三角採用標準陣列進行模擬
//  2.確定標準陣列的圖形描述關係:
//      (1).陣列當中第一列的所有元素以及正對角線的所有元素都為1
//      (2).陣列當中的其它元素等於上一行左一列
//  3.陣列模擬楊輝三角的訣竅!
//      將整個楊輝三角向左傾斜成為標準的二維陣列
int main01(void)
{
    int intArrArr[N][N] = { 0 };
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j <= i; ++j)
        {
            if (0 == j || i == j)
                intArrArr[i][j] = 1;
            else//核心程式碼
                intArrArr[i][j] = intArrArr[i - 1][j - 1] + intArrArr[i - 1][j];
        }
    }
    //模擬楊輝三角的標準陣列列印方式
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j <= i; ++j)
        {
            printf("%4d", intArrArr[i][j]);
        }
        printf("\n");
    }
    //楊輝三角列印方式
    for (int i = 0; i < N; ++i)
    {//19=10*4/2-1-i*2
        printf("%*c", 19 - i*2, '\0');//printf();當中的*表示預訂寬度,scanf();當中的*表示忽略寬度
        for (int j = 0; j <= i; ++j)
        {
            printf("%4d", intArrArr[i][j]);
        }
        printf("\n");
    }

    system("pause");
}

程式片段(02):01.Array.c+02.二維陣列實戰.c+03.二維陣列轉置.c
內容概要:02.二維陣列本質

///01.Array.c
#include <stdio.h>
#include <stdlib.h>

//01.二維陣列本質:
//  1.二維陣列的陣列名本質:
//      就是整個二維陣列的首個陣列元素首地址
//  2.二維陣列當中的陣列元素和行元素區分:
//      就二維陣列整體而言:
//          每個陣列元素都只是一個陣列元素
//          每個行元素當中包含有多個陣列元素
//      就一維陣列整體而言:
//          每個陣列元素都只是一個行元素
//  注意事項:
//      1.所有陣列的儲存方式都是採取執行緒儲存:
//          儲存特點:連續+型別相同
//      2.所有線性儲存方式的資料結構都可以採取
//          線性方式進行順序規律的初始化方式初始
//      3.二維陣列也是採取的靜態初始初始化方式
//          也就是長度必須採用常量進行標識
//      4.陣列的靜態初始化特點:
//          (1).一個大括號代表一個維度
//          (2).只要存在前置元素初始化,那麼後面的所有陣列元素
//              都會預設進行初始化為0的操作
//                  (前置:必須從首個"陣列元素"開始,否則不會出現連續預設初始化為0的現象)
int main01(void)
{
    int intArrArr[3][4] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            //%p<==>%#x(將數值以16進位制以及攜帶進位制標識的方式進行列印)
            //&intArrArr[i][j]與intArr[i]+j等價的原因:intArrArr[i]表示的是二維陣列當中每個一維陣列的首個元素的地址(也就是每個一維陣列的地址)
            printf("%2d,%p,%p", intArrArr[i][j], &intArrArr[i][j], intArrArr[i] + j);
        }
        printf("\n");
    }

    //對二維陣列的不同看待方式會有不同的效果!
    //  將二維陣列看做為一維陣列的處理方式,
    //      那麼以一維陣列的陣列元素獲取方式,就是在獲取每個陣列元素的首地址
    printf("%p,%p,%p \n", intArrArr[0], intArrArr[1], intArrArr[2]);

    system("pause");
}
///02.二維陣列實戰.c
#include <stdio.h>
#include <stdlib.h>

#define N 10
int intArrArr[N][N];
//01.不引入任何變數實現二維矩陣陣列的標準資料規律化賦值方式:
//      表示式:intArrArr[i][j]=i*N+1+j;//從1開始進行的規律化賦值
int main02(void)
{
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < N; ++j)
        {
            printf("%3d", intArrArr[i][j] = i * N + j + 1);//舉行陣列賦值的規律表示式(不引入任何其他變數)
        }
        printf("\n");
    }

    system("pause");
}

//02.二維陣列當中的特殊資料統計方式:
//  sumA:表示統計所有
//  sumB:統計每行
//  sumC:統計每列
// sumD:統計正斜線
//  sumE:統計反斜線
int main03(void)
{
    int sumA = 0;
    int sumD = 0;
    int sumE = 0;
    for (int i = 0; i < N; ++i)
    {//表示行
        int sumB = 0;
        for (int j = 0; j < N; ++j)
        {//表示列
            printf("%4d", intArrArr[i][j] = i*N + 1 + j);
            sumA += intArrArr[i][j];
            sumB += intArrArr[i][j];
            //if (i == j)
            //  sumD += intArrArr[i][j];
            if (i + j == N - 1)
                sumE += intArrArr[i][j];
        }
        printf("sumB = %d \n", sumB);
        sumD += intArrArr[i][i];
        printf("\n");
    }
    printf("\n\n");

    for (int j = 0; j < N; ++j)
    {//表示列
        int sumC = 0;
        for (int i = 0; i < N; ++i)
        {//表示行
            sumC += intArrArr[i][j];
        }
        printf("sumC = %d \n", sumC);
    }

    system("pause");
}
///03.二維陣列轉置.c
#include <stdio.h>
#include <stdlib.h>

//01.對陣列的各種轉置操作:
//  1.轉置:正轉置,翻轉置,翻頁轉置
//      相當於對二維平面的任意操作特點
//  2.轉置規律分析:
//      就是直接將帶轉置的圖形與
//      轉置之後的結果進行對比分析
//      快速得出二維陣列的轉置規律
//02.翻頁轉置效果總結:
//  1.待轉置陣列與轉置後陣列特點:
//      待轉置陣列:intArrArrA[N1][N2];
//      轉置後陣列:intArrArrB[N2][N1];
//  2.轉置效果分類:轉置線+翻頁點
//      反斜線轉置:intArrArrA[j][i]
//          上翻頁:intArrArrB[i][j]
//          下翻頁:intArrArrB[N2-1-i][N1-1-j]
//      正斜線轉置:intArrArrA[N1-1-j][N2-1-j]
//          上翻頁:intArrArrB[i][j]
//          下翻頁:intArrArrB[N2-1-i][N1-1-j]
//  規律:先確定轉置線,再確定翻頁點
int main04(void)
{                                                              
    /*
        //待轉置陣列
        1   2   3   0
        4   5   0   13
        6   7   8   9
        //正常列印待轉置陣列
    */
    int intArrArrA[3][4] = { { 1, 2, 3 }, { 4, 5, 0, 13 }, { 6, 7, 8, 9 } };
    int intArrArrB[4][3] = { 0 };
    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {//待轉置陣列
            printf("%3d", intArrArrA[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    //1  4  6
    //2  5  7//反斜線轉置
    //3  0  8
    //0 13  9
    //特點:反斜線+以左下角下翻頁:
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {//轉置後陣列:正確列印方式=intArrArrB[j][i];
            printf("%3d", intArrArrB[i][j] = intArrArrA[j][i]);//以左下角為翻頁點,反斜線為轉置線,作為翻頁轉置效果
        }
        printf("\n");
    }
    printf("intArrArrB[i][j]<--intArrArrA[j][i] \n\n");
    //特點:反斜線+以左下角上翻頁
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 3; ++j)                                                                                                   
        {//轉置後陣列:逆向接收方式=intArrArrB[j][i];
            printf("%3d", intArrArrB[3 - i][2 - j] = intArrArrA[j][i]);//以右上角為翻頁點,反斜線為轉置線,作為翻頁轉置效果
        }
        printf("\n");
    }
    printf("intArrArrB[3-i][2-j]=intArrArrA[j][i] \n\n");
    //總結:翻頁轉置的效果相似,都是以斜對角線為基準進行轉置,一個正向翻頁,一個逆向翻頁

    //9 13  0
    //8  0  3//正斜線轉置
    //7  5  2
    //6  4  1
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            printf("%3d", intArrArrB[i][j] = intArrArrA[2 - j][3 - i]);
        }                                             
        printf("\n");
    }
    printf("intArrArrB[i][j]=intArrArrB[2-j][3-i] \n\n");
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            printf("%3d", intArrArrB[3 - i][2 - j] = intArrArrA[2 - j][3 - i]);
        }
        printf("\n");
    }
    printf("intArrArrB[3-i][2-j]=intArrArrB[2-j][3-i] \n\n");

    system("pause");
}

#define row 2
#define column 3
//02.翻頁轉置規律大總結:
//  先確定轉置線,再確定翻頁點
int main05(void)
{
    int intArrArrA[row][column] = { 1, 2, 3, 4, 5, 6 };
    printf("原樣輸出: \n");
    for (int i = 0; i < row; ++i)
    {
        for (int j = 0; j < column; ++j)
        {
            printf("%2d", intArrArrA[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    int intArrArrB[column][row] = { 0 };
    printf("以反斜線為轉置線,以左下角為翻頁點,進行翻頁轉置! \n");
    for (int i = 0; i < column; ++i)
    {
        for (int j = 0; j < row; ++j)
        {
            printf("%2d", intArrArrB[i][j] = intArrArrA[j][i]);
        }
        printf("\n");
    }
    printf("\n");
    printf("以反斜線作為轉置線,以右上角作為翻頁點,進行翻頁轉置! \n");
    for (int i = 0; i < column; ++i)
    {
        for (int j = 0; j < row; ++j)
        {
            printf("%2d", intArrArrB[column - 1 - i][row - 1 - j] = intArrArrA[j][i]);
        }
        printf("\n");
    }
    printf("\n");

    printf("以正斜線作為轉置線,以右下角作為翻頁點,進行翻頁轉置! \n");
    for (int i = 0; i < column; ++i)
    {
        for (int j = 0; j < row; ++j)
        {
            printf("%2d", intArrArrB[i][j] = intArrArrA[row - 1 - j][column - 1 - i]);
        }
        printf("\n");
    }
    printf("\n");
    printf("以正斜線作為轉置線,以左上角作為翻頁點,進行翻頁轉置! \n");
    for (int i = 0; i < column; ++i)
    {
        for (int j = 0; j < row; ++j)
        {
            printf("%2d", intArrArrB[column - 1 - i][row - 1 - j] = intArrArrA[row - 1 - j][column - 1 - i]);
        }
        printf("\n");
    }
    printf("\n");

    system("pause");
}

程式片段(03):03.Time.c
內容概要:高維陣列

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

//01.二維陣列的初始化方式:
//  奧數技巧:線性初始化方式
//  注:凡是線性儲存的資料結構都存在著線性的初始化方式
//02.線性初始化的規律總結:
//  1.採用一個迴圈結構控制迴圈次數(實質就是陣列當中所含元素的個數)
//  2.操控陣列的時候規律:
//      intArrArr[變化慢的][變化快的] = i + 1;
//          變化慢的:求模最低維數
//          變化快的:取餘最低維數
//          i+1:使得線性初始化值為1,2,3...(能夠避免不必要的修改迴圈控制變數的值)
//  注:%p<==>%#X的列印實質等價
int main01(void)
{
    //A     0       1       2       3
    //0   00      01      02    03
    //1   10      11    12    13
    //2   20    21    22    23
    //3   30    31    32    33
    int intArrArr[3][4] = { 0 };
    for (int i = 0; i < 12; ++i)
    {
        intArrArr[12 / 4][12 % 4] = i + 1;//二維陣列的線性初始化方式
    }
    printf("%p \n", intArrArr);
    //printf("%#X \n", intArrArr);

    system("pause");
}

//03.三維陣列的線性初始化總結:
//      1.三維陣列組成分析:
//          本質:三維陣列的具體模型-->立體結構(六個方向:上,下,左,右,前,後)
//          特點:intArrArr[z][x][y];
//              z:代表立體結構縱座標-->這是由二維到三維的轉變維度
//              x:代表平面結構x座標
//              y:代表平面結構y座標
//      2.三維陣列的線性初始化方式詳解:
//          intArrArrArr[z][x][y];
//          for (int i = 0; i < z*x*y; ++i)
//              intArrArrArr[i / (x*y)][i % (x*y) / y][i % (x*y) % y] =i + 1;
//          i / (x*y):代表當前索引所指向的立體結構(第幾層)
//          i % (x*y) / y:代表當前索引所指向的立體結構的(不完全面)的第幾行
//          i % (x*y) % y:代表當前索引所指向的立體結構的(不完全面)的第幾列
//  注:
//      1.凡是資料結構為線性的儲存結構,那麼前置元素只要初始化為0,後置儲存便會
//          預設初始化為0(尤其是陣列的初始化特點)
//      2.陣列通性特點:
//          元素型別一致,連續記憶體儲存[陣列都是以線性記憶體結果進行的資料儲存,因此才可以進行線性初始化賦值操作]
//      3.內層優化技巧:
//          能夠減少不必要的運算過程就應當儘量減少
//              比如:三維陣列的初始化技巧,不必要使用三層迴圈結構,減少不不要的兩層迴圈結構,採用一層結構進行搞定
int main02(void)
{
    int intArrArrArr[3][4][5] = { 0 };
    intArrArrArr[0][0][0] = 0;
    intArrArrArr[1][0][0] = 20;//intArrArrArr[1][2][0]=30;=>intArrArrArr[1][2][3]=33;
    intArrArrArr[2][0][0] = 40;
    printf("%p \n", intArrArrArr);//三維陣列的首地址
    for (int i = 0; i < 60; ++i)
    {
        //intArrArrArr[60 / 20][60 % 20 / 5][60 % 20 % 5] = i;//效能優化操作-->遊戲開發當中,少一層迴圈結構,多提升一些效率
        intArrArrArr[i / (4 * 5)][i % (4 * 5) / 5][i % (4 * 5) % 5] = i;
        //0,1,2-->0,1,2,3-->0,1,2,3,4
    }
    //intArrArrArr[i][j][k]-->程式效能優化:能夠減少的迴圈層數就一定要進行相應的減少
    //intArrArrArr[(i*j*k)/(j*k)][(i*j*k)%(j*k)/k][(i*j*k)%(j*k)%k]

    system("pause");
}

//04.從0維陣列到N維陣列的推導過程:
//  0維陣列:就是一個變數
//      實質:點
//  1維陣列:就是一個一維陣列
//      實質:線
//  2維陣列:就是一個二維陣列
//      實質:面
//  3維陣列:就是一個三維陣列
//      實質:立體
//  4維陣列:就是一個四維陣列
//      實質:立體+時間
//  5維陣列:就是一個五維陣列
//      實質:立體+時間+質量
//  6維陣列:就是一個六維陣列
//      實質:立體+時間+質量+能量
//  n維陣列:就是一個N維陣列
//      實質:(n-1)維基礎條件+第n維的條件
//05.陣列線性初始化特點:
//  從第一層第一面第一個點開始進行逐個點的初始化
//      從下層不斷的往上層
//      從一個面不斷的往另外一個面
//      從一個點不斷的往一個點
int main03(void)
{
    int intArrArrArr[2][3][4] = { 0 };
    int num = 0;
    for (int z = 0; z < 2; ++z)//層結構(包含面)
    {//遍歷2個平面
        for (int x = 0; x < 3; ++x)//面結構(包含行)
        {//遍歷3個行數
            for (int y = 0; y < 4; ++y)//線結構(包含點)
            {//遍歷4個列數
                printf("%3d, %p", intArrArrArr[z][x][y] = ++num, &intArrArrArr[z][x][y]);
            }
            printf("\n");
        }
        printf("\n\n");
    }

    system("pause");
}

程式片段(04):01.Fun.c
內容概要:陣列與函式

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

//01.陣列作為函式引數進行傳遞的特殊性質:
//  陣列作為函式的引數傳遞,會自動退化為指標,目的就是為了傳遞地址[陣列-->指標-->地址]
//  注:
//      1.目的是為了節省資源,避免不必要的記憶體拷貝動作,提升程式效能(直接採用指標操作原始資料)
//      2.陣列名作為實參,就是指向首個陣列元素的指標,陣列名沒有作為引數,就是表示整個陣列的型別
void testArrName(int intArr[10])//地址:陣列是例外,陣列傳遞的是指標,也就是地址,陣列沒有副本機制
{
    printf("%p \n", intArr);
    intArr[3] = 1000;
    printf("sizeof(intArr) = %d \n", sizeof(intArr));//這裡的實質就是求取地址這個整數所佔用的記憶體位元組數
    int intArrTest[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    printf("sizeof(intArrTest) = %d \n", sizeof(intArrTest));//陣列沒有用作函式實參進行傳遞,就是資料實際大小
}

int main01(void)
{
    int intArr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    printf("%p \n", intArr);
    testArrName(intArr);
    for (int i = 0; i < 10; ++i)
    {
        printf("%d \n", intArr[i]);
    }

    system("pause");
}

程式片段(05):01.列舉陣列.c
內容概要:陣列與列舉常量

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

enum person{ 吳偉, lzq, zb, yc, 李波 };//0,1,2,3...預設匹配的整數形式
double yanZhiBiao[5] = { 97.9, 93.9, 88.9, 60.9, 98.9 };

//01.列舉陣列的特點:列舉+陣列=結合使用(類似於查表法的使用)
//  讓列舉資料具備一定的比較特性
//  查表法:已知一個索引,在已經存在的對應表當中進行資料查詢
int main01(void)
{
    //讓列舉資料具備一定的比較特性
    for (enum person people = 吳偉; people <= 李波; ++people)
    {
        printf("%lf \n", yanZhiBiao[people]);
    }

    system("pause");
}

程式片段(06):01.命名.c
內容概要:起名工具

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

//01.知識要點:
//  1.隨機數生成方式
//  2.查表法的應用
//      先定義表體內容,
//      再定義查詢內容
int main01(void)
{
    //time_t te;//定義時間型別
    //unsigned int seed = (unsigned int)time(&te);//獲取隨機數種子
    //srand(seed);//種植隨機數種子
    srand((unsigned int)time(NULL));//種植隨機數種子
    //int passLength = rand() % 10 + 6;//6~15:密碼長度
    //2個字兒,3個字兒的密碼生成,定住姓氏,隨機名字
    char passChr[10] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
    //for (int i = 0; i < passLength; ++i)
    //{
    //  int num = rand() % 10;//隨機獲取組成密碼的單個字元
    //  printf("%c", passChr[num]);
    //}

    for (int i = 0; i < rand() % 10 + 6; ++i)
    {
        printf("%c", passChr[rand() % 10]);
    }
    printf("\n");

    system("pause");
}

//02.查表法很重要!
int main02(void)
{
    setlocale(LC_ALL, "zh-CN");
    wchar_t wcharS[8] = { L'龍', L'虎', L'大', L'偉', L'天', L'桂', L'三', L'財' };
    //putwchar(wcharS[0]);
    putwchar(L'吳');
    srand((unsigned int)time(NULL));
    for (int i = 0; i < rand() % 2 + 1; ++i)
    {
        putwchar(wcharS[rand() % 8]);
    }

    system("pause");
}

程式片段(07):01.洗牌.c
內容概要:07.洗牌

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

//01.洗牌演算法透析:
//  原理:讓任何一張牌有機會與其後面的任意一張牌進行交換
//      int randNum = 0;
//      for (int i = 0; i < 53; ++i)//只需要讓倒數第二張牌和倒數第一張牌有交換機率就行了,倒數第一張牌沒有後續的交換概率
//      {//由於最大索引為53-->然而前面已經保證了從後面一張牌開始-->因此需要1+X能夠等於53-->rand()%(53-i)-->極限推理法
//          randNum = i + 1 + rand() % (53 - i);//(i+1)保證絕對不會發生本體交換特點a;rand()%(53-i)保證隨機數合理,(53-i)防止出界
//      }
int main01(void)
{
    int intArr[54] = { 0 };
    printf("洗牌之前:\n");
    for (int i = 0; i < 54; ++i)
    {
        printf("%3d", intArr[i] = i + 1);
    }
    printf("\n\n");

    srand((unsigned int)(time(NULL)));//種植隨機數種子
    for (int i = 0; i < 53; ++i)//少一次:為了避免最後一次沒有交換物件
    {
        int num = i + 1 +  rand() % (53 - i);
        intArr[i] = intArr[i] ^ intArr[num];
        intArr[num] = intArr[i] ^ intArr[num];
        intArr[i] = intArr[i] ^ intArr[num];
    }

    printf("洗牌之後:\n");
    for (int i = 0; i < 54; ++i)
    {
        printf("%3d",intArr[i]);
    }

    system("pause");
}

相關文章