2.2 指针的计算

1. 1 + 1 = 2?

给一个指针 加 1,表示要让指针指向下一个变量
如果指针不是指向一片连续分配的空间,这种运算没有意义

#include<stdio.h>

int main(void)
{
    // char 数组 
    char ac[] = {0, 1, 2, 3, 4, 5, 6};
    char *p = ac;

    printf("p=%p\n", p); // p=000000000022FE40
    printf("P+1=%p\n", p + 1); // P+1=000000000022FE41
    printf("sizeof(char)=%d\n", sizeof(char)); // sizeof(char)=1

    // int 数组 
    int ai[] = {1, 2, 3, 4, 5};
    int *q = ai;

    printf("q=%p\n", q); // q=000000000022FE10
    printf("q+1=%p\n", q + 1); // q+1=000000000022FE14
    printf("sizeof(int)=%d\n", sizeof(int)); // sizeof(int)=4
    printf("*(q+1)=%d\n", *(q + 1)); // *(q+1)=2 即 *(q + 1) = ai[1]

    return 0;
}

2. 指针的算术运算

可以给指针 加 减一个整数、递增(++)、递减(–)、两个指针相减

#include<stdio.h>

int main(void)
{
    char ac[] = {0, 1, 2, 3, 4, 5, 6, 7};
    char *p = &ac[0];
    char *p1 = &ac[5];

    printf("p =%p\n", p); // p =000000000022FE20
    printf("p+1=%p\n", p + 1); // p+1=000000000022FE21
    printf("p1-p=%d\n", p1-p); // p1-p=5


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

    printf("q =%p\n", q); // q =000000000022FE20
    printf("q6=%p\n", q6); // q6=000000000022FE38,十六进制 
    printf("q6-q=%d\n", q6-q); // q6-q=6

    return 0;
}

3. *p++

  • 先计算 ++,在计算 *
  • 取出 p 所指的那个数据,再将p移到下一个位置
  • 用于数组类的连续空间操作
  • 在某些CPU上,可以直接被翻译成一条汇编指令
#include<stdio.h>

int main(void)
{
    char ac[] = {0, 1, 2, 3, 4, 5, 6, -1};
    char *p = &ac[0];
    int i;
    for(i = 0; i < sizeof(ac)/sizeof(ac[0]); i++){
        printf("%d\n", ac[i]);
    }

    printf("-------------\n");

    // 假设 -1 表示结束
    while( *p != -1){
        printf("%d\n", *p++);
    }

    return 0;
}

这里写图片描述

4. 指针比较

<, <=, == , >, >=, != 都可以对指针做
可以比较在内存中的地址
数组中的单元的地址肯定是 现行递增的

5. 0地址

  • 0地址通常是不能随便碰的地址,所以你的指针不应该具有 0值
  • 可以用0地址来表示特殊的事:
    • 返回的指针是无效的
    • 指针没有被真正初始化
  • NULL是一个预定义的符号,表示0地址
    • 有的编译器不愿意用0来表示0地址

6.指针的类型

  • 无论指向什么类型,所有的指针的大小都是一样的,因为都是地址
  • 指向不同类型的指针 不能直接互相赋值,这是为了避免用错指针
#include<stdio.h>

int main(void)
{
    char ac[] = {0, 1, 2, 3, 4, 5, 6, -1};
    char *p = &ac[0];

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

//  q = p; //   [Error] cannot convert 'char*' to 'int*' in assignment

    return 0;
}

7. 指针的类型转换

  • void* 表示不知道指向什么东西的指针
  • 指针也可以转换类型
#include<stdio.h>

int main(void)
{
    int i = 5;
    int *p = &i;
    // 没有改变p所指的变量的类型,只是换了个看待p所指变量的方式
    // 不再当它是 int,认为是 void
    void* q = (void*)p; 

    return 0;
}

8.指针的用途

  • 需要传入比较大的数据时 用作参数
  • 传入数组后,对数组做操作
  • 函数返回不止一个结果,需要用函数来修改不止一个变量
  • 动态申请的内存

9. 动态分配内存

9.1 malloc

#include<stdlib.h>
void* malloc(size_t size);
  • malloc申请的空间的大小是以字节为单位的
  • 返回的类型是 void*,需要类型转换为 自己需要的类型,比如 (int*)malloc(n * sizeof(int))
  • 如果什么失败则返回0,或者叫做NULL

输入数据时,先告诉你个数n,再输入n个数字,要记录每个数据
C99可以用变量n做数组定义的大小,C99之前呢?用 int a = (int )malloc(n * sizeof(int));

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int number;
    int* a;
    printf("输入数量:");
    scanf("%d", &number);

    a = (int*)malloc(number * sizeof(int));
    int i;
    for(i = 0; i < number; i++){
        scanf("%d", &a[i]);
    }

    for(i = number - 1; i >= 0; i--){
        printf("%d ", a[i]);
    }

    free(a);


    return 0;
}
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    //你的系统能给你多大空间?
    void *p;
    int cnt = 0;
    while((p=malloc(100 * 1024 * 1024))) {
        cnt++;
    }

    printf("分配了%d00MB的空间\n", cnt); // 分配了10300MB的空间


    return 0;
}

9.2 free

  • 把申请得来的空间还给系统
  • 只能还申请来的空间的首地址

常见问题

  • 申请了没free,长时间运行内存逐渐下降
    • 新手:忘了
    • 老手:找不到合适的free的时机
  • free过了再free
  • 地址变了,直接去free
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值