《指针运算》

文章详细介绍了指针运算中的指针与整数、指针与指针的相减概念,展示了如何用指针实现strlen函数,并讨论了指针相加的含义。同时,提到了数组初始化时的指针注意事项,遵循标准规定避免潜在问题。

指针运算

一、指针+-整数

int a=5;

float  arr[a];

float *p;

for(p=&arr[0];p<&arr[5];)

{

        *p++=0;//   *p=0   p++

}

二、指针-指针

指针与指针之间是可以相减的

int arr[10]={0};

printf("%d",(&arr[9] - &arr[0]));

打印的结果是9,(中间有9个元素)

指针减去指针,得到的是指针与指针之间元素的个数,高指针减去低指针就是正数,低指针减去高指针指针得到的就是负数。

但不是所有指针之间都能相减,指向同一块内存的指针相减才有意义

int arr[10]=[0];

char arr2[10]=[0];

printf("%d",(&arr[9] - &arr2[0]));  //这种写法本质上是没有意义的

那么借助指针相减的这个性质,我们可以利用指针相减来进行一些功能,比如我们可以实现strlen函数的功能

int len = my_strlen("abcdef");   这个len中存放的是a  b  c  d  e f  \0

这是使用指针实现的函数

int my_strlen(char*  str)

{

    int  count =0;

    while(*str !='\0' )

    {

        count++;

        str++;

    }

    return count;

}

这是一个用指针相减的办法来实现函数

int my_strlen(char*  str)

{

    char* strat = str;

    while(*str !='\0')

    {

        str++;

    }

    return (str -start);

}

那指针能不能相加呢?

其实这是没意义的,指针的本质是地址,地址减去地址可以推算出两个地址的距离,但是地址加地址没有实际的意义。就像是计算距离某个节日还剩多少天,我可以让莫某个节日是某月30日减去我今天的3日得出还剩27天,但是相加就没有什么实际的意义。

我们再来看指针初始化数组的这样一个代码

int arr[5];

int *p;

for(p = &arr[5];p>&arr[0])

{

    *--p = 0;

}

按照我们做开始学习的for语句的模板,我们也可以把这个代码写作这样

for(p=&arr[4];p>=&arr[0];p--)

{

    *p=0;

}

感觉这个代码比较容易理解

上述这串代码在绝大多数的编译器上都是可以运行的,但是我们应该避免这样子写,因为标准并不保证它可行。

标准规定,允许指向数组元素的指针与指向数组最后一个元素后面呢那个内存位置的比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

意思是,标准指向数组的指针与最后的元素的后面那个指针比较,但是不允许与第一个元素之前的那个指针比较。

这里我们用图来解释一下,标准允许指向这个数组的指针与p2进行比较,但不允许与p3进行比较。

### 关于指针运算 在C/C++中,指针运算是非常重要的概念之一。通过指针可以访问内存中的不同位置,并执行各种操作。 #### 指针算术运算 当对指针应用加法或减法时,编译器会自动考虑数据类型的大小[^1]。例如: - 如果 `ptr` 是指向整型变量的指针,则表达式 `ptr + 1` 实际上会使该指针前进到下一个整数的位置。 ```c++ int numbers[] = {1, 2, 3}; int *ptr = &numbers[0]; // ptr现在指向数组的第一个元素 ptr++; // ptr现在指向数组的第二个元素 ``` 对于不同的基本类型,每次增加或减少的数量也有所不同。比如浮点数占用四个字节,在这种情况下移动一个单位意味着跳过这四字节的空间;而对于双精度浮点数来说则是八个字节等等[^4]。 #### 数组与指针的关系 在很多方面,数组名可以用作指向其首个成员的常量指针来处理。因此可以通过索引来获取特定位置上的值或者使用偏移量来进行遍历。 ```c++ char str[] = "Hello"; for (char* p = str; *p != '\0'; ++p){ putchar(*p); } puts(""); ``` 这段代码展示了如何利用指针遍历整个字符串并打印出来。这里`str`实际上就是指向字符序列起始处的一个指针。 #### 函数参数传递中的指针 除了作为独立的数据项外,指针还经常被用来向函数传递复杂结构体或其他大型对象而无需复制它们的内容。这样不仅可以提高效率还可以简化接口设计。 ```cpp void swap(int& a,int& b){ int temp=a; a=b; b=temp; } // 或者更常见的是使用指针形式 void swap_ptr(int* pa, int* pb) { int temp=*pa; *pa=*pb; *pb=temp; } ``` 上述例子说明了两种方法都可以达到交换两个数值的效果,但是后者更加直观地体现了底层机制的工作原理。 #### 安全性和注意事项 尽管灵活强大,但不当使用的后果可能很严重——容易引发未定义行为甚至安全漏洞。所以在实际开发过程中应当格外小心谨慎对待每一个涉及指针的操作[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值