c语言 二维指针怎么申请空间,二话指针 - 二维空间 - OSCHINA - 中文开源技术交流社区...

指针的基本概念

指针即地址

通常意义上声明一个变量,总会存在两个概念,一个是变量的值,另一个是变量的地址。这两个是必须存在!其实更多的情况下,我们只关心变量的值,不并在乎变量的地址是什么。而且不是所有的语言都提供地址运算。

Char *p = &c;

上面声明最的正确解释是,声明了一个指针变量c地址处的指针p,即p的值是变量c的地址。

测试代码:

char c = 'A';

char *p = &c;

if(p != &c){

printf(“Logic is error\n”);

}

回到上面为什么一个变量而言必须存在一个变量的地址呢?

程序在执行的时候,都是在内存里面跑的。计算机为了管理和使用内存的方便,进而对内存进行了编址,相当于给房屋的门牌号码,对于每一个号码其对应该房子的位置都是确定的。每次计算机申请的内存时,都是申请到一个地址对应的编号。申请变量的类型,决定了这块可使用地址的长度。几乎都是起始地址+长度的方式来判定的。这个编号是计算机本身在使用,程序员不太关注。几乎程序员只关系自己是否有可以写的变量,自己的写操作是否正确。如同住户不必每天都关心自己的门牌号一样,只是别人问起的时候或者邮寄的时候才会看看自己门牌号。

通过上面的例子说明了一点,地址是让别人找到自己的位置的一个描述符。

二维指针的使用

二维指针的使用还是比较频繁的,相对于三维以上的指针而言,也是比较好理解的。二维指针即指针的指针。

对于特定的系统指针所占用的字节数都是相同的。对于一个32位的操作系统,无论是一维指针还是二维指针占用的字节数都是4个字节。

Char **p = NULL;

p = (char**)malloc(sizeof(char*)*LENGTH);

申请了存放LENGTH个char*的地址空间,每个char*可以根据自己的需要来申请大小。

此处通过指针运算可以比较方便地操作。

为什么要使用指针

使用指针一是可能带回变量的值,二是指针运算比较方便,三是指针确实是增大的变量的寻址空间。

一使用指针带回变量的值

看一个交换的例子。如果是在一个函数内部对两个变量的值进行交换,那么只要下面的代码就可以了:

int t = a;

a = b;

b = t;

但是如果是通过函数调用的形式来实现这个交换,那么就是要使用下面的代码。

int swap(int *a , int *b){

int t = *a;

*a = *b;

*b = t;

}

为什么会这样?

函数有两种传送参数的方式,一种是传值,另一种是传址(在这里实际上都是通过传值的)。函数在调用执行的过程中,使用栈来传送参数,从而保证每个函数有独立的执行空间。正是由于每次都是通过push操作将参数压入到栈里中,子过程的操作实际上是在操作函数栈里面的变量内容。栈与本地变量所处的位置不一样,所以会导致栈里面的内容修改而本地变量的内容没有被修改。从而失去了交换的真正目的。

那么为什么以使用上述的函数调用形式呢?其实本质上述的函数仍然是采用传值的方式传送参数的,只不过这里传入的值是变量的地址,同时函数体内部通过地址指向操作,即实现了对本地变量内容的修改。

实质上C语言里面是没有引用的概念,引用是在以后的高级语言新引进的概念。这个东西,很像指针,但又不是指针。至少不能如同指针一样运算,那么指针可以做哪些运算?又是怎么运算的?

先看看下面的测试代码

char a = 'A';

char *p = &a;

printf("address of a:%p\n",&a);

printf("address of a:%p\n",p);

p++;

printf("address of p:%p\n",p);

address of a:0xbfa41c2b

address of a:0xbfa41c2b

address of p:0xbfa41c2c

int a = 'A';

int *p = &a;

printf("address of a:%p\n",&a);

printf("address of a:%p\n",p);

p++;

printf("address of p:%p\n",p);

address of a:0xbfd75a38

address of a:0xbfd75a38

address of p:0xbfd75a3c

两希程序执行都是 p++,但是两次增量是不一样的。第一段地址的增量是sizeof(char),第二段地址的增量是sizeof(int).这个正好就是这个指针的类型所占的字节数,指针的加减运算的变量是指针类型。那么遇到空指针时会是什么个情况,下面继续测试:

int a = 'A';

int *p = &a;

void *nil_point = p;

printf("null nil_point:%p\n",nil_point);

nil_point ++;

printf("null nil_point:%p\n",nil_point);

nil_point = p;

(int*)nil_point++;

printf("convert to int* nil_point:%p\n",nil_point);

运行结果是:

null nil_point:0xbf960784

null nil_point:0xbf960785

convert to int* nil_point:0xbf960789

如果没有对指针进行强制转换,那么是以字节的形式变化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值