指针:
可以有效地表示复杂的数据结构; //下一个阶段 数据结构
能动态分配内存; //指针 提供了一个能力 --直接使用内存
方便地使用字符串;
有效而方便地使用数组;
在调用函数时能获得1个以上的结果;
能直接处理内存单元地址等
指针是啥?
计算机的内存是按字节进行编址的 --- 一个字节一个地址编号(地址)
地址 --- (通过地址信息 可以知道 想要目标)
看地址值 --- 本身也是一种数值
能不能像普通变量 也开一块空间 来存放这个值
引出 ---指针的概念
指针 (pointer) --- 指针 就是 地址 ,地址 就是 内存单元的编号
想要存储或处理指针这种数据,应该怎么办?
设计了一种数据类型 叫指针类型
int a = 10; //a是int类型
int 类型 ---- 这是一种整数类型 --可以用来处理整数这种数据 以及 相关运算
指针类型 ---- 这是一种数据类型 -- 可以用来处理 指针 这种数据 以及 相关运算
指针数据 和 整型数据区别?
房间编号 1000 数值 1000
内存单元编号 1000
[小结]
1.指针是啥?
指针 就是 地址 。地址就是内存单元编号
2.指针值 指针数据
就是内存单元编号(地址)
3.指针类型
专门处理 "地址(内存单元编号)" 这种数据
地址 不是一个单纯的数值 ,而是具有 地址含义 数值
---------------------------------------------------
语法:
定义一个指针类型的变量 //
定义指针变量的一般形式为
基类型 * 指针变量名;
(1) (2) (3)
说明:
(1)基类型 : 表示的是 指针(地址) 所指向的空间的 数据类型
(2) * : 定义指针变量时,只是用来说明该变量 是指针类型
(3)指针变量名: 就是一个标识符 和 普通变量的命名规则一致
eg:
int a = 10; //
int * p; //定义了一个指针变量p
//定义了一个指向int型数据的指针变量p
//定义了指针变量 意味着 也要开空间
空间开多大 --- 取决于 p对应的数据类型 --- p对应的数据类型 ---指针类型 int*
32位 系统 --- 对应地址大小 统一都是32位 --4个字节
64位 系统 --- 对应地址大小 统一都是64位 --8个字节
eg:
int a = 10;
int *p = &a;
&a 取地址运算 表示取到a所在空间的起始地址
对于a这块空间的使用?
有两种方式
1.直接通过a使用 --- 直接引用
2.间接引用 --- 指针的方式
int a = 10;
int *p = &a;
step1(找): 首先,通过p本身
可以得到 a所在空间的地址 //通过p本身 只是 能找到a
step2(用): 能不能用a所在的空间?
*运算数 ---- 指针运算符(解引用) ---运算数必须是地址
*p
运算过程:
//step1: 拿出p中地址编号,到内存中寻找 //找
//step2: 从定位处开始 偏移出sizeof(基类型)大小的一块空间 //用
//step3: 将偏移出的这块空间,当做一个基类型变量来看
*p <==运算结果==> 相当于是一个 int型变量
考点:
实现一个函数测试电脑大小端
为啥需要指针? --- 可以实现被调修改主调
int addOne(int *p)
{
*p = *p + 1;
//p = p + 1;
}
main()
{
int n = 10; //主调函数中 有一个变量 想在被调函数中对这个变量进行修改
addOne(&n);
}
// 可以实现被调修主调
什么是被调 --- 被调函数 ---被调用函数
什么是主调 --- 主动调用的函数
需要用到地址 (指针)
注意:
被调修改主调
1.要修改谁,就传谁的地址
2.在被调函数中,一定要有相应的*p运算
传地址的方式 --- 地址传参 (地址传递) ---- 可以实现被调修改主调
值传递
说明:
指针 80% 以上的用途都是来干这个事情的
include <time.h>
time_t time(time_t *tloc);
//方式1 通过返回值获得
time_t t = time(NULL);
//方式2 通过指针的形参
time_t t;
time(&t);
练习:
实现两个数求和
指针 操作 数组
数组:
整型 一维
int a[10] = {1,2,3,4,5,6,8,9,10}; //
数组特点:
1.连续性
2.单一性 <--类型一致
3.有序性 <--按顺序存放
//通过指针 操作 数组
定义什么类型的指针?
谁能代表数组所在空间起始位置?
数组名
从值的的角度 --数组名代表数组首元素的地址 ---首元素地址也是整个数组起始地址
知道了首元素地址--- 能不能访问首元素———能
int *p = a;
= &a[0]; // a[0] 是啥类型 --- 是int类型
//&a[0] 取了一个存放int型数据空间的地址 // int *
指针运算:
p + 1 //表示地址 加了 一个基类型大小
p + N //表示地址 加了 N个基类型大小
p - 1 //表示地址 减了 一个基类型大小
p - N //表示地址 减了 N个基类型大小
p ++
p --
p-q //必须是同类型指针 表示 差了几个基类型
关系运算:
> >= < <= == !=
p > q //地址编号 编号大的 就大
指针操作数组
1.因为数组的特点
只需要知道首元素地址即可
2.指针运算
p+N
3.指针 * 运算
p+i => 第i个元素的地址 i可以是 0 1 2 ...
*(p+i)=> 第i个元素(变量) 等价于 a[i]
a[i] <=> *(p+i)
a[i] <=> *(a+i)