深入理解指针_1_指针运算

在这里插入图片描述

1.指针±整数
2.指针-指针
3.指针的关系运算

1.指针±整数:

#include<stdio.h>
int main()
{
  int arr[10]={1,2,3,4,5,6,7,8,9,10};
  int* p=&arr[0]
}

在x86环境下,先来看看这段代码中数组元素的存储情况:
在这里插入图片描述
可以看出每个元素的地址相差4个字节,一个字节可以存两个“字”
数组元素在内存中是连续存放的,且随着元素编号增大,地址升高,只要知道一个元素的内存,就可以推出其他元素的内存地址

在这里插入图片描述
例如:第一个字节(01)的地址是 0x007EF89C ; 第二个字节 00 的地址就是:0x007EF89D ; 第三个:0x007EF89E…

p+n 中, n 的意义是:一个指针指向对象的字符类型所占的字节数,p+n表示跳过数组中 n 个元素

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0;i < sz;i++)
	{
		printf("%d ", *(p + i));
	}
}

在这里插入图片描述

注意事项:
arr[0]是访问的起始点,处于第一个箭头位置
p+2便跳到了第三个元素起始位置,如第二个箭头所示,要访问第三个元素
所以,当箭头指在某个元素地址起始位置是,这个元素也会被访问
这里对于判断for中限定 i 的大小有用
在这里插入图片描述

2.指针 - 指针(只能减,不能加)

#include<stdio.h>
int main()
{
  int arr[10]={1,2,3,4,5,6,7,8,9,10};
  int* p1=&arr[9];
  int* p2=&arr[0];
  int ret=p1-p2;
  printf( "%d\n",ret);
} 

运行结果:
在这里插入图片描述
指针减指针的结果是两个地址间的元素个数
注意:只有指向同一块的指针变量才能相减因为俩数组之间到底地址差多远谁知道
比如:

int arr1[5]=0;
int arr2[]="abcde" 
char* p1=&arr2[0];
int*  p2=&arr1[4];
//p1和p2不能相减

那为啥是 9 不是 10呢?
1.
在这里插入图片描述
上面说过,arr[9]的位置在第10个元素起始位置
两个箭头间已经跨过了 9 个元素
所以两指针间的元素个数是 9

2.
&arr[0] + 9 = &arr[9]
也能理解为什么是 9

当然以上代码,也能反着减
在这里插入图片描述

指针相减的另一个例子:

1.写一个函数,能实现与strlen()相同的作用:

#include<stdio.h>
int my_strlen(char* str)
{
  int count=0;
  while(*str!='\0')
  { 
    count++;
    str++;
  }
  return count;
}
int main()
{
  char arr[]="abcde";
  my_strlen(arr);//用数组名直接传参默认传的是第一个元素的地址
  printf("%d\n",  my_strlen(arr));
  return 0;
}

在这里插入图片描述

my_strlen函数也可以这样写:

int my_strlen(char* str)
{
 int* start=str;
 while(*str!='\0')
 {
  str++;
 }
 return str-start;
}

3.指针的关系运算:

关系运算,即指针比较大小

例:
打印一个数组中的全部元素,用指针

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;//直接用数组名表示首元素的地址
	while (p <= arr + sz - 1)//直接用数组名表示首元素的地址
	{
		printf("%d ", *p);
		p++;
	}
}
//也可以写成: while(p<arr+sz)

在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值