指针
1 什么是指针?
指针是C语言的灵魂,指针就是地址,地址就是指针,指针变量就是就是存放内存单元编号的变量,或者说指针变量就是存放地址的变量,指针和指针变量是两个不同的概念,通常我们叙述时会吧指针变量简称为指针,实际指针的本质就是一个操作受限制的非负整数。
1.1 指针的重要性
- 表达一些复杂的数据结构
- 快速的传输数据
- 使函数返回一个以上的值
- 能直接访问硬件
- 能够方便的处理字符转
- 是理解面向对象语言中引用的基础
1.2什么是地址?
- 内存单元的编号
- 从零开始的非负整数
1.3 基本类型指针
- 定义指针:int * p;定义了一个整形指针变量p
- 对指针赋值:p = &i;将i的地址赋值给p,整形指针变量只
能存储整形数据的地址
- 对指针变量进行取值:*p表示取指针p指向的地址存储的数据,
本质上*p==i
1.5 例:互换两个数字
#include<stdio.h>
void jiaohuan(int *p,int *q){
int i = *p;
*p = *q;
*q = i;
}
int main(void)
{
int a = 10;
int b = 100;
jiaohuan(&a,&b);
printf("%d\n",a);
printf("%d\n",b);
return 0;
}
1.6 星号的含义
- 乘法
- 定义指针变量
- 指针取值运算符
2 指针拓展
2.1 指针与函数
2.1 通过被调函数函数修改主调函数
- 实参必须为该普通变量的地址
- 形参必须为普通变量
- 通过*p = …的方式修改主调函数相关变量的值
2.2 指针与一维数组
- 一维数组名:一维数组名是一个指针常量,存放一维数组第一个数的地址;
- 下标和指针的关系:如果p是一个数组名,则p[i]永远你等价于*(p+i);
- 指针变量的运算:指针变量不能相加,不能相除,不能相乘,当两个指针变量指向的是同一块连续空间中的不同存储单元,则这两个变量才可以相减
3 动态内存分配
3.1 传统数组的缺点
- 数组长度必须事先制定,且必须是常整数,不能是变量
- 传统函数定义的数组,该函数的内存程序员无法手动释放,数组一旦定义,系统为该数组分配的内存空间会一直存在,知道该函数运行完毕时,数组空间才会被释放
- 数组的长度不能在函数运行的过程中动态的扩充或缩小
- 不能跨函数使用
3.2 为什么需要动态分配内存
动态数组很好的解决了传统数组的缺陷,传统数组也叫静态数组
3.3 举例
/*
malloc是memory allocate 即内存分配的缩写
*/
#include<stdio.h>
#include<malloc.h>
int main(void)
{
int i = 5;//静态分配了四个字节
int *p = (int *)malloc(4);
//1. malloc函数在malloc.h头文件里
//2.malloc函数只有一个整形形参
//3.形参表示系统分配字节的大小
//4.malloc函数返回第一个字节的地址
//5.p变量占4字节,p指向的空间占4字节
//6.p所占的内存是静态的,指向的空间是动态的
free(p);//表示把p指向的内存释放掉
return 0;
}
3.4 动态一维数组
例: 动态创建一个长度为100的整形数组
int *p = (int *)malloc(100 * sizeof(int));
//p就是数组名,可以像静态数组一样使用
//sizeof是一个库函数,形参为变量类型,返回值为变量类型所占字节大小
//动态数组可以通过realloc扩充或缩小
3.5 静态内存和动态内存比较
静态内存
- 静态内存由系统自动分配,由系统自动释放
- 静态内存由栈分配,调用函数时压栈,函数执行完出栈,程序永远在栈顶执行
动态内存
- 动态内存由程序员手动分配,手动释放
- 动态内存是由堆分配
4 多级指针
n级指针是用来存放n-1级指针地址的变量,详见:百度:多级指针