C语言中指针的运算
int a1[]={0,1,5,9,4,}; 为避免偶然 我不按顺序排数
int *p = a1;
printf("p = %p\n",p);
printf("p+1 = %p\n",p+1);
printf("sizeof(int) = %d\n",sizeof(int));
double a2[]={0,1,2,3,4,};
double *q = a2;
printf("q = %p\n",q);
printf("q+1 = %p\n",q+1);
printf("sizeof(double) = %d\n",sizeof(double));
/*
那为什么指针加一相当于加一个数据类型长度?
因为在一个数组里,一个元素分为对于数据类型的字节,
如果int 一个数组 一个元素被划分为4个字节 指针代表一个地址
如果加一不是加一个数据类型长度,而是地址加一,
那么加了一之后还是这个元素,就显得毫无意义,
所以就设置为加一个数据类型长度,本质上就是移动一个元素下标,移动一个位置
*/
printf("*p = %d\n",*p);
printf("a1[0] = %d\n",a1[0]);
printf("*(p+2) = %d\n",*(p+2));
printf("a1[2] = %d\n",a1[2]);
printf("*(p+3) = %d\n",*(p+3));
printf("a1[3] = %d\n",a1[3]);
printf("*p+1 = %d\n",*p+1);
printf("*p+2 = %d\n",*p+2);
/*
有无括号是有区别的
*(p+n)有括号 此时为地址加n个数据类型长度 因为p是地址 相当于a1[0]移动n个下标
*p+n 无括号 此时为数值加一 因为*p就是值 相当于就是*p= a1=&a1[0] =0 再加上数值n 而已
指针可用运算符有
-,-=,+=,++,--
*/
int *p1 = &a1[3] ;
printf("p = %p\n",p);
printf("p1 = %p\n",p1);
printf("p1 - p = %d\n",p1-p);
/*
两个十六进制的地址相减为C C即为十进制12
此时p1=9,p=0,显然p1-p不是两者差值,那3是什么?
3是由地址差值除以数据类型长度得来的 即12/4=3
那么这就说明,指针与指针的运算又与指针本身加减是有所不同的
指针之间的运算是地址之间的运算,这就很有意思了
*/
int array[]={0,1,2,3,4,5,6,-1};
int *arr = array;
while(*arr != -1)
{
printf("%d ",*arr++);
}
/*
指针也可以用作数组空间的连续操作,这其中还是有历史故事的。
C语言初期,电脑运行速度并没有那么快,
当时的*p++,表示可以把c语言代码翻译成机器执行指令,
因此代码跑起来就更快,这也是指针的来源。
*/
/*
补充:
指针是不可以继续乘除的;
指针之间也可以比较,实质是地址的比较;
常用比较运算符,指针也可以使用;
*/