C语言指针运算和函数传参数
1:取地址和指针运算符
2:指针赋值运算
3:数组名概念
4:指针的加减运算
5:指针比较运算
取地址和指针运算符
1:取地址运算符:
&运算符,返回操作数的内存地址
printf(“%p\n”,&a);
2:指针运算符:
* 运算符,也称为间接访问运算符,返回指针指向存储单元的数值;也称为指向运算符号:
注意:
指针运算符是取地址运算符号的反运算符号
*(&a) = 10;
指针赋值的运算:
指针变量1 = 指针变量2;
指针变量2中存放的地址赋予给指针变量1
如:
int a = 10;
int *p1 = &a,*p2;
p2 = p1;//将p1中存储的地址赋予给p1
插曲:
左值和右值:左边的值代表存储单元,用变量表示,右值代表存储单元中的值;
如:*pointer = *pointer + 1;
数组名的概念:
一个数组存储在一块连续内存单元中,数组名就是这块连续单元的首地址,也是数组中第一个元素的地址:
如int num = {0,1,2,3,4,5,6,7};
注意:
1:数组名称就是地址
2:数组的第一个元素表示的就是数组的地址
3:数组名加上偏移量也就可以得到其他元素的地址
4:数组名是一个常量,是不允许被重新赋值的
如int a [] = {1,2,3,4,5};
int b [] = {7,8,9};
a = b;//这种操作是错误的操作
调试代码:
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char* argv[]){
int array[] = {1,2,3,4,5,6};
//数组地址就是数组名或者数组中第一个元素的地址
printf("array address:%p\n",array);
printf("array[0] address:%p\n",&array[0]);
//C语言中对地址的加减操作移动的是存储单元的大小
printf("array next address:%p\n",array+1);
printf("array[1] address:%p\n",&array[1]);
return 0;
}
结果为:
array address:0x7ffdd7cdbad0
array[0] address:0x7ffdd7cdbad0
array next address:0x7ffdd7cdbad4
array[1] address:0x7ffdd7cdbad4
从上面的结果 中我们可以看到的是:数组名就是数组第一个元素的地址,而我们也可以通过数组名的加减运算去得到数组中元素的数值,通过这样的运算,我们可以不断的去获得数组中元素的地址和元素的数值是多少,无论这样的数组是几维数组都是可以获得的。
指针的加减运算
数组名与指针是非常相似的,我们可以通过比较数组名的这样的加减运算,来照搬到指针的运算中,而实质上,我们可以把对数组名这样的操作就看成是我们对于指针的操作
1:指针每递增一次,它其实会指向下一个元素的存储单元
2:指针每递减一次,它都会指向前一个元素的存储单元
3:指针在增减时候跳跃的字节数将取决于指针所指向变量数据类型长度
调试代码如下:是指针与数组的联合调试,便于我们更好的看到加减操作,
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char * argv[]){
int num [] = {1,3,6,8,10,15,22};
int *pointer = num;//指向数组的指针
printf("*pointer:%d\n",*pointer);//指针指向1
pointer++;
printf("*pointer(p++):%d\n",*pointer); //指针指向3
++pointer;
printf("*pointer(++p):%d\n",*pointer);//指针指向6
--pointer;
printf("*pointer(--p):%d\n",*pointer);//指针回退,指向3
pointer--;
printf("*pointer(p--):%d\n",*pointer);//指针回退指向1
pointer = num;
pointer+=4;
printf("*pointer(p+4):%d\n",*pointer);//指针加了四个类型字节的长度,指向10
pointer-=2;
printf("*pointer(p-2):%d\n",*pointer);//指针回退两个存储单元,指向6
//改变指针指向空间中的值
pointer = num;
printf("++pointer:%d\n",++(*pointer));//先取出指向的元素数值,然后再去做加加操作,然后输出
printf("pointer++:%d\n",(*pointer)++);//先取出指向的元素数值,然后输出,输出后再做加加操作,改变原来指向元素的数值
printf("num[0]:%d\n",num[0]);
//改变指针指向
pointer = num;
printf("*pointer++:%d\n",*pointer++);
printf("*(pointer++):%d\n",*(pointer++));
printf("*pointer:%d\n",*pointer);
return 0;
}
输出的结果为:
*pointer:1
*pointer(p++):3
*pointer(++p):6
*pointer(–p):3
*pointer(p–):1
*pointer(p+4):10
*pointer(p-2):6
++pointer:2
pointer++:2
num[0]:3
*pointer++:3
*(pointer++):3
*pointer:6
由此可以看出区分其结合性中的优先级。*与++都是右结合性的,因此在运算的时候都是从右边开始进行++的;注意在增减过后其指向的数值,或者指针的指向都是改变的
注意:在指针与++或–相结合的时候尽量是要用括号
指针的比较<一般没有多少意义>
前提条件:
前提都是两个指针都指向同一个数组中的元素,否则不同内存区域的指针是没有意义的。如果在数组中的话,可以通过指针来比较数组元素的大小
如:
int a = {1,2,3,4,5,6};
int *pointer = a;
int *pointer2 = a+4;
if((pointer)>((pointer2))){
//伪代码块
}
或者地址比较:
if(pointer > (pointer2 )){
//执行代码块
}
指针也可以来进行相减
int a = pointer2 - pointer;
算出来是指针所指向地址之间相差多少个存储单元(单位是存储单元)
因此a = 4,即相差4个存储单元
小弟因为是初学指针,有什么不对的地方,还请各位看官能够提醒,谢谢