23. 数组与指针分析

指针的运算

指针p+n等价于我们这个 指针所保存的地址的绝对值加上 n乘这个指针指向元素类型的大小
结论:
指针p指向一个同类型的数组的元素时: p+1将指向 当前元素的下一个元素; 
                                                                p-1将指向当前元素的上一 个元素。
#include <stdio.h>
int main()
{
    int a[5] = {0,1,2,3,4};
    printf("%0x\n%0x\n", a,a+1);
    return 0;
}
result:
        61fe00
        61fe04
指针之间 只支持减法运算 ,且必须参与运算的指针类型必 须相同
注意: 只有当 两个指针指向同一个数组中的元素时 ,指针 相减才有意义, 其意义为指针所指元素的下标差; 当两个指针指向的元素不在同一个数组中时, 结果 未定义
#include <stdio.h>
#include <malloc.h>
int main()
{
    char s1[] = {'H', 'e', 'l', 'l', 'o'};
    int i = 0;
    char s2[] = {'W', 'o', 'r', 'l', 'd'};
    char* p0 = s1;
    char* p1 = &s1[3]; //s[3]是数组的第四个元素
    char* p2 = s2;
    int* p = &i;
    printf("%d\n", p0 - p1);//两个指针定义在同一个数组中,OK,result:-3
    //printf("%d\n", p0 + p2);
    printf("%d\n", p0 - p2);//没有意义
    //printf("%d\n", p0 - p);
    //printf("%d\n", p0 * p2);
    //printf("%d\n", p0 / p2);
   
    return 0;
}

指针的比较

指针也可以进行关系运算    <         <=         >         >=
指针关系运算的前提是 同时指向同一个数组中的元素
任意两个指针之间的比较运算(==, !=)无限制(可以不是同一个数组)
#include <stdio.h>
#include <malloc.h>
#define DIM(a) (sizeof(a) / sizeof(*a))
int main()
{
    char s[] = {'H', 'e', 'l', 'l', 'o'};
    char* pBegin = s;
    char* pEnd = s + DIM(s);
    char* p = NULL;
    //用指针遍历一个数组
    for(p=pBegin; p<pEnd; p++)
    {
        printf("%c", *p);
    }
   
    printf("\n");
   
    return 0;
}

数组的访问

以下标的形式访问数组中的元素
以指针的形式访问数组中的元素

a和&a的区别

a为数组首元素的地址
&a为整个数组的地址
a和&a的意义不同其区别在于指针运算
数组名作为sizeof操作符的参数时不能将其看作常量指针
在C或C++中,对于数组 int a[5]; 和与之相关的几个表达式,使用 sizeof 运算符的结果会有所不同。让我们详细解释每个表达式的结果及其区别:
  1. sizeof(a);
    • 结果:整个数组  a  的大小,即  5 * sizeof(int)
    • 解释: a  在这个上下文中表示整个数组,所以  sizeof  返回整个数组占用的字节数。
  2. sizeof(&*a);
    • 结果:通常与  sizeof(int*)  相同,即指针的大小。
    • 解释: &a  取得数组  a  的地址(即指向整个数组的指针), *a  解引用这个地址得到数组的第一个元素。然后, &*a  再次取得这个元素的地址,这通常还是指向数组第一个元素的地址。因此, sizeof(&*a)  实际上是求一个指向  int  的指针的大小。
  3. sizeof(*&a);
    • 结果:与  sizeof(a)  相同,即整个数组  a  的大小。
    • 解释: &a  是指向整个数组的指针, *&a  解引用这个指针得到数组本身。由于  sizeof  对数组有特殊的处理规则, 它返回整个数组的大小,而不是解引用后得到的单个元素或指针的大小
  4. sizeof(&a);
    • 结果:指向整个数组  a  的指针的大小。
    • 解释: &a  是指向整个数组的指针,所以  sizeof(&a)  返回的是这种指针的大小,这通常与平台相关,但通常与指向单个元素的指针大小相同。
  5. sizeof(*a);
    • 结果:一个  int  类型的大小。
    • 解释: *a  是数组  a  的第一个元素的引用,所以  sizeof(*a)  等于  sizeof(int) ,即单个整数的大小。
总结:
  • sizeof(a)  和  sizeof(*&a)  都返回整个数组的大小。
  • sizeof(&*a)  和  sizeof(int*)  通常返回指向  int  的指针的大小。
  • sizeof(&a)  返回指向整个数组的指针的大小。
  • sizeof(*a)  返回单个  int  类型的大小。
关键点在于理解 sizeof 对数组的特殊处理规则 sizeof 直接作用于数组名时,它返回整个数组的大小,而不是解引用后得到的单个元素或指针的大小。同时,要注意数组名在大多数情况下会退化为指向其第一个元素的指针,但在 sizeof 的上下文中是个例外。

指针运算经典问题

Motorola面试题
#include <stdio.h>
int main()
{
    int a[5] = {1, 2, 3, 4, 5};
    int* p1 = (int*)(&a + 1);
    int* p2 = (int*)((int)a + 1);
    int* p3 = (int*)(a + 1);
   
    printf("%d, %d, %d\n", p1[-1], p2[0], p3[1]);
   
    return 0;
}
result:  5, 33554432, 3

数组参数

C语言中,数组作为函数参数时,编译器将 其编译成对应的指针
一般情况下,当定义的函数中有数组参数时, 需要定 义另一个参数来标示数组的大小。

指针和数组的对比

数组声明时 编译器 自动分配 一片连续内存空间
指针声明时 只分配了 用于容纳指针的4字节空间
在作为函数参数时, 数组参数指针参数  等价
数组名多数情况(sizeof、&作用下除外)可以看做 常量指针,其值不能改变
指针的本质是变量,保存的值被看做内存中的地址值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值