C语言学习_指针

本文详细介绍了C语言中指针的概念、使用方法,包括地址运算符、不同类型指针的处理、数组与指针的关系,以及动态内存分配和内存管理的最佳实践。重点讲解了如何通过指针交换变量值、函数参数传递和指针类型转换等内容。
摘要由CSDN通过智能技术生成

C语言学习

指针

  • 运算符&

    • eg:scanf("%d",&i);
    • 获取变量的地址,它的操作数必须是变量
      • int i;printf("%x",&i);
    • 地址的打算小是否与int取决于编译器
      • int i;printf("%p",&i);取地址用 %p
    • &不能对没有地址的东西取地址
      • &(a+b)
      • &(a++)
      • &(++a)
    • 相邻变量的地址,地址差一个变量类型字节大小,即相邻的变量是紧密存储的,C语言内存分配是从上向下分配,自顶向下。
    • 对数组取地址

      结果为:
      结果
  • 指针就是保存地址的变量int i;int *p=&i;

    • 指针变量
      • 变量的值就是内存的地址
        • 普通变量的值是实际的值
        • 指针变量的值是具有实际值的变量的地址
    • 作为参数的指针void f(int *p);
      • 在被调用时,得到了某个变量的地址:int i=0;f(&i)
      • 在函数里面可以通过这个指针访问外面的i,即可以在函数内改变i的值
        • *是一个单目运算符,用来访问指针的值所表示的地址上的变量
        • 可以做右值也可以做左值int k=*p;*p=k+1;
        • *p当作整体其实就是一个值
  • 指针的运算符&*

    • 相互反作用
      • *& yptr -> *(&yptr) -> *(yptr的地址) -> 得到那个地址上的变量 -> yptr
      • &* yptr -> &(*yptr) -> &(y) -> 得到y的地址,也就是yptr -> yptr
  • 指针的应用

    • 交换两个变量的值交换两个变量的值
      交换两个变量的值交换两个变量的值

    • 函数返回多个值,某些值只能通过指针返回

      • 传入的参数实际上是需要保存带回的结果的变量
        传入的参数实际上是需要保存带回的结果的变量
      • 结果为min=1,max=55
    • 函数需要返回状态和值,值通过指针返回

      • 函数return状态,结果通过指针返回状态
        结果通过指针返回状态
  • 指针常见错误

    • 定义了指针变量,还没有指向任何变量,就开始使用指针
      • int *p;*p=12;会出错
  • 指针与数组

    • 传入函数的数组其实是指针 函数传参的int a[] = int *a
    • 数组变量是特殊的指针
      • 数组变量本身表达地址
        • int a[10]; int *p = a;无需采用&取地址
        • a == &a[0];但数组的单元表达的是变量,需要用&取地址
      • []运算符可以对数组做,也可以对指针做
        • p[0] <==> a[0]
      • *运算符可以对数组做,也可以对指针做
        • *a = 25;
      • 数组变量是const的指针,所以不能被赋值
  • 指针与const

    • 指针是const
      • 一但得到某个变量的地址,不能再指向其他变量
        • int *const q = &i;//q是const
        • *q = 26;//OK
        • q++;//ERROR
    • 所指是const
      • 不能通过指针去修改那个变量(并不能使那个变量成为const)
        • const int *p = &i;
        • *p = 26;//ERROR (*p是const)
        • i = 26;//OK
        • p = &j;//OK
    • const int *p1 = &i; <==> int const *p2 = &i;均为所指为const,即*p为const
    • int *const p3 = &i;指针为const,不能被修改
    • const数组
      • const int a[] = {1,2,3,5,8};
      • 数组变量已经是const指针,这里const指数组内每个元素都是const int
      • 所以必须在初始化时赋值,否则就不能赋值了
    • 保护数组值
      • 因为数组传入函数时,传的是地址,所以函数内部可以修改数组的值
      • 为了保护数组不被函数修改破坏,可以设置参数为const
        • int sum(const int a[],int len);
  • 指针运算

    • 对指针+1,其实是在地址上加一个数据类型的sizeof,即指向下一个元素
      • *p --> a[0];*(p+1) --> a[1]
      • 只有连续的元素(数组),这样+1才是有意义的
      • 包括 -,++,--
    • *p++
      • 取出p所指的数据来,完事之后顺便把p移到下一个位置
      • *的优先级虽然高,但没有++优先级高
      • 常用于数组类的连续空间操作(遍历)常用于数组类的连续空间操作(遍历)
  • 指针比较

    • <,>,<=,>=,==,!=都可以对指针做
    • 比较它们在内存中的地址
    • 数组中的单元的地址肯定是线性递增的
  • 不同类型指针

    • 不论指向什么类型,所有指针大小都相同,因为都是地址
    • 但指向不同类型的指针是不能直接相互赋值的
  • 指针的类型转换

    • void*表示不知道指向什么东西的指针
      • 计算时与char*相同(但不相通)
    • 指针也可以转换类型
      • int *p = &i;void *q = (void*)p;
      • 并没有改变p所指的变量类型,而是让后人用不同眼光通过p看到它所指的变量,不再是int,而是void,p去看i是int,q去看i是void
  • 动态申请内存

    • int *a = (int *)malloc(n*sizeof(int));
      • 要使用malloc需要引入#include <stdlib.h>
      • 用完需要free(a)
        • 申请的都要还,并且最终都要还
        • 只能还申请来的空间首地址
        • 常见问题
          • 申请了没free,导致内存逐渐下降
            • 忘了
            • 找不到合适时机进行free
            • 已经free,继续free
            • 地址变过了,直接去free
      • 向malloc申请的空间大小是以字节为单位的
      • 返回结果是void*,需要类型转换为自己需要的类型
        • (int*)malloc(n*sizeof(int))
      • 若系统没空间了,会返回0/NULL
        补充:32位架构:int -> 4字节 地址 -> 4字节(sizeof(&i))
        64位架构:int -> 4字节 地址 -> 8字节(sizeof(&i))
  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值