20160215.CCPP體系詳解(0025天)

尹成發表於2016-03-01

程式片段(01):01.Malloc.c
內容概要:Malloc擴充

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

//01.記憶體伸縮函式:
// void  *  realloc(void * block, unsigned int size);
//      用途:用於記憶體節省,動態根據所需記憶體尺寸進行記憶體開闢!
//      說明:返回值+引數
//          引數(block):原始記憶體塊兒的記憶體起始地址!
//          引數(size):經過記憶體位元組伸縮之後所佔用的總記憶體位元組尺寸!
//          返回值(void *):經過記憶體位元組伸縮之後返回的有效首地址(可能變化)!
//      特點:擴充之後的記憶體不會自動清零!
int main01(void)
{
    //realloc();-->重新分配:在同一個函式當中進行堆記憶體的(伸縮|擴充)非常簡單,指標變數所儲存的指標位置總是正確的!
    int * p = (int *)malloc(100);
    for (int i = 0; i < 25; ++i)
    {
        printf("%3d", p[i] = i);
    }
    p = (int *)realloc(p, 104);//擴充記憶體:讓記憶體位元組總數增加四個位元組,以多容納一個額外的陣列元素[記憶體位元組尺寸擴充!]
    printf("擴充成功! \n");
    for (int i = 0; i < 26; ++i)
    {
        printf("%3d", p[i] = i);
    }

    system("pause");
}

void add1(int * p, int num)
{
    p = (int *)realloc(p, 104);//記憶體首地址可能存在更改,可能不能實現跨函式修改資料!
    p[25] = num;//修改動作!
}

/*
    A-->P-->PP
    1->&A->&P
*/
int * add2(int * p, int num)
{//通過返回記憶體地址的方式,確保跨函式修改記憶體的正確性!
    p = (int *)realloc(p, 104);//動態擴充堆記憶體,有可能返回一個新的記憶體首地址,從而無法實現原始記憶體地址的資料修改!
    p[25] = num;
    return p;
}

//int------>int * p;
//int * p-->int ** pp;
void add3(int ** pp, int num)
{//通過傳遞變數的地址,實現跨函式修改記憶體
    *pp = (int *)realloc(*pp, 104);
    (*pp)[25] = num;//中括號("[]")的優先順序高於星號("*"),特別注意!
}                                                                                

int main02(void)
{
    int * p = (int *)malloc(100);
    for (int i = 0; i < 25; ++i)
    {
        printf("%3d", p[i] = i + 1);
    }
    printf("\n");
    //p = add(p, 100);//通過記憶體地址返回的方式,實現跨函式修改記憶體!
    add3(&p, 26);//通過傳遞變數的地址的方式,實現跨函式修改記憶體!
    printf("記憶體擴充成功! \n");
    for (int i = 0; i < 26; ++i)
    {
        printf("%3d", p[i]);
    }

    system("pause");
}

//02.跨函式修改記憶體:
//  返回新地址+傳遞變數地址

程式片段(02):01.二級指標.c
內容概要:鋸齒陣列

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

#define N 10

//01.動態記憶體開闢規律:
//  1.N級指標用於開闢(N-1)級指標的動態陣列
//  2.N級指標變數的名稱就是動態陣列的名稱
//  3.動態陣列的名稱和靜態陣列名稱的區別:
//      動態陣列名稱:變數指標
//      靜態陣列名稱:常量指標
//  注:陣列名稱的特點,動態陣列可以自我指定是變數指標還是常量指標!
//      0級指標用於代替變數本身!
//02.所有圖形列印都在於規律尋求:
//  行規律+規律+組合規律!
//03.鋸齒陣列:
//  1.關於核心N行進行對稱
//  2.總函式就是2*N-1
//  3.前五行:N-i控制+後五行:i - N +2控制
int main01(void)
{
    //int * p = (int *)malloc(N * sizeof(int));
    int **pp = (int **)malloc((2 * N - 1) * sizeof(int *));//縱向一級指標陣列!
    //pp[2 * N - 1];//(行數規律+對稱規律)
    for (int i = 0; i < N; ++i)
    {//列印上部分鋸齒
        pp[i] = (int *)malloc((N - i) * sizeof(int));//縱向指標一級指標陣列所對應的整型陣列開闢
        for (int j = 0; j < N - i; ++j)//i:0-1-2-3-4-->j<N-i:5-4-3-2-1;
        {
            printf("%3d", pp[i][j] = j + 1);
        }
        printf("\n");
    }
    for (int i = N; i < 2 * N - 1; ++i)//i=5:索引從5開始;i<2*N-1:最後一個索引
    {
        pp[i] = (int *)malloc((i - N + 2) * sizeof(int));//每個一級指標所對應的整數遞增!
        for (int j = 0; j < i - N + 2; ++j)
        {
            printf("%3d", pp[i][j] = j + 1);
        }
        printf("\n");
    }

    system("pause");
}

程式片段(03):01.刪除.c
內容概要:動態陣列刪除資料

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

void findFirstNum1(int * p, int length, int delNum)
{
    int flag = 0;//假定多數情況找不到
    for (int i = 0; i < length; ++i)
    {
        if (delNum == *(p + i))
        {
            flag = 1;//存在否定情況
            break;
        }
    }
    return flag;
}

int * findFirstNum2(int * p, int length, int delNum)
{
    int * pFlag = NULL;//假定多數情況找不到!
    for (int i = 0; i < length; ++i)
    {
        if (delNum == *(p + i))
        {
            return pFlag = p + i;//存在否定情況找得到!
        }
    }
    return NULL;
}

int findFirstNum3(int * p, int length, int delNum)
{
    int pos = -1;
    for (int i = 0; i < length; ++i)
    {
        if (delNum == *(p + i))
        {
            pos = i;
            break;
        }
    }
    return pos;
}

void deleteNum(int ** pp, int *length, int delNum)
{
    int pos = findFirstNum3(*pp, *length, delNum);
    if (-1 != pos)
    {
        for (int i = pos; i < *length - 1; ++i)//i<*length-1:空留最後一個位置用於做為刪除緩衝!
        {
            *((*pp) + i) = *((*pp) + i + 1);//移動覆蓋!
        }
        *pp = (int *)realloc(*pp, (*length-1));//壓縮記憶體
        --*length;
    }
}

//01.for迴圈具備迴圈條件的對稱性:
//  從左往中+從右往中:對稱判斷性!
int main01(void)
{
    int * p = (int *)malloc(100);
    int length = 25;
    for (int i = 0; i < length; ++i)
    {//間隔賦值方式!
        if (0 == i % 2)
        {
            *(p + i) = 4;
        }
        else
        {
            *(p + i) = 5;
        }
    }
    for (int i = 0; i < length; ++i)
    {
        printf("%d \n", *(p + i));
    }
    for (int pos = findFirstNum3(p, length, 4); -1 != pos; pos = findFirstNum3(p, length, 4))
    {//不斷的進行同一個整數的刪除操作
        deleteNum(&p, &length, 4);
    }
    printf("刪除之後! \n");
    for (int i = 0; i < length; ++i)
    {
        printf("%d \n", *(p + i));
    }
    printf("length = %d \n", length);

    system("pause");
}

程式片段(04):01.字串.c
內容概要:指標陣列動態分配

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

//01.跨級指標實現資料層&顯示層
//  查詢許可權的控制-->地址對映對!
int main01(void)
{
    //char *pArr[10] = { "1123", "1231" };
    int count;
    scanf("%d", &count);
    char **pp = (char **)malloc(count * sizeof(char *));
    for (int i = 0; i < count; ++i)
    {
        char str[1024] = { 0 };
        scanf("%s", str);//針對於字串的所有操作實質都是通過字元指標實現間接修改記憶體實體!
        *(pp + i) = (char *)malloc((strlen(str) + 1)*sizeof(char));//字串結尾整體識別符號'\0'
        strcpy(*(pp + i), str);//字串拷貝!
    }
    for (int i = 0; i < count; ++i)
    {
        printf("%s \n", *(pp + i));
    }

    system("pause");
}

int num;
//跨函式操控指標陣列!
void init(char *** ppp)
{
    scanf("%d", &num);
    *ppp = (int **)malloc(num * sizeof(int *));
    for (int i = 0; i < num; ++i)
    {
        char str[1024] = { 0 };
        scanf("%s", str);
        *((*ppp) + i) = (int *)malloc((strlen(str) + 1) * sizeof(char));
        strcpy(*((*ppp) + i), str);
    }
    for (int i = 0; i < num; ++i)
    {
        printf("%s \n", *((*ppp) + i));
    }
}

//指標陣列二分查詢
int binsearch(char **pp)
{
    printf("二分查詢法! \n");
    char searchStr[128] = { 0 };
    scanf("%s", searchStr);
    int minIndex = 0;
    int midIndex = 0;
    int maxIndex = num - 1;
    while (minIndex <= maxIndex)
    {
        midIndex = (minIndex + maxIndex) / 2;
        if (0 == strcmp(searchStr, *(pp + midIndex)))
        {
            printf("searchStr = %s找到,位於多少%p號地址! \n", searchStr, *(pp + midIndex));
            return midIndex;
        }
        else if (-1 == strcmp(searchStr, *(pp + midIndex)))
        {
            maxIndex = midIndex - 1;
        }
        else
        {
            minIndex = midIndex + 1;
        }
    }
    return -1;
}

//指標陣列排序
void sort(char **pp)
{
    for (int i = 0; i < num - 1; ++i)
    {
        for (int j = 0; j < num - 1 - i; ++j)
        {
            if (0 < strcmp(*(pp + j), *(pp + j + 1)))
            {//比較資料區+交換指標區
                char * pTmp = *(pp + i);
                *(pp + i) = *(pp + i + 1);
                *(pp + i + 1) = *(pp + i);
            }
        }
    }
    puts("排序之後! \n");
    for (int i = 0; i < num; ++i)
    {
        printf("%s \n", *(pp + i));
    }
}

//通過二級指標陣列間接從指標陣列當中進行資料查詢!
int binSearchAddr(char *** ppp)
{
    printf("二分查詢法! \n");
    char searchStr[128] = { 0 };
    scanf("%s", searchStr);
    int minIndex = 0;
    int midIndex = 0;
    int maxIndex = num - 1;
    while (minIndex <= maxIndex)
    {
        midIndex = minIndex + (maxIndex - minIndex) / 2;
        if (0 == strcmp(searchStr, *(*(ppp + midIndex))))
        {
            printf("searchStr = %s找到,位於%p號地址! \n", *(*(ppp + midIndex)));
            return midIndex;
        }
        else if (-1 == strcmp(searchStr, *(*(ppp + midIndex))))
        {
            maxIndex = midIndex - 1;
        }
        else
        {
            minIndex = midIndex + 1;
        }
    }
    return -1;
}

//不操作原有指標陣列的情況之下操作二級指標陣列實現排序!
//  訣竅:比較記憶體實體,交換指標變數(資料保護措施!)
//注:只要有需求不改變原有資料的情況下實現排序,就需要高階指標:
//  通過對地址對映進行排序,從而實現資料表現形式的排序特點!
void sortByAddr(char ** pp)
{
    char *** ppp = (char ***)malloc(num * sizeof(char **));
    for (int i = 0; i < num; ++i)
    {
        *(ppp + i) = pp + i;
    }
    for (int i = 0; i < num - 1; ++i)
    {
        for (int j = 0; j < num - 1 - num; ++j)
        {
            if (0 < strcmp(*(*(ppp + j)), *(*(ppp + j + 1))))
            {
                char ** ppTmp = *(ppp + j);
                *(ppp + j) = *(ppp + j + 1);
                *(ppp + j + 1) = ppTmp;
            }
        }
    }
    printf("二級指標陣列顯示層! \n");
    for (int i = 0; i < num; ++i)
    {//對二級指標陣列進行排序之後-->方可對二級指標數進行查詢操作!
        printf("%s \n", *(*(ppp + i)));
    }
    printf("一級指標陣列資料層! \n");
    for (int i = 0; i < num; ++i)
    {
        printf("%s \n", *(pp + i));
    }
    binSearchAddr(ppp);
}

int main02(void)
{
    //char * p[10] = { "1123", "1231" };
    char **pp;
    init(&pp);
    //sort(pp);//指標陣列排序
    //binsearch(pp);//指標陣列二分查詢
    sortByAddr(pp);//構建二級指標陣列,實現一級指標資料的許可權查詢

    system("pause");
}

程式片段(05):01.五級指標.c
內容概要:五級指標

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

//堆記憶體動態陣列模擬棧記憶體靜態普通變數陣列
int main01(void)
{
    int * p = (int *)malloc(10 * sizeof(int));
    printf("%p \n", p);//列印的是變數所儲存的二進位制資料
    for (int i = 0; i < 10; ++i)
    {
        printf("%2d \n", *(p + i) = i);
    }
    free(p);

    system("pause");
}

//堆記憶體動態陣列模擬棧記憶體靜態指標變數陣列
int main02(void)
{
    int ** pp = (int **)malloc(10 * sizeof(int *));
    printf("%p \n", pp);
    for (int i = 0; i < 10; ++i)
    {
        *(pp + i) = (int *)malloc(10 * sizeof(int));
        printf("%p\n", *(pp + i), " ");
        for (int j = 0; j < 10; ++j)
        {
            printf("%4d", *(*(pp + i) + j) = i * 10 + j);
        }
        printf("\n");
    }

    system("pause");
}

//堆記憶體動態陣列模擬棧記憶體靜態二級指標陣列
int main03(void)
{
    int *** ppp = (int ***)malloc(10 * sizeof(int **));
    printf("%p \n", ppp);
    for (int z = 0; z < 10; ++z)
    {
        *(ppp + z) = (int **)malloc(10 * sizeof(int *));
        printf("%p \n", *(ppp + z));
        for (int x = 0; x < 10; ++x)
        {
            *(*(ppp + z) + x) = (int *)malloc(10 * sizeof(int));
            printf("%p \n", *(*(ppp + z)));
            for (int y = 0; y < 10; ++y)
            {
                printf("%4d \n", *(*(*(ppp + z) + x) + y) = z * 100 + x * 10 + y);
            }
            printf("\n");
        }
        printf("\n\n");
    }

    system("pause");
}

//01.記憶體架構模型:
//  通過多級指標陣列實現!

相關文章