1. 指针的分类
按照指针指向的数据类型进行分类
可分为字符型指针、短整型指针、整形指针、长整型指针、浮点型指针、double型指针
char ch = 'y';
char *pch = &ch;//字符型指针
short s = 10;
short *ps = &s;//短型指针
int a = 10;
int *pa = &a;//整型指针
long long l = 10;
long long *pl = &l;//长整型指针
float f = 10;
float *pf = &f;//浮点型指针
double d = 10;
double *pd = &d; //double型指针
函数指针,本质是一个指针,是指向函数的指针
指针函数,本质是一个函数,函数的返回值是一个指针
结构体指针,本质是一个指针,指向一个结构体的指针
指针的指针,是指向指针的指针,是一个二级指针
数组指针,本质是一个指针,表示指向数组的指针
指针数组,本质是一个数组,数组中的每一个元素都是指针
指针地址的自增自减和数据类型有关,该指针的数据类型是什么,增加的地址量就是该数据类型的大小的个数
2. 指针和变量的关系
指针可以存放变量的地址编号,之前不能用函数将两个数交换,学了指针就完成这一工作
#include<stdio.h>
int swap(int *pa, int *pb);
int main()
{
int a = 10;
int b = 20;
printf("交换前%d, %d\n", a, b);
swap(&a, &b);
printf("交换后%d, %d\n", a, b);
return 0;
}
int swap(int *pa, int *pb)
{
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
return 0;
}
函数的形参传不回来,但是指针可以一直指向那个值,并传递回来
3. 字节序
字节序,又称端序或尾序,在计算机领域中,指电脑内存中或在数字通信链路中,占用多个字节的数据字节排列顺序
字节的排列方式又两种:大端序,小端序
大端序是指将数据的低位放在内存的高地址位,高位放在低位,这种方式就相当于从上至下将数据的位序顺序存储,而小端序和这个正好相反
我们可以测试电脑是大端序还是小端序
#include<stdio.h>
int main()
{
int a = 0x12345678;
int b = 0x78563412;
short *pa, *pb;
pa = (short *)&a;
pb = (short *)&b;
printf("%p, %p\n", &pa, &pb);
printf("%x, %x\n", *pa, *pb);
*pa++;
*pb++;
printf("%p, %p\n", &pa, &pb);
printf("%x, %x\n", *pa, *pb);
return 0;
}
可以看出我的电脑是大端序
注:
*p的取值,由指针类型所决定,例如字符型就是一个字节
p++指向下一个对应类型的数据
4. 指针与数组元素之间的关系
指针可以指向数组的数组名,意为指向数组的第一个值的地址
int a[10];
int *p = a;
其实数组名也是一个地址(指针),在后面可以和p代换
for(int i = 0; i < 10; i++)
{
printf("%d\n", a[i]);
printf("%d\n", p[i]);
printf("%d\n", *(a + i));
printf("%d\n", *(p + i));//取值
printf("%p\n", &a[i]);
printf("%p\n", &p[i]);
printf("%p\n", a + i);
printf("%p\n", p + i);//取地址
}
我们遍历一个数组的时候,a[i]和p[i]都代表数组中第i个元素,*(p + i),*(a + i)代表数组的后i个元素,也可以将值输出出来,取地址,和这个也类似
但要注意的是p和a是有不同的,p是一个指针变量,而a是一个常量,a不可以赋值,但是可以给p赋值
练习:通过swap函数和指针,将输入的三个数,从小到大输出
#include<stdio.h>
float swap(float *pa, float *pb)
{
float temp;
temp = *pa;
*pa = *pb;
*pb = temp;
return 0;
}
int main()
{
float a, b, c;
printf("请输入三个小数:\n");
scanf("%f%f%f", &a, &b, &c);
if(a > b)
{
swap(&a, &b);
if(b > c)
{
swap(&b, &c);
}
if(a > b)
{
swap(&a, &b);
}
}
else
{
if(b > c)
{
swap(&b, &c);
}
if(a > b)
{
swap(&a, &b);
}
}
printf("a = %.1f, b = %.1f, c = %.1f", a, b, c);
return 0;
}
和之前做过比大小输出的类似,这回直接用swap函数将两个值替换,发现有个函数,代码量是真的会减少很多
5. 指针的运算
指针是可以加一个整数的,意为指向这个整数后的元素,结果还是个地址变量
但是一般这么做是没有什么意义的,只有在数组中加一个整数才有一个实际意义
指针也可以比较大小,但也是在数组中才有意义
两个指针也可以相互赋值,但是必须是两个类型相同的指针
6. 指针数组和数组指针
指针数组是一个存放指针的数组,其实可以用来和一个数组一一对应,然后用指针来操作数组
#include<stdio.h>
int main()
{
int *arr[5] = {NULL};
int brr[5] = {4396, 4936, 4399, 4639, 4369};
for(int i = 0; i < 5; i++)
{
arr[i] = &brr[i];
printf("%p\n", arr[i]);
printf("%d\n", *arr[i]);
}
return 0;
可已通过指针数组来将brr数组的值全部输出
数组指针本质上是一个指针,他可以指向一个二维数组,他后面跟的是这个二维数组的列,行是根据这个二维数组的变化而变化
#include<stdio.h>
int main()
{
//数组指针,指向一个数组的指针
int (*parr)[5] = {0};
int arr[3][5] = {{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15}};
parr = arr;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 5; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}
总结:
今天算是真正开始学习指针,还是有些绕,特别是指针的运算刚开始有些绕不清,但是后面慢慢熟悉了以后,就能看懂了,我觉得有了指针,就能更好地使用函数以及对数组操作