C语言指针

指针学习笔记(郝斌C语言课程)

目录

指针简介

指针的重要性

指针的定义

指针的分类


指针简介

  1. 内存是以字节(8位)为单元,不是以01位
  2. 地址:内存单元(字节)的编号
  3. 指针----地址:指针就是地址,地址就是指针
    int * p;//int * 是变量类型,p是变量名
    p = &i;//p用来保存变量地址(&是取地址符)
    *p == i;//*p是指p变量保存的地址对应的变量的值
  4. 指针变量是存放地址的变量
  5. 指针和指针变量是两个不同的概念(前者是地址;后者是变量)

通常我们叙述的时候会把指针变量简称指针,实际含义并不一样。

指针的重要性

  • 表示一些复杂的数据结构
  • 快速传递数据
  • 使函数返回一个以上的值(被调函数修改主调函数实参)
  • 能直接访问硬件
  • 能够方便的处理字符串
  • 是理解面向对象语言中引用的基础

指针的定义

  • 地址:内存单元的编号

        从零开始的非负整数

        范围:4G【0--4G-1】(32个地址线✖CPU8个位线)

  • 指针:指针就是地址

指针变量:存放内存单元编号(即地址)的变量

指针和指针变量是两个不同的概念(前者是地址;后者是变量)

通常我们叙述的时候会把指针变量简称指针,实际含义并不一样

指针的本质就是操作受限的非负整数(地址可以相减-,不能进行+*/

指针变量占几个字节?

32位:4字节(byte)首字节表示,长度由变量类型决定

64位:8字节(byte)

指针的分类

  1. 基本类型指针
  1. int * p;//int * 是变量类型,p是变量名
  2. int i;
  3. p = &i;//p用来保存变量地址(&是取地址符),p指向i
  4. *p == i;//*p是指p变量保存的地址对应的变量的值

常见错误:

给不属于该程序的内存空间修改值:在未给p赋值之前给*p赋值

不属于你控制单元的值不可读(读不出未初始化的垃圾值)

赋值时类型不一致

内存空间只释放一次就行了,不释放就会导致内存泄露(内存越来越少)

  1. 指针和数组
  1. 指针和一维数组

【一维数组名:】

int a[5];  // a是数组名,5是元素个数

一维数组名是一个指针常量

它存放的是一维数组第一个元素的地址(即是一个地址常量,不能赋值

printf("a = %p\n", a);

printf("&a[0] = %p\n", &a[0]);

//输出结果一样

【下标和指针的关系:】

如果p是一个指针变量,则

p[i]永远等价于*(p+i)

【确定一个一维数组(需要哪些参数)】

需要两个参数

数组的首地址(即数组名)+数组的长度len

【指针变量的运算:】

指针变量不能相加、相乘、相除。

当两个指针变量指向同一块连续空间中不同储存单元时可以相减。(元素个数)

  1. 多级指针
#include <stdio.h>

int main(void)
{
    int i = 10;
    int* p = &i;
    int** q = &p;
    int*** r = &q;

    return 0;
}
***r == i;
**q == i;
*p == i;

指针的指针;

专题:动态内存分配

  1. 传统数组的缺点
  • 数组长度必须事先制定,且只能是常整数,不能是变量

例:int b;int a[b]  // error

  • 传统形式定义的数组,其内存无法手动释放

        例:函数运行时分配的内存会一直存在,除非函数终止

  • 数组长度一旦定义,其长度不能改变,即不能在函数运行时扩充/缩小
  • A函数定义的数组仅在其运行时可以被其他函数使用。其他时候不行
  1. 为什么需要动态内存分配

        动态数组很好的解决了传统数组的缺陷(以上4个)

  1. 动态内存分配举例子_动态数组的构造
  • malloc函数的使用。malloc:memory(内存) allocate(分配)
  1. 需要头文件:malloc.h
  2. malloc函数只有一个int形的形参;
  3. (int*)malloc(4) 表示为其分配4个字节;
  4. malloc函数返回第一个字节的地址,(int*)强制类型转换决定地址类型(怎么划分,多长)。

malloc(100):

int*:25个、char*:100个……

  1. (int*)malloc(4)//总共分配了8个字节(32位):

        定义p变量4个字节(静态)+ 指向的内存4个字节(动态)

  1. free(p)  // 把p指向的内存释放掉
  2. realloc(p,100)  // 调整p指向空间大小为100字节

  • 数组长度一旦定义,其长度不能改变,即不能在函数运行时扩充/缩小

        realloc(p,100)//调整p指向空间大小为100字节

  • A函数定义的数组仅在其运行时可以被其他函数使用。其他时候不行

  1. 静态内存与动态内存比较

        (程序运行过程就是压栈与出栈)

静态

动态

分配方式

静态内存是由系统自动分配和释放

malloc、free函数(程序员)

形式

静态内存是在栈分配的

动态内存是在堆分配的

  1. 跨函数使用内存的问题

发送地址—修改值

静态分配的内存在函数运行结束时会自动释放,因此在其他函数无法使用

/*
错误的程序示范
访问了不属于其权限的内存空间,逻辑错误
f函数执行完时,i变量占用的内存空间已经被释放
不能在main函数中再去调用i
*/
#include <stdio.h>

void f(int ** q)
{
    int i = 5;
    *q = &i;

    return;
}

int main(void)
{
    int* p;

    f(&p);
    printf("%d", *p);//语法没有问题,但是逻辑有问题

    return 0;
}

动态配的内存可以跨函数使用

/*
正确示例
动态内存可以跨函数使用
*/
#include <stdio.h>
#include <malloc.h>

void f(int** q)
{
    *q = (int*)malloc(sizeof(int));
    **q = 5;
    return;
}

int main()
{
    int* p;

    f(&p);
    printf("%d\n", *p);

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值