在计算机中,内存的分配就是一块块的,内存中可以存储很多东西,不同的数据类型,指针,并且每块内存都有相应的物理地址编号。用户向计算机申请分配内存资源时,计算机将没有占用的内存资源按照某种方式分配给用户。
地址的本义也是内存存储的数据,但是这个数据是可以指向某个数据的标识。
将两个数据进行交换:
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,q为x,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,q为x,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.
====================================================