指针小随笔

在计算机中,内存的分配就是一块块的,内存中可以存储很多东西,不同的数据类型,指针,并且每块内存都有相应的物理地址编号。用户向计算机申请分配内存资源时,计算机将没有占用的内存资源按照某种方式分配给用户。
地址的本义也是内存存储的数据,但是这个数据是可以指向某个数据的标识。

将两个数据进行交换:

void swap(int x,int y)  
    {  
        int tmp;                //相当于只交换了形参变量的值的值 
        tmp=x;  
        x=y;  
        y=tmp; 
        printf("later形参:%d,%d\n",x,y);    
    }  
 void swap(int* x,int* y)  
    {  
        int *tmp=NULL;  
        tmp=x;  
        x=y;  
        y=tmp;     
    }  

以上两种都不会真正的交换值,仅仅相当于是将实参的地址或者数据直接
拷贝了一份传给形参,对形参操作后并不会传给实参,所以并会真正起作用。实参并没有发生任何影响。

    #include <stdio.h>  
    int main()  
    {  
        int a=2,b=3;  
        void swap(int* x,int* y);  
        printf("before:%d,%d\n",a,b);  
        swap(&a,&b);  
        printf("later实参:%d,%d\n",a,b);
        printf("later实参地址:%d,%d\n",&a,&b);   
        return 0;  

    }  

    void swap(int* x,int* y)  
    {  
        int tmp;  
        tmp=*x;  
        *x=*y;  
        *y=tmp; 
        printf("later形参:%d,%d\n",*x,*y);   
        printf("later形参地址:%d,%d\n",x,y);       
    }  

然而上面这部分虽然也是地址的交换,但是是将形参地址所指向的值进行交换,那么实参形参相同数据相同的情况下指向也一样,数据发生交换,地址并没有发生改变结果如下:

运行结果:
before:2,3
later形参:3,2
later形参地址:6684236,6684232
later实参:3,2
later实参地址:6684236,6684232
#include<stdio.h>
void swap(int **a,int **b)
{  
     int  *t;                 
    t=*a;   *a=*b;  *b=t;      //交换地址的地址
    printf("形参地址的地址指向的值:%d\t%d\n",a,b); 
    printf("形参地址指向的值:%d\t%d\n",*a,*b); 
}
main()
{  
 int  x=3,y=5,*p=&x,*q=&y;// p,qx,y的地址
 printf("before实参:%d\t%d\n",x,y);//相当于交换的p,q的地址  
 printf("before实参地址:%d\t%d\n",&x,&y);
 swap(&p, &q);            //交换p,q的地址 
 printf("later实参地址指向的值:%d\t%d\n",*p,*q);
 printf("later实参地址:%d\t%d\n",p,q); 
 printf("later实参:%d\t%d\n",x,y);//相当于交换的p,q的地址 
} 
运行结果:
before实参:3    5
before实参地址:6684236  6684232
形参地址的地址指向的值:6684224  6684216
形参地址指向的值:6684232        6684236
later实参地址指向的值:5 3
later实参地址:6684232   6684236
later实参:3     5
#include<stdio.h>
void swap(int ***a,int ***b)
{  
     int  **t;                 
    t=*a;   *a=*b;  *b=t;      //交换地址的地址
    printf("形参地址的地址指向的值:%d\t%d\n",*a,*b); 
    printf("形参地址指向的值:%d\t%d\n",**a,**b); 
}
main()
{  
 int  x=3,y=5,*p=&x,*q=&y;// p,qx,y的地址
 int **m=&p;
 int **n=&q;
 printf("before实参:%d\t%d\n",x,y);
 printf("before实参地址:%d\t%d\n",&x,&y);
 swap(&m, &n);           
 printf("later实参地址的地址指向的值:%d\t%d\n",**m,**n); 
 printf("later实参地址指向的值:%d\t%d\n",*p,*q);
 printf("later实参地址:%d\t%d\n",p,q); 
 printf("later实参:%d\t%d\n",x,y);//相当于交换的p,q的地址 
} 
运行结果:
before实参:3    5
before实参地址:6684236  6684232
形参地址的地址指向的值:6684216  6684224
形参地址指向的值:6684232        6684236
later实参地址的地址指向的值:5   3
later实参地址指向的值:3 5
later实参地址:6684236   6684232
later实参:3     5

上面的两个例子显示:当参数的高层地址对次层地址进行交换时,也会发生次层地址所指向的内容会反生交换,即在那一层发生地址指向的内容发生变化,就是那一层的问题。

int const和const int 的区别

int *const p;
p=&x;
相当于这个const定义的是这个这个指针指向的变量不会发生改变,可以将变量进行操作但是不能让这个p指针指向另外一个变量。
const int *p;
p=&x;
p=&y;
相当于const定义的是一个常量指针,这个指针不能被发生改变,不能对这个指针直接赋值如:
*p=81;//这种情况不会发生.
间接改变*p的值只能通过p指针指向不同的变量来执行:
如:

#include <stdio.h>
int main()
{
    int x=9,y=90;
    int *const p=&x;
    const int *q;
    //p=&x;
    //p=&y;
    q=&x;
    q=&y;
    printf("*p->:%d\n",*p);
    printf("*q->:%d\n",*q);
    x=90;
    y=100;
    printf("*p->:%d\n",*p);
    printf("*q->:%d",*q);
}
*p->:9
*q->:90
*p->:90
*q->:100

int const* p=&x;int const*第一遍初始化时就必须直接将指向内容定义到。否则报错。

指针级应用理解

(下面代码来源于网上大牛:)

#include <stdio.h>
#include <malloc.h>
struct NODE {
    char         data;
    struct NODE *U;//上
    struct NODE *R;//右
    struct NODE *D;//下
    struct NODE *L;//左
} *B,*q;
struct NODE *m[10];
char p[3][4];
int i;
void show_node(struct NODE *s,int y,int x) {
    if (NULL==s) return;
    for (i=0;i<10;i++) {
        if (m[i]==s) return;
    }
    for (i=0;i<10;i++) {
        if (NULL==m[i]) {
            m[i]=s;
            break;
        }
    }
    p[y][x]=s->data;
    show_node(s->U,y-1,x  );
    show_node(s->R,y  ,x+1);
    show_node(s->D,y+1,x  );
    show_node(s->L,y  ,x-1);
}
void show_xlinks(struct NODE *b) {//显示整个十字链表
    int y,x;

    for (i=0;i<10;i++) m[i]=NULL;
    for (y=0;y<3;y++) {
        for (x=0;x<4;x++) {
            p[y][x]=' ';
        }
    }
    show_node(b,1,1);
    for (y=0;y<3;y++) {
        for (x=0;x<4;x++) {
            printf("%c",p[y][x]);
        }
        printf("\n");
    }
    printf("----\n");
}
void swap_xlinks(struct NODE **pa,struct NODE **pb) {
    struct NODE *a,*aU,*aR,*aD,*aL;
    struct NODE *b,*bU,*bR,*bD,*bL;
    struct NODE *t;

    if (pa==pb) return;

    a=*pa;
    aU=a->U;
    aR=a->R;
    aD=a->D;
    aL=a->L;

    b=*pb;
    bU=b->U;
    bR=b->R;
    bD=b->D;
    bL=b->L;

    if (aU && aU!=b) aU->D=b;
    if (aR && aR!=b) aR->L=b;
    if (aD && aD!=b) aD->U=b;
    if (aL && aL!=b) aL->R=b;

    if (bU && bU!=a) bU->D=a;
    if (bR && bR!=a) bR->L=a;
    if (bD && bD!=a) bD->U=a;
    if (bL && bL!=a) bL->R=a;

    t=a->U;a->U=b->U;b->U=t;if (a->U==a) a->U=b;if (b->U==b) b->U=a;
    t=a->R;a->R=b->R;b->R=t;if (a->R==a) a->R=b;if (b->R==b) b->R=a;
    t=a->D;a->D=b->D;b->D=t;if (a->D==a) a->D=b;if (b->D==b) b->D=a;
    t=a->L;a->L=b->L;b->L=t;if (a->L==a) a->L=b;if (b->L==b) b->L=a;

    if (a==*pa) *pa=b;
    if (b==*pb) *pb=a;
}
void free_xlinks() {
    for (i=0;i<10;i++) if (NULL!=m[i]) free(m[i]);
}
int main() {
    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='1';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q记录为起始节点B//
    B=q;                //   1
                        //
    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='2';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的上边    //   2
    B->U=q;             //   1
    q->D=B;             //

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='3';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的右边    //   2
    B->R=q;             //   13
    q->L=B;             //

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='4';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的下边    //   2
    B->D=q;             //   13
    q->U=B;             //   4

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='5';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的左边    //   2
    B->L=q;             //  513
    q->R=B;             //   4

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='6';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的左上    //  62
    B->L->U=q;          //  513
    B->U->L=q;          //   4
    q->R=B->U;
    q->D=B->L;

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='7';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的右上    //  627
    B->R->U=q;          //  513
    B->U->R=q;          //   4
    q->L=B->U;
    q->D=B->R;

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='8';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的右下    //  627
    B->R->D=q;          //  513
    B->D->R=q;          //   48
    q->L=B->D;
    q->U=B->R;

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='9';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在B的左下    //  627
    B->L->D=q;          //  513
    B->D->L=q;          //  948
    q->R=B->D;
    q->U=B->L;

    //创建1个节点的十字链表q
    q=(struct NODE *)malloc(sizeof(struct NODE));
    if (NULL==q) return 1;
    q->data='a';
    q->U=NULL;
    q->R=NULL;
    q->D=NULL;
    q->L=NULL;

    //将q放在3的右边    //  627
    B->R->R=q;          //  513a
    q->L=B->R;          //  948

    printf("begin:\n");
    show_xlinks(B);

    printf("swap 1a:\n");
    swap_xlinks(&B,&B->R->R);
    show_xlinks(B);

    printf("swap a3:\n");
    swap_xlinks(&B,&B->R);
    show_xlinks(B);

    printf("swap 34:\n");
    swap_xlinks(&B,&B->D);
    show_xlinks(B);

    printf("swap 45:\n");
    swap_xlinks(&B,&B->L);
    show_xlinks(B);

    printf("swap 52:\n");
    swap_xlinks(&B,&B->U);
    show_xlinks(B);

    printf("swap 28:\n");
    swap_xlinks(&B,&B->R->D);
    show_xlinks(B);

    printf("swap 47:\n");
    swap_xlinks(&B->L,&B->R->U);
    show_xlinks(B);

    free_xlinks();

    printf("end.\n");
    return 0;
}
运行结果:
begin:
627
513a
948
----
swap 1a:
627
5a31
948
----
swap a3:
627
53a1
948
----
swap 34:
627
54a1
938
----
swap 45:
627
45a1
938
----
swap 52:
657
42a1
938
----
swap 28:
657
48a1
932
----
swap 47:
654
78a1
932
----
end.

====================================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值