关于指针
指针的重要性
- 能直接访问硬件
- 能够快速传递数据,减少内存的耗用
- 方便解决一些字符串的问题
- 能表示一些复杂的数据结构
- 是理解面向对象语言引用的一个基础
总结:指针是C语言的灵魂
指针是什么
- 指针是地址,地址是指针(地址是内存单元的编号,该编号是从0开始的非负整数)
- 指针是存储内存单元编号的变量,也是存储地址的变量
注意:指针和指针变量的概念不同,但我们会习惯将指针变量简称指针
指针的分类
- 基本类型指针
- 指针与数组
- 指针与函数
- 指针与结构体
- 多级指针
指针变量的运算
- 两个指针变量相加、相乘、相除都没有意义
- 只有两个指针变量指向同一块连续分配的不同存储单元,相减才有意义。所得值为这两个变量相隔存储单元的个数
指针变量的所占字节数
无论该指针变量指向的变量占多少个字节,它本身只占4个字节
重点:如何通过被调函数,修改主函数中普通变量的值
- 实参必须为普通变量的地址
- 形参必须是指针变量
- 通过修改*形参名的值来改变该普通变量的值
小习题1(通过函数互换两个数字的值)
# include <stdio.h>
void exchange (int* p, int* q)
{
int t;
t = *p;
//*p等价于a
*p = *q;
*q = t;
}
int main (void)
{
int a = 3, b = 5;
exchange (&a, &b);
printf ("a = %d, b = %d", a, b);
return 0;
}
//结果: a = 5, b = 3
小习题2 (通过函数将数组中的每个元素的值输出)
一维数组名是一个指针常量,它储存的是该一维数组首个元素的地址
# include <stdio.h>
void print (int* b, int len)
//b为数组名,len为数组的长度
{
int i;
for (i = 0; i < len; i++)
{
printf ("%d ", b[i]);
//parr[i]等价于*(parr+i),整个程序来看,相当于输出a[i]或*(a+i)
}
}
int main (void)
{
int a[3] = {1, 2 ,3};
print (a, 3);
return 0;
}
//结果: 1 2 3
小习题3(通过函数修改数组元素的值)
# include <stdio.h>
void change (int* b)
{
b[1] = 9;
//等价于*(b+1) = 9,从整个程序来看,相当于令a[1]=9或*(a+1)=9
}
int main (void)
{
int a[3] = {1, 2, 3};
change (a);
//数组名a表示该数组首个元素a[0]的地址
printf ("a[1] = %d", a[1]);
return 0;
}
//结果:a[1] = 9
多级指针
int main (void)
{
int i = 5;
int* p = &i;
//p是int*类型的指针变量,所以p只能存放int类型变量的地址
int** q = &p;
//q是int**类型的指针变量,所以q只能存放int*类型变量的地址
int*** r = &q;
//r是int***类型的指针变量,所以r只能存放int**类型变量的地址
printf ("%d", ***r);
/*
因为*r等价于q, *q等价于p, *p等价于i
两边同时加*号
所以***r等价于**q等价于*p等价于i
故输出结果为5
*/
}