10-01指针
1.概念
内存单元的编号也叫地址,根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地址称为【指针】
内存单元的指针和内存单元的内容是两个不同的概念。
2.使用指针的好处
a.为函数提供修改调用变量的灵活手段
b.可以改善某些子程序的效率
在数据传递时,如果数据块较大(比如说数据缓冲区或比较大的结构),这时就可以使用指针传递地址而不是实际的数据,即提高传输速度,又节省大量内存。
c.让函数有多个返回值
d.为动态数据结构(如二叉树,链表)提供支持
3.变量的存取方式
存储方式分为两种:直接存取和间接存取
a.直接存取:变量的赋值和取值(通过变量名存取值)
b.间接存取:通过地址获取存储单元的值
4.指针变量
在C语言中,允许用一个变量来存放指针,这种变量称为指针变量,因此,一个指针变量的值就是某个内存单元的地址或称为某个内存单元的指针
注意:严格意义上说:指针就是一个地址,是一个常量
指针变量是存放一个地址,是一个变量
图中,变量就是一个指针变量,
5.定义一个指针变量
其一般形式为:
类型说明符 *变量名;
例如:
<span style="font-size:14px;">int *p;//定义了
一个指针变量,变量名是p, int表示,p只能存放一个int类型的变量的地址
char *o;//同理与int *p;</span>
6.注意事项
- “*”必须有,如果没有,就相当于定义了一个普通变量
7.指针变量的初始化方法
Inta = 3;
Int* p = &a;
注意:指针变量不初始化的后果?
7.1指针变量如果进行初始化?指针变量应该用地址初始化
A.定义的同时进行初始化
1)完全初始化 int *p = &a;
2)部分初始化 int * p1 =&a, *p2;
p2= &a;
B.先定义后初始化
int*p;
p= NULL;
建议定义的时候就初始化
C.定义了一个变量,但是不知道只想谁
int *p =NULL;
7.2常见错误
A.int *p = 1000; //这样会有警告,因为指针变量存储的应该是一个地址而不是一个数,这样做法要杜绝
B.指针变量可以改变指向
例如
int a = 1,b=2;
int*p = &a;
int*p = &b;<span style="font-family: Calibri; font-size: 11pt;"> </span>
9.注意
地址在内存中占用8个字节
int a = 10;
int *p = &a;
printf("a = %ld\n", sizeof(a));
printf("p = %ld", sizeof(p));
打印结果:
a = 4
p = 8
10.使用指针交换两个变量的值
#include <stdio.h>
//不使用指针的交换函数
void swap(int a, int b){
int temp = a;
a = b;
b = temp;
}
//使用指针的交换函数
void swapByPointer(int * a, int * b){
int temp = *a;
*a = *b;
*b = temp;
}
int main(int argc, const char * argv[])
{
int A = 10;
int B = 123;
swap(A,B);
printf("After swap A = %d,B = %d\n", A,B);
swapByPointer(&A,&B);
printf("After swap by pointer A = %d,B =%d\n", A, B);
return 0;
}
打印结果:
After swap A = 10,B = 123After swap by pointer A = 123,B = 10
分析:因为不用指针的值传递只是把原变量的值拷贝了一份给函数,不会影响到原值。用指针做参数传递,是把变量的地址传递到函数,这样会改变原值。指针做参数传递可以实现函数返回多个值。
11.指针的常见应用场景
A.在函数中间接访问调用者中的变量
B.让函数返回多个值
12.二级指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量,也称为"多级指针"
例如:
int a = 10;
int *p = &a;
int **p2 = &p;
printf("a = %d", **p2);
打印结果
a = 10
例外我试过,其实int *p2 = p跟int **p2 = &p的效果是一样的
int a = 10;
int *p = &a;
int **p2 = &p;
int *p3 = p;
printf("*p2 = %d\n", *p2);
printf("*p3 = %d", p3);
打印结果:
*p3 = 1606416668
12.指针为什么要区分类型?
在同一个编译器下,所有指针变量占用的字节数都一样
例如
int a = 10;
char ch = 'a';
float b = 123.3f;
double c = 123.2;
int *pa =&a;
char *pch = &ch;
float *pb = &b;
double *pc = &c;
printf("int pointer size = %ld\n", sizeof(pa));
printf("char pointer size = %ld\n", sizeof(pch));
printf("float pointer size = %ld\n", sizeof(pb));
printf("double pointer size = %ld\n", sizeof(pc));
打印结果:
int pointer size = 8char pointer size = 8
float pointer size = 8
double pointer size = 8
那么为什么还要区分类型呢?
因为如果存储的是一个int类型的变量,值266,占用四个字节,取出来的时候是按照char型取的,而char型在内存中只占用一个字节,那么此时只会取一个字节,这样就会有预料不到的后果。