C语言学习笔记17——数组与指针

指针的运算

指针与整数的运算规则:

  • 指针和整数可以进行运算, 其结果为指针

    • p + n <==> (unsigned int)p + n * sizeof(*p)

结论: 当指针 p 指向一个同类型的数组的元素时:

  • p + 1 将指向当前元素的下一个元素
  • p - 1 将指向当前元素的上一个元素
/* 测试代码 */

#include <stdio.h>

int main()
{
    int a[5] = {0};
    int* p = NULL;

    printf("a = 0x%X\n", (unsigned int)(a));
    printf("a + 1 = 0x%X\n", (unsigned int)(a + 1));  // a + 1 == 0x22FF18 + 1 * sizeof(int) == 0x22FF18 + 1 * 4 == 0x22FF1C

    printf("p = 0x%X\n", (unsigned int)(p));
    printf("p + 1 = 0x%X\n", (unsigned int)(p + 1));

    return 0;
}

运行结果

a = 0x22FF18
a + 1 = 0x22FF1C
p = 0x0
p + 1 = 0x4

指针与指针之间的运算规则:

  • 指针之间只支持减法运算

  • 参与减法运算的指针类型必须相同

  • p1 - p2 <==> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type)

注意:

  1. 只有当两个指针指向同一个数组中的元素时, 指针相减才有意义, 其意义为指针所指元素的下标差

  2. 当两个指针指向的元素不在同一个数组中时, 结果未定义

/* 测试代码 */

#include <stdio.h>

int main()
{
    int i = 0;
    char s1[] = {'H', 'e', 'l', 'l', 'o'};
    char s2[] = {'W', 'o', 'r', 'l', 'd'};

    char* p0 = s1;
    char* p1 = &s1[3];
    char* p2 = s2;
    int* p = &i;

    printf("%d\n", p0 - p1);     // -3
    printf("%d\n", p0 + p2);     // error
    printf("%d\n", p0 - p2);     // (C语言未定义, 不同编译器不同实现)
    printf("%d\n", p0 - p);      // error
    printf("%d\n", p0 * p2);     // error
    printf("%d\n", p0 / p2);     // error

    return 0;
}

指针的比较

  • 指针可可以进行关系运算 ( <, <=, >, >= )

  • 指针关系运算的前提是**同时指向同一个数组中的元素

  • 任意两个指针之间的 比较运算(==, != )无限制

  • 参与比较运算的指针类型必须相同


数组的访问方式

  • 下标的形式访问数组中的元素
int main()
{
    int a[5] = {0};

    a[1] = 3;
    a[2] = 5;

    return 0
}
  • 指针的形式访问数组中的元素
int main()
{
    int a[5] = {0};

    *(a + 1) = 3;
    *(a + 2) = 5;

    return 0;
}
  • 下标形式 vs 指针形式

    • 以固定增量在数组中移动时, 指针效率高于下标形式

    • 下标形式与指针形式的转换

      • a[n] <⇒ (a + n) <==> (n + a) <==> n[a]

注:现代编译器中, 在固定增量时, 下标形式的效率已经和指针形式相当。从可读性和代码维护的角度来看, 下标形式更优


a 和 &a 的区别

  • a 为数组首元素的地址

  • &a 为整个数组的地址

  • a 和 &a 的区别在于指针运算

    • a + 1 ===> (unsigned int) a + sizeof(*a)

    • &a + 1 ===> (unsigned int)(&a) + sizeof(*&a) ===> (unsigned int)(&a) + sizeof(a)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值