20160215.CCPP体系详解(0025天)

程序片段(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.内存架构模型:
//  通过多级指针数组实现!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值