小说网 找小说 无限小说 烟雨红尘 幻想小说 酷文学 深夜书屋

20160207.CCPP体系详解(0017天)

程序片段:01.Point.c+02.进程.c+03.内存的栈和堆.c
内容概要:内存32位和64位的区别

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

//01.指针变量所占用的内存尺寸由编译器进行直接决定
//      指针变量所占用的内存尺寸同时直接或间接与CPU-->操作系统-->编译器平台有关
//          综合决定:CPU-->操作系统-->编译器平台
//          直接决定:编译器平台
//02.指针变量当中的指针就是内存寻址范围当中的地址(注意类型差别)
//  32位操作系统的CPU寻址能力
//      32位编译器:0x00000000~0xFFFFFFFF
//          2^32=2^2*2^10*2^10*2^10=4*1024*1024*1024=4G
//  64位操作系统的CPU寻址能力
//      64位编译器:0x0000000000000000~0xFFFFFFFFFFFFFFFFF
//          所能寻址的范围很大
//03.CPU的不同位数所导致的能力差异:
//  1.寻址能力不同:
//      寻址范围非常的大
//  2.运算能力不同:
//      32位CPU只能做32位运算;
//      64位CPU既能做32位运算,也能做64位运算
int main01(void)
{
    int num = 1;
    int * pNum = &num; 
    printf("%llu \n", sizeof(pNum));

    system("pause");
}

//04.寄存器相关的特点分析:
//  1.所有的运算操作都需要借助CPU的寄存器区域进行完成
//  2.任何一个表达式都是位于CPU的寄存器区域(eax|rax)
//      但是C语言不能直接对CPU的寄存器进行写入操作,除非内嵌汇编
//      注:包括对任何一个变量名的取地址操作(&varName)
//05.计算机在CPU的寄存器区域生成常量的过程:
//      CPU-->寄存器-->代码区-->符号表-->读取常量-->寄存器生成常量
int main02(void)
{
    int num = 1;
    int data = 0;
    data = num;
    //&(num+1);
    data = num + 1;
    data = num + 2;

    system("pause");
}
///02.进程.c
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

//01.单个进程处于不同编译器平台之下所支持的单进程内存尺寸不同:
//  32位编译器平台情况之下,所支持的单进程最大内存尺寸为2GB
//  64位编译器平台情况之下,所指吃的单进程最大内存尺寸为1024GB
//  注:
//      1.区分大小写B的区别
//      2.该单进程内存尺寸指整个进程所占用的内存(包含:代码区+全局区+栈内存+堆内存)
//      3.单个进程所占用的内存尺寸是由编译器平台的位数所直接决定的(间接因素:CPU->操作系统->编译器)
//02.内存分配,内存释放,内存回收四个词语的意思:
//  内存分配:操作系统为进程分配指定内存区域的访问权限(写入权限和读取权限)
//  内存释放:操作系统从进程回收指定内存区域的访问权限
//      只是收回权限,不会清空数据
//  内存回收:清空内存的实际数据
//      不仅收回权限,还会清空数据
//03.关于软访问和硬访问的区别:
//  软访问:所能访问的最小内存单位是二进制位(Bit)(补码)
//      但是通常都是采取字节作为最小单位操作内存的
//      除非是位运算就会操作到内存的最小单位
//  硬访问:所能访问的最小硬盘单位是字节(Byte)
int main03(void)
{
    while (1)
    {
        malloc(1024*1024*100);//不断的分配内存空间
        Sleep(100);
    }

    system("pause");
}
///03.内存的栈和堆.c
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <process.h>

//01.最常用栈内存和堆内存耗费方式:
//  栈耗费:auto int num
//  对耗费:malloc(1024)
//02.栈内存和堆内存的基本特点:
//  数据结构的栈和堆:
//      栈:先进后出的一种数据结构
//      堆:一种二叉树形式的存储结构
//  内存访问的栈内存和堆内存:
//      栈内存:自动释放,自动回收
//      堆内存:手动释放,手动回收
//  注:栈内存由编译器进行维护,编译器控制自动释放和自动回收的时机,默认栈内存所占用的尺寸为1M,可以手动拓展编译器
//      所操控的栈内存尺寸大小,通过项目配置修改栈内存所操纵的栈内存尺寸大小[配置属性-->链接器-->系统-->堆栈保留大小]
//03.区分虚拟内存和物理内存:
//  虚拟内存:硬盘内存
//  物理内存:真实内存
void stack(int numA)//int numA:作为形式参数,占用栈内存
{
    int numB = 10;//局部变量,占用栈内存
    printf("%p, %p \n", &numA, &numB);
    numA = 1;
    numB = 2;
    getchar();//某些情况之下如果不能进行断点调试,需要添加上这句无用的代码,以便插上断点进行断点调试
}

//04.关于编译器的自动优化特点解释:
//  1.一个函数在调用完成之后,如果调用了其它函数,那么当前函数会被立即释放
//  2.然而编译器检测到两次调用的是相同函数,只不过中间插入了一个无关紧要的函数,
//      那么此时的编译器不会对两次重复调用的相同函数进行不同的栈内存开辟
//05.静态数组分配的代码分析:
//  int intArr[1024*1024];
//      1.该数组占用栈内存字节数为4M
//      2.该数组属于静态数组,需要在代码一旦加入进内存之后就决定该数组的内存尺寸
//      3.该数组分配方式为静态分配,因此必须使用常量指明数组元素个数
int main04(void)
{
    //stack(1);
    //printf("\n\n\n");
    //stack(1);
    //printf("\n\n\n");
    //int intArr[1024 * 1024];
    system("pause");
}

//06.线程任务函数的标准格式
void run(void * p)
{
    while (1)
    {
        int num[1024 * 1024];//自动释放回收栈内存
    }

    while (1)
    {
        malloc(1024 * 1024 * 10);//不断的进行堆内存的分配而没有进行释放,很容易造成内存溢出情况
        Sleep(1000);//堆内存膨胀-->导致整个进程的内存溢出,不是栈内存溢出
    }
}

//07.32位编译器平台之下,由于编译器所编译的单个进程程序所支持的最大内存尺度为2GB(同时包含内存四区)大小
//  全局区+代码区+栈内存+堆内存=2GB,因此堆内存所占用的尺寸极限必定小于2GB
//08.关于多线程情况之下的单个进程的内存使用情况:
//  1.多条线程共享同一个进程的堆内存
//  2.各条线程独自占用一定的进程的栈内存
//09.关于启动线程函数处理线程任务代码的特点分析:
//  代码:_beginthread(taskFun, 0, NULL);
//  参数说明:
//          taskFun:线程待处理的任务函数
//                     0:以跟主线程相同栈内存尺寸分配线程任务栈内存-->通常所说的堆栈保留大小其实就是主线程的堆栈保留大小
//              NULL:传递给任务处理函数的实际参数
int main05(void)
{
    //void * p = malloc(1024 * 1024);//分配1M
    for (int i = 0; i < 8; ++i)
    {
        _beginthread(run, 0, NULL);//多线程,每一个线程都有各自独立的栈内存
    }

    system("pause");
}

程序片段(02):01.Heap.c
内容概要:Heap

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

void taskFun(void * p)
{
    while (1)
    {
        malloc(1024 * 1024 * 10);
        Sleep(100);
    }
}

int main01(void)
{
    //taskFun(NULL);    

    for (int i = 0; i < 3; ++i)
    {
        _beginthread(taskFun, 0, NULL);
    }

    system("pause");
}

程序片段(03):stack.h+stack.c+main.c
内容概要:Stack

///stack.h
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define EN 100
struct stack//单个结构体变量可以用于整合多个不同类型的变量
{
    int data[EN];//栈内存空间
    int top;//栈顶标识
};

typedef struct stack Stack;//Stack别名
void initStack(Stack * pStack);//初始化栈结构
int isEmpty(Stack * pStack);//判断栈结构是否为空
int isFull(Stack * pStack);//判断栈结构是否填满
void pushStack(Stack * pStack, int value);//栈结构压入数据
int popStack(Stack * pStack);//栈结构弹出数据
int getTop(Stack * pStack);//获取栈顶数据
void showStack(Stack * pStack);//栈结构显示
///stack.c
#include "stack.h"

void initStack(Stack * pStack)
{
    memset(pStack->data, 0, sizeof(int)*EN);//数据清零,模拟回收数据
    pStack->top = -1;//表示栈顶索引只要在0以上就表示栈结构当中存储有数据
}

int isEmpty(Stack * pStack)
{
    if (-1 == pStack->top)
    {
        return 1;
    }
    return 0;
}

int isFull(Stack * pStack)
{
    if (EN - 1 == pStack->top)
    {
        return 1;
    }
    return 0;
}

void pushStack(Stack * pStack, int value)
{
    if (1 == isFull(pStack))
    {
        return;
    }
    pStack->data[++pStack->top] = value;
}

int popStack(Stack * pStack)
{
    if (1 == isEmpty(pStack))
    {
        return;
    }
    return pStack->data[pStack->top--];
}

int getTop(Stack * pStack)
{
    if (1 == isFull(pStack))
    {
        return -1;
    }

    return popStack(pStack);
}

void showStack(Stack * pStack)
{
    if (1 == isEmpty(pStack))
    {
        return;
    }
    printf("栈结构的数据是: \n");
    for (int i = 0; i <= pStack->top; ++i)
    {
        printf("%4d \n", pStack->data[i]);
    }
    printf("\n");
}
///main.c
#define _CRT_SECURE_NO_WARNINGS
#include "stack.h"

//01.结构体类型与结构体变量:
//  1.结构体类型:用于整合多个不同类型
//  2.结构体变量:用于整合多个不同类型的变量
//  3.结构体变量的成员访问方式:点访问符+指针访问符
//      注:点号(".")操作符的优先级大于星号("*")操作符的优先级
int main01(void)
{
    struct MyStack//结构体类型用于整合多个不同类型
    {
        int data[10];
        int top;
    };
    //结构体变量意义:整合多个不同类型的变量
    struct MyStack my1 = { { 1, 2, 3 }, 1 };//结构体变量的静态初始化
    printf("%d \n", my1.top);//访问结构体变量的成员变量
    printf("%d \n", (&my1)->top);
    printf("%d \n", my1.top);
    printf("%d \n", (*(&my1)).top);

    struct MyStack * my2 = &my1;
    //printf("%d \n", *my2.top);//星号("*")的优先级低于点号(".")
    printf("%d \n", (*my2).top);

    for (int i = 0; i < 10; ++i)
    {
        printf("%d \n", my1.data[i]);//可以用点号(".")操作符进行访问
    }

    system("pause");
}

int main02(void)
{
    //int intArr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    Stack myStack;
    initStack(&myStack);
    for (int i = 0; i < 10; ++i)
    {
        pushStack(&myStack, i);
    }
    while (!isEmpty(&myStack))
    {
        printf("%3d", getTop(&myStack));
    }

    system("pause");
}

int main03(void)
{
    //int intArr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    Stack myStack;
    initStack(&myStack);
    for (int i = 0; i < 10; ++i)
    {
        pushStack(&myStack, i);//压栈一个
        printf("%3d", getTop(&myStack));//弹栈一个
    }

    system("pause");
}

//02.如何求取一个整数的二进制形式?
//  10      %2      5       0
//    5     %2      2       1
//    2     %2      1       0
//    1     %2      0       1
//    0     %2      0       0-->直到被除数为0,末尾添加一个0(被除数:0->取模数:0)
void    intHexToBin(int intHexNum)
{
    if (0 == intHexNum)//表示最终的被除数为0的情况
    {
        putchar('0');//表明确实已经除到了最后一个数值-->意思:直到被除数为0,末尾添加了一个0
    }
    else
    {
        intHexToBin(intHexNum / 2);
        putchar('0' + intHexNum % 2);//十进制的整数类型转化为字符型的整数
    }
}

int main04(void)
{
    int intHexNum = 0;
    scanf("%d", &intHexNum);
    intHexToBin(intHexNum);

    system("pause");
}

//压入一个,弹出一个
int main05(void)
{
    int intNum;
    scanf("%d", &intNum);
    Stack myStack;
    initStack(&myStack);
    while (intNum)
    {
        pushStack(&myStack, intNum % 2);
        putchar('0' + getTop(&myStack));
        intNum /= 2;
    }
    putchar('0');//当被除数变为0的时候,也需要在末尾进行补零操作

    system("pause");
}

//压入全部,一次性逆序弹出
int main06(void)
{
    int num;
    scanf("%d", &num);
    Stack myStack;
    initStack(&myStack);
    while (num)
    {
        pushStack(&myStack, num % 2);
        num /= 2;
    }
    pushStack(&myStack, 0);//当被除数为0的时候,需要补上一个存储0

    while (!isEmpty(&myStack))
    {
        putchar('0' + getTop(&myStack));
    }

    system("pause");
}

程序片段(04):01.蟒蛇.c
内容概要:

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

//01.蛇形行走:
//  1.规律总结:
//      (1).每次都是围绕"未走过"的"最外圈"棋盘
//      (2).每一圈儿的行走起点都是该圈儿的最左上角
//  2.必杀技巧:
//      (1).二维数组模拟棋盘
//      (2).采用循环变量控制圈儿数以及转向(四个方向)
//  注:圈数采用变量模拟和控制
//02.控制技巧:
//  1.外层循环核心控制圈数
//      (1).圈数必定大于等于1
//      (2).圈数与行数之间的关系
//          行数=1-->圈数=1
//          行数=2-->圈数=1
//          规律:(行数+1)/2-->圈数
//  2.内部循环控制四周的转向操作
//      在这里是顺时针的转向操作
//  3.空置棋盘,填充规律数字
#define N 10
int intArrArr[N][N] = { 0 };
int main01(void)
{
    int num = 1;//规律数值生成器:初始化为1
    for (int q = 0, x = 0, y = 0; q < (N + 1) / 2; ++q)
    {
        while (y < N - q)//控制横向列数
        {
            intArrArr[x][y] = num++;
            ++y;
        }
        --y;//回列
        ++x;//走行
        while (x < N - q)//控制纵向行数
        {
            intArrArr[x][y] = num++;
            ++x;
        }
        --x;//回行
        --y;//走列
        while (y > q - 1)
        {
            intArrArr[x][y] = num++;
            --y;
        }
        ++y;//回列
        --x;//走行
        while(x > q)
        {
            intArrArr[x][y] = num++;
            --x;
        }
        ++x;//回行
        ++y;//走列
    }

    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < N; ++j)
        {
            printf("%4d", intArrArr[i][j]);
        }
        printf("\n");
    }

    system("pause");
}

程序片段(05):数组交集与并集.c
内容概要:交集与并集

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

//00.求交并集的首要条件是:
//  去除各个集合当中重复的元素,防止重复存储
#define M 15
#define N 10
//01.求交集规律总结:
//  1.新建交集数组存储交集结果:
//      交集数组的元素个数最多为较小待求交集的那个数组的元素个数
//  2.以待求交集的那个数组的元素个数为外层循环遍历该数组
//      然后用该数据与另外一个较大待求交集的那个数组元素进行比较
//  3.如果较小数组元素和较大数组元素一样
//      那就将该数组元素存入进交集数组当中,否则不用放入
int main01(void)
{
    int intArrM[M] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    int intArrN[N] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };

    int intArrJiao[N] = { 0 };//求交集
    int index = 0;
    int flag = 0;
    for (int i = 0; i < N; ++i)//外层循环最少,能够达到最大的节省循环次数
    {
        flag = 0;
        for (int j = 0; j < M; ++j)
        {
            if (intArrN[i] == intArrM[j])
            {
                flag = 1;
                break;
            }
        }
        if (1 == flag)
        {
            intArrJiao[index++] = intArrN[i];
        }
    }
    for (int i = 0; i < N; ++i)
    {
        if (0 == intArrJiao[i])
        {
            break;
        }
        printf("%3d", intArrJiao[i]);
    }

    system("pause");
}

//02.求并集规律总结:
//  1.新建并集数组存储并集结果:
//      并集数组的元素个数最多为两个待求并集数组的元素个数总和
//  2.并集数组拷贝:
//      将待求并集数组当中元素最多的那个数组的元素全部拷贝到并集数组当中
//      因为并集数组当中元素最少就是较大的那个数组当中的元素个数
//  3.然后遍历较小的那个待求并集数组当中的每个元素
//      再用该元素与较大的那个待求并集数组的元素进行比对
//  4.如果较小数组元素和较大数组元素不一样
//      那就将该数组元素存储进并集数组当中,否则不用进行存入
int main02(void)
{
    int intArrM[M] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    int intArrN[N] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };

    int intArrBing[M + N] = { 0 };
    for (int i = 0; i < M; ++i)
    {
        intArrBing[i] = intArrM[i];
    }
    int index = M;
    int flag = 0;
    for (int i = 0; i < N; ++i)
    {
        flag = 0;
        for (int j = 0; j < M; ++j)
        {
            if (intArrN[i] == intArrM[j])
            {
                flag = 1;
                break;
            }
        }
        if (0 == flag)
        {
            intArrBing[index++] = intArrN[i];
        }
    }
    for (int i = 0; i < M + N; ++i)
    {
        if (0 == intArrBing[i])
        {
            break;
        }
        printf("%3d", intArrBing[i]);
    }

    system("pause");
}

程序片段(06):01.破解密码.c
内容概要:密码概率分布

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

#define N 20
int intArr[N] = { 1, 2, 3, 1, 2, 9, 9, 10, 11, 12, 1, 2, 1, 2, 2, 2, 1, 10, 11, 98 };
typedef struct
{
    int value;//密码值
    int count;//次数
} Pass;
Pass pass[N] = { 0 };//结构体数据清零

int main(void)
{
    //对数组pass当中的元素进行排序
    int currentIndex = 0;
    int currentValue = 0;
    for (int i = 1; i < N; ++i)
    {
        currentIndex = i;
        currentValue = intArr[i];
        while (currentIndex > 0 && intArr[currentIndex - 1] > currentValue)
        {
            intArr[currentIndex] = intArr[currentIndex - 1];
            --currentIndex;
        }
        intArr[currentIndex] = currentValue;
    }

    for (int i = 0; i < N; ++i)
    {
        printf("%3d", intArr[i]);
    }
    printf("\n\n");

    int index = 0;//代表结构体数组当中第一个结构体元素的索引
    int count = 0;
    for (int i = 0; i < N; ++i)
    {   
        count = 1;
        pass[index].value = intArr[i];
        for (int j = i; j < N - 1; ++j)
        {
            if (intArr[j] == intArr[j + 1])
            {
                ++count;
            }
            else
            {
                i = j;//最后一个相同值的所在位置
                break;//中断
            }
        }
        pass[index++].count = count;
    }

    //for (int i = 0; i < N; ++i)
    //{
    //  if (0 == pass[i].count)
    //  {
    //      break;
    //  }
    //  printf("%3d%3d \n",pass[i].value, pass[i].count);
    //}

    int end = 0;
    for (int i = 0; i < N; ++i)
    {
        if (pass[i].count == 0)
        {
            end = i;//等效于有效元素个数
        }
    }

    int maxIndex = 0;
    int maxCount = 0;
    for (int i = 0; i < end - 1; ++i)
    {
        maxIndex = i;
        maxCount = pass[i].count;
        for (int j = i + 1; j < end; ++j)
        {
            if (maxCount < pass[j].count)
            {
                maxIndex = j;
                maxCount = pass[j].count;
            }
        }
        if (i != maxIndex)
        {
            pass[i].value = pass[i].value ^ pass[maxIndex].value;
            pass[maxIndex].value = pass[i].value ^ pass[maxIndex].value;
            pass[i].value = pass[i].value ^ pass[maxIndex].value;

            pass[i].count = pass[i].count ^ pass[maxIndex].count;
            pass[maxIndex].count = pass[i].count ^ pass[maxIndex].count;
            pass[i].count = pass[i].count ^ pass[maxIndex].count;
        }
    }
    for (int i = 0; i < end; ++i)
    {
        if (0 == pass[i].count)
        {
            break;
        }
        printf("%3d%3d \n", pass[i].value, pass[i].count);
    }

    system("pause");
}

程序片段(07):stack.h+stack.c+01.台阶.c
内容概要:台阶问题

///stack.h
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define N 100
struct stack
{//[将结构体当中为一个整体进行看待]
    int data[N];
    int top;//标识栈顶
};
typedef struct stack Stack;//Stack作为该结构体的别名,相当于是对重新定义的一个数据类型进行更名识别

//[对结构体当中的某个属性进行修改]
void init(Stack *p);//初始化
int isempty(Stack *p);//判断栈是否为空
int isfull(Stack *p);//判断栈溢出
int gettop(Stack *p);//获取栈顶
void push(Stack *p);//插入数据 
void pop(Stack *p);//吐出栈顶数据
void show(Stack *p);//显示栈结构数据
///stack.c
#include "stack.h"

void init(Stack *p)//初始化栈结构
{
    memset(p->data, 0, sizeof(int)*N);//数据清零
    p->top = -1;//代表为空
}
int isempty(Stack *p)//判断栈结构是否为空
{
    if (p->top=-1)
    {
        return 1;//为空
    }
    else
    {
        return 0;//不为空
    }
}
int isfull(Stack *p)//判断栈溢出
{
    if (p->top==N-1)
    {
        return 1;//溢出
    }
    else
    {
        return 0;//还能再喝点儿
    }
}
int gettop(Stack *p)//获取栈顶数据
{
    return p->data[p->top];
}
void push(Stack *p, int key)//将数据压入栈头
{
    if (isfull(p)==1)
    {
        return;
    }
    else
    {
        p->top += 1;//结构体指向下一个整体
        p->data[p->top] = key;//压入数据
    }
}
void pop(Stack *p)//吐出
{
    if (isempty(p)==1)
    {
        return; 
    }
    else
    {
        p->top -= 1;//出栈
    }
}
void show(Stack *p)//显示栈结构当中的所有数据
{
    if (isempty(p)==1)
    {
        return;
    }
    else
    {
        printf("\n栈的数据时\n");
        for (int i = 0; i <=p->top; i++)
        {
            printf("%4d", p->data[i]);//打印栈结构当中的数据
        }
        printf("\n");
    }
}
///01.台阶.c
#include "stack.h"

#define STPES 10
//01.三级台阶问题:
//  1.1次只能走1步,2步,或者3步
//  2.10级台阶有多少中走法?
//  1       1
//  2       2       11+2
//  3       4       111+12+21+3
//  4       7       1111    +112+121+211+13+31
//  n=(n-3)+(n-2)+(n-1);//规律总结
int stepMethods(int steps)
{
    if (1 == steps)
    {
        return 1;
    }
    else if (2 == steps)
    {
        return 2;
    }
    else if (3 == steps)
    {
        return 4;
    }
    return stepMethods(steps - 3) + stepMethods(steps - 2) + stepMethods(steps - 1);
}

//01.通过数组栈来提升递归效率:
//  递归-->加速-->循环+数组栈
int main01(void)
{
    int intArr[STPES] = { 1, 2, 4 };//前3级台阶作为基础进行规律的建立
    for (int i = 3; i < STPES; ++i)
    {
        intArr[i] = intArr[i - 3] + intArr[i - 2] + intArr[i - 1];
    }
    printf("stepMethods = %d, intArr[N - 1] = %d \n", stepMethods(STPES), intArr[STPES - 1]);

    system("pause");
}

//02.直接循环结构
int main02(void)
{
    int steps1 = 1;
    int steps2 = 2;
    int steps3 = 4;
    int stepsN = 0;
    for (int i = 3; i < 10; ++i)
    {
        stepsN = steps1 + steps2 + steps3;
        steps1 = steps2;
        steps2 = steps3;
        steps3 = stepsN;
    }
    printf("stepsN = %d \n", stepsN);

    system("pause");
}

程序片段(08):queue.h+queue.c+01.队列.c
内容概要:队列

///queue.h
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define N 100//队列结构的元素实体个数
typedef struct
{
    int data[N];//队列结构的内存存储空间
    int head;//标识队列结构的头部位置
    int back;//标识队列结构的尾部位置
} Queue;

void initQueue(Queue * pQueue);//初始化队列结构
int isEmpty(Queue * pQueue);//判定队列结构是否为空
int isFull(Queue * pQueue);//判定队列结构是否已满
void enQueue(Queue * pQueue, int value);//为队列结构添加一个数据元素
void deQueue(Queue * pQueue);//出队
int getLast(Queue * pQueue);//获取队列尾部数据实体
void showQueue(Queue * pQueue);//展示队列状态
///queue.c
#include "queue.h"

//01.队列结构的开头位置是固定死的
void initQueue(Queue * pQueue)
{
    (*pQueue).head = (*pQueue).back = 0;//标识队列结构为空
    memset(pQueue, 0, sizeof(int)*N);//只是针对于内存空间的数据清零操作
}

int isEmpty(Queue * pQueue)
{
    if ((*pQueue).head == (*pQueue).back)
    {
        return 1;
    }
    return 0;
}

int isFull(Queue * pQueue)
{
    if (pQueue->back == N - 1)
    {
        return 1;
    }
    return 0;
}

void enQueue(Queue * pQueue, int value)
{
    if (1 == isFull(pQueue))
    {
        return;
    }
    else
    {
        if (1 == isEmpty(pQueue))
        {
            (*pQueue).data[0] = value;
            ++((*pQueue).back);
        }
        else
        {
            for (int i = (*pQueue).back; i > 0; --i)
            {
                (*pQueue).data[i] = (*pQueue).data[i - 1];
            }
            (*pQueue).data[0] = value;
            ++((*pQueue).back);
        }
    }
}

int getLast(Queue * pQueue)//只是查询效果
{
    return (*pQueue).data[(*pQueue).back - 1];
}

void deQueue(Queue * pQueue)
{
    if (isEmpty(pQueue))
    {
        return;
    }
    --((*pQueue).back);
}

void showQueue(Queue * pQueue)
{
    for (int i = 0; i < (*pQueue).back; ++i)
    {
        printf("%4d", (*pQueue).data[i]);
    }
    printf("\n\n");
}
///01.队列.c
#include "queue.h"
#include "Windows.h"
#include "process.h"

int main01(void)
{
    Queue myQueue;
    initQueue(&myQueue);
    for (int i = 99; i < 108; ++i)
    {
        enQueue(&myQueue, i);
        showQueue(&myQueue);
    }
    while (!isEmpty(&myQueue))
    {
        printf("%4d \n", getLast(&myQueue));
        deQueue(&myQueue);
        showQueue(&myQueue);
    }

    system("pause");
}

Queue myQueue;
void run(void * p)
{
    int * px = p;
    printf("线程编号是%d \n", *px);
    enQueue(&myQueue, *px);
}

//int intArr[10]-- > int * p = intArr;
int main02(void)
{
    initQueue(&myQueue);
    int intArr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    for (int i = 0; i < 10; ++i)
    {
        HANDLE hd = _beginthread(run, 0, &intArr[i]);
        WaitForSingleObject(hd, INFINITE);
        //WaitForMultipleObjects();
    }

    system("pause");//防止主线程提前结束
    showQueue(&myQueue);

    system("pause");
}

posted on 2016-02-18 22:39  牛栏山1  阅读(186)  评论(0编辑  收藏  举报

导航