流心
发布于 2024-05-10 / 1 阅读
0

指针运算

指针加减法

 #include<stdio.h>
 int main(void)
 {
    char ac[] = {0,1,2,3,4,5,6,7,8,9,};
    char *p = ac[0];
    char *p1 = ac[5];
    printf("p = %p\n",p);   // p = 000000000061FE0E
    printf("p+1=%p\n",p+1);     // p+1=000000000061FE0F 16进制 +1 就是 F
    
    printf("p1-p=%d\n",p1-p);   // p1-p=5

    int ai[] = {0,1,2,3,4,5,6,7,8,9,};
    int *q = ac[0];
    int *q1 = ac[5];
    printf("q = %p\n",q);   // 000000000061FE06
    printf("q+1=%p\n",q+1);    // 000000000061FE0A 16进制 +4 6+1应该等于7结果却是A(10)

    printf("q1-q=%d\n",q1-q);   // q1-q=1

    /**
     * 指针加法
     * p运算加一并不是在地址值上面+1,而是 sizeof + 1
     * sizeof给出单前类型的字节数
     * 
     */

    /**
     * 指针减法
     * 减两个指针的时候,得出结果不是两个指针地址的差,而是两个地址差除以 sizeof 类型 得出的是在这两个地址中有几个这种类型的,或者能放几个这种类型
     * 
     */

    return 0; 
    
 }
  • 指针加法

    • p运算加一并不是在地址值上面+1,而是 sizeof + 1sizeof 给出当前类型的字节数

  • 指针减法

    • 减两个指针的时候,得出结果不是两个指针地址的差,而是两个地址差除以 sizeof 类型 得出的是在这两个地址中有几个这种类型的,或者能放几个这种类型

  • 指针也可以像数组一样操作

    • *p -> ac[0]

    • *(p+1) -> ac[1])

  • 因为 * 是运算符而且比 + 优先级高所以加括号

  • 如果指针不是指向一片连续分配的空间,如数组,则这种运算没有意义

  • 当 *p 指向 ac[] 的时候 *(p+n) 就跟 ac[n] 一样了

  • 指针可以 加、减一个整数(+,+=,-,-=),+ 是将当前位置往后挪,-就是将当前位置往前挪

  • 递增递减(++/--)

  • *p++

  • 取出 p 所指的那个数据,顺便把 p 移到下一个位置

  • * 的优先级没有 ++ 高

  • 常用于数组类的连续空间操作

  • 在某些 CPU 上,可以被翻译成汇编指令

 #include<stdio.h>
 int main(void)
 {
    char ac[] = {0,1,2,3,4,5,6,7,8,9,-1};
    char *p = &ac[0];
    int i;
    // 传统写法
    for ( i = 0; i < sizeof(ac)/sizeof(ac[0]); i++)
    {
        printf("%d\n",ac[i]);
    }
    // 便捷写法
    for ( p = ac; *p != -1; i++)
    {
         printf("%d\n",*p);
    }
    
    while(*p != -1){
         printf("%d\n",*p++);
    }

    int ai[] = {0,1,2,3,4,5,6,7,8,9,};
    int *q = ai;

    return 0; 
    
 }

指针比较

  • <.<=,==,>,>=,!= 都可以做比较

  • 比较它们在内存中的地址

  • 数组中单元的地址肯定是线性递增的

0地址

  • 你的内存中有0地址,但是0地址通常是个不能随便碰的地址

  • 所以你的指针不应该具有0值

  • 因此可以用0地址来表示特殊的事情:

    • 返回的指针是无效的

    • 指针没有被真正初始化(先初始化为0)

  • NULL是一个预定定义的符号,表示0地址

    • 有的编译器不愿意你用0来表示0地址

指针的类型

  • 无论指向什么类型,所有的指针大小都是一样的,都是地址

  • 但是指向不同类型的指针是不能直接相互赋值的

  • 避免用错指针

指针的类型转换

  • void* 表示不知道指向什么东西的指针

    • 计算时和 char* 相同(不相通)

  • 指针也可以转换类型

    • int p = &i ; void q = (void*) p ;

  • 这不会改变 p 指向的变量类型,而是通过不同眼光看 p 它指向的变量

    • 我不把它当 int 我认为它就是 void

指针的用处

  • 需要传入较大的数据时用作参数

  • 传入数组后对数组做操作

  • 函数返回不止一个结果

  • 需要用函数来修改不止一个变量

  • 动态申请的内存…