对C语言一些个人见解系列:指针和一维数组的关系

来源:互联网 发布:mac teamviewer 破解 编辑:程序博客网 时间:2024/05/22 05:21

1.指针的定义和声明

我认为定义一个指针,本质来说,就是在定义一个变量。只是这个变量,不是拿来存在一个具体的数字。而是存放一个地址(指针指向的地方)。

比如说:int a=4;表示的是声明一个整数型的变量,在内存内开辟了一个int型大小的内存空间,存放着4这个数字。而这个内存空间有个系统分配的地址来标注它。

int* b=&a;这个我们可以把int*看成一个整体,它声明了一个指针变量b,用来存放了整形变量a所在的地址。因此,指针变量b指向了a的地址空间。

所以,从这里我们可以看出,指针存放的是一个地址,而不是单纯的一个数字。

代码:

#include<stdio.h>int main(){     int a=4;     int* b=&a;     printf("%p,%p",b,&a);//0022FEB8,0022FEB8     printf("%d,%d",*b,a);//4,4}
从这个程序我们可以看出来,在屏幕打印出来的值都是对应相等。即,b指向了a的地址空间。

2.指针和一维数组

首先,数组本质是个常数指针,即指向是不能改变的。

比如说:char str[5]={};

       str="abcd";

这样写是不对的,这样相当于改变了数组的指向。

我们来看一段代码:

#include<stdio.h>int main(){int str[]={1,2,3,4,5,6};printf("str=%p\n",str);//str=0022FEA8printf("&str[0]=%p\n",&str[0]);//&str[0]=0022FEA8printf("str+1=%p\n",str+1);//str+1=0022FEACprintf("*str=%d\n",*str);//*str=1printf("str[0]=%d\n",str[0]);//str[0]=1printf("*(str+1)=%d\n",*(str+1));//*(str+1)=2printf("str+5-str=%d\n",str+5-str);//str+5-str=5printf("(int)(str+5)-(int)str=%d\n",(int)(str+5)-(int)str);//(int)(str+5)-(int)str=20printf("(short*)(str+5)-(short*)str=%d\n",(short*)(str+5)-(short*)str);//(short*)(str+5)-(short*)str=10printf("(char*)(str+5)-(char*)str=%d\n",(char*)(str+5)-(char*)str);//20
我们先看空格上面的代码:

       1.我们可以看到str=&str[0]=0022FEA8,说明数组名可以作为数组的首地址,也就是str[0]的地址。

       2.而*(str+1)=2=str[1],而且str+1与str相差4,说明所谓地址的加1,并不仅仅是数字上的+1,而是+1个int型的大小(4)。

       3.比如:*((int*)(&str+1)-1)=6,因为对&str对一维数组取地址,可以直接理解为变成一个二维数组,因此对二维数组的地址+1,相当加上一个一维数组的长度,然后在通过int* 将它强制转换成一维数组,再-1,就相当与减一个int型的长度,因此等于6.

       4.对于一维数组地址的相减,我们不能简单的理解成,两个数简单的算数相减,而是要带单位的相减。

  就如程序里面的int型的大小是4,short的大小是2,char的大小是1。因此,可以用一个公式概括:

  [a(地址1)-b(地址2)]/(int或short或char的大小),因此,得出才会是5,10和20

而为什么(int)(str+5)-(int)str=20呢?

因为(int)直接将地址直接强制转换成int型数据,而不再是一个地址,而是一个简简单单的数据。而这个数本来就相差20,所以结果也就是20.

/********************以上纯属个人理解**********************/

/*********如果有错误的地方,希望能够指点一下*********/


0 0