数据结构学习(二)指针和内存那些事儿

  地球人都知道,C语言中内存和指针一直是很多人不甚明白的地方,两者的关系也一直是犹抱琵琶半遮面,让人迷惑不解。 

  最近编写了个初始化三元组Triplet的函数,通过调试分析,指针和内存那层神秘的面纱被层层揭破,其实,也就那么回事儿。

  初始化三元组函数如下,内有详细的注释,很容易看懂,这个不是我们的重点,我们重点是分析内存和指针两者的关系。

代码Triplet.cpp
/* 引用查找路径 两种引用方式 */
#include
<stdio.h>
#include
<stdlib.h>

/* 定义常量 增强可读性*/
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERFLOW 3

/* 定义类型别名 增强可读性 */
typedef 
int Status;
typedef 
int Boolean;

/* 分配一个整形三元组的内存空间,返回该片内存空间首地址 */
int *InitTriplet(int v1,int v2,int v3)
{
    
int *= (int *)malloc(3*sizeof(int));
    
if(!T)
        exit(OVERFLOW);

    T[
0= v1;
    T[
1= v2;
    T[
2= v3;

    
return T;
}

/* 程序入口 */
int main(char *argc , char **argv)
{
    
/* 定义并声明T,获得内存首址 */
    
int *= InitTriplet(1,2,3);

    
/* 如果T,则说明内存分配成功 */
    
if(T)
    {
        printf(
"内存分配成功!\n");
        printf(
"\nT表示的地址为%x,*T的值,也就是T[0]的值为:%d",T,(int)T[0]);
        printf(
"\nT+1表示的地址为%x,*(T+1)的值,也就是T[1]的值为:%d",T+1,(int)T[1]);
        printf(
"\nT+2表示的地址为%x,*(T+2)的值,也就是T[2]的值为:%d\n",T+2,(int)*(T+2));
    }
    
/* 如果!T,则说明内存分配失败 */
    
else
    {
        printf(
"内存分配失败!\n");
        exit(OVERFLOW);
    }

    
//暂停以便输出
    system("pause");

    
//无论如何,返回
    return OK;
}

 

   下面的两张图片才是亮点,应该比较明白的说清楚了指针和内存的那些事儿,虽然他们的事儿还挺多的。

 

   下面的图片是运行结果:

 


  其实指针并不神秘,内存管理也就那样,但是要用好两者还是要心细如发,不能大意。

  下面的代码是三元组数据结构的代码,实现了新建,排序,设置值,获取值,最大值等功能,这里需要理解引用变量和赋值变量的区别!

Triplet完整代码
/* 引用查找路径 两种引用方式 */
#include
<stdio.h>
#include
<stdlib.h>

/* 定义常量 增强可读性 */
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERFLOW 3

/* 顺序存储结构 Triplet为int *类型 */
typedef 
int *Triplet;

/* 定义类型别名 增强可读性 */
typedef 
int Status;
typedef 
int Boolean;

/* 分配一个整形三元组的内存空间,返回该片内存空间首地址 */
int *InitTriplet(int v1,int v2,int v3)
{
    
int *= (int *)malloc(3*sizeof(int));
    
if(!T)
        exit(OVERFLOW);

    T[
0= v1;
    T[
1= v2;
    T[
2= v3;

    
return T;
}

/* 采用引用参数 T是int *类型的Triplet的引用,改变T,也就是改变Triplet*/
Status InitTriplet2(Triplet 
&T,int v1,int v2,int v3)
{
    T 
= (int *)malloc(3*sizeof(int));
    
if(!(T))
    {
        printf(
"内存分配失败!\n");
        exit(OVERFLOW);
    }
    
else
    {
        (T)[
0= v1;
        (T)[
1= v2;
        (T)[
2= v3;
    }

    
return OK;
}

/* 销毁三元组 T为Triplet的别名(引用) */
Status DestroyTriplet(Triplet 
&T)
{
    
//如果T不为NULL,才释放
    if(T)
    {
        free(T);
    }

    
//设置T为0x00000000,也就是NULL
    T = NULL;
    
return OK;
}


/* 用e返回T的第i个值 */
Status Get(Triplet T,
int i,int &e)
{
    
if(i<1 || i>3return ERROR;
    e 
= T[i-1];
    
return OK;
}

/* 设置T的第i个值 */
Status Set(Triplet 
&T,int i,int e)
{
    
if(i<1 || i>3return ERROR;
    T[i
-1= e;
    
return OK;
}

/* 判断三元组是否升序排列 */
Boolean IsAscending(Triplet T)
{
    
return (T[0<= T[1]) && (T[1<= T[2]);
}

/* 判断三元组是否升序排列 */
Boolean IsDescending(Triplet T)
{
    
return (T[0>= T[1]) && (T[1>= T[2]);
}

/* 最大值用e返回 */
Status Max(Triplet T,
int &e)
{
    e 
= (T[0>= T[1]) ? (T[0>= T[2]?T[0]:T[2]):(T[1>= T[2]?T[1]:T[2]);
    
return OK;
}

/* 最大值用e返回 */
Status Min(Triplet T,
int &e)
{
    e 
= (T[0<= T[1]) ? (T[0<= T[2]?T[0]:T[2]):(T[1<= T[2]?T[1]:T[2]);
    
return OK;
}

/* 程序入口 */
int main(char *argc , char **argv)
{
    
int *T2 = NULL;

    
if(InitTriplet2(T2,4,5,6))
    {
        printf(
"1.内存分配成功!\n");
        printf(
"\nT2表示的地址为%x,*T2的值,也就是T2[0]的值为:%d",T2,(int)T2[0]);
        printf(
"\nT2+1表示的地址为%x,*(T2+1)的值,也就是T2[1]的值为:%d",T2+1,(int)T2[1]);
        printf(
"\nT2+2表示的地址为%x,*(T2+2)的值,也就是T2[2]的值为:%d\n",T2+2,(int)*(T2+2));

        
int tmp;
        Get(T2,
2,tmp);
        printf(
"T2[1]的值为:%d\n",tmp);

        
if(IsAscending(T2))
        {
            printf(
"T2升序排列\n");
        }
        
else if(IsDescending(T2))
        {
            printf(
"T2降序排列\n");
        }
        
else
        {
            printf(
"T2完全无序\n");
        }

        Set(T2,
2,8);
        Get(T2,
2,tmp);
        printf(
"T2[1]设置新值后,T2[1]的值为:%d\n",tmp);

        
        Max(T2,tmp);
        printf(
"T2的最大值为:%d\n",tmp);


        Min(T2,tmp);
        printf(
"T2的最小值为:%d\n",tmp);

        
if(DestroyTriplet(T2))
        {
            printf(
"T2的内存被释放!\n");
        }
        
else
        {
            printf(
"T2释放内存失败!");
        }
    }

    
/* 定义并声明T,获得内存首址 */
    
int *= InitTriplet(1,2,3);

    
/* 如果T,则说明内存分配成功 */
    
if(T)
    {
        printf(
"\n2.内存分配成功!\n");
        printf(
"\nT表示的地址为%x,*T的值,也就是T[0]的值为:%d",T,(int)T[0]);
        printf(
"\nT+1表示的地址为%x,*(T+1)的值,也就是T[1]的值为:%d",T+1,(int)T[1]);
        printf(
"\nT+2表示的地址为%x,*(T+2)的值,也就是T[2]的值为:%d\n",T+2,(int)*(T+2));
    }
    
/* 如果!T,则说明内存分配失败 */
    
else
    {
        printf(
"内存分配失败!\n");
        exit(OVERFLOW);
    }

    
//暂停以便输出
    system("pause");

    
//无论如何,返回
    return OK;
}

 

 

posted on 2010-06-12 10:35  虚怀若谷  阅读(489)  评论(0编辑  收藏  举报

导航