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=0022FEA8
printf("&str[0]=%p\n",&str[0]);//&str[0]=0022FEA8
printf("str+1=%p\n",str+1);//str+1=0022FEAC
printf("*str=%d\n",*str);//*str=1
printf("str[0]=%d\n",str[0]);//str[0]=1
printf("*(str+1)=%d\n",*(str+1));//*(str+1)=2
printf("str+5-str=%d\n",str+5-str);//str+5-str=5
printf("(int)(str+5)-(int)str=%d\n",(int)(str+5)-(int)str);//(int)(str+5)-(int)str=20
printf("(short*)(str+5)-(short*)str=%d\n",(short*)(str+5)-(short*)str);//(short*)(str+5)-(short*)str=10
printf("(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.
/********************以上纯属个人理解**********************/
/*********如果有错误的地方,希望能够指点一下*********/