让我们一起来了解指针更深层次的内容!
一、二级指针(指针指向指针变量的地址)
<一>定义
二级指针是指向一级指针的指针
<二>使用
1.函数体想修改 函数体外 指针变量 指向空间里的值
2.指针数组传参, 数组名是指向第一个指针元素的二级指针
//打印举例
int a = 100;
int *p = NULL;
int **q = NULL;
p = &a; //取a的地址,赋给指针变量p。指针就指向了该地址对应的空间
q = &p;
//取指针变量p的地址,赋给二级指针,二级指针q就指向了 一级指针p指向的空间

//字符串常量打印
注意代码中的注释!!
#include <stdio.h>
void fun(char **pptmp)
{
*pptmp = "hello world";
//把字符串常量的首地址 赋值给 二级指针指向的空间,也就是指针p的空间,改变了二级指针的地址
return;
}
int main(void)
{
char *p = NULL;
fun(&p); //把指针变量的地址传给二级指针,二级指针就指向了p指向的空间
printf("p = %s\\n", p);
return 0;
}
二、void指针
表示内存地址,常用作函数传参、函数返回值
- 一般不用做运算 或 * 操作
- 传参时兼容不同的指针类型
- char* 、int*、doubel* 转换为 void*,需要强制类型转换
- void* 转换为 char* 、int*、doubel*,则不需要
三、volatile指针
- 常用来搭配指针或变量使用,表示变量或指针指向空间中的数据容易被改变
- 防止编译器优化代码,每次读写都是去内存取变量值
volatile int *p;
volatile int num;
四、数组指针、指针数组
<一>概念
数组指针 是 指针,指针指向整个数组
指针数组 是 数组, 数组中每个元素都是指针
<二>指针数组
- int *a[5] = {NULL}; //定义数组a,共5个元素,每个元素都是int*型,内存共40byte
- 字符型指针数组 操作 已经存在的字符串数组
- 一维字符型数组存放字符串,二维字符型数组存放字符串数组
- 指针操作字符串,指针数组操作字符串数组
//接收5个字符串,对其冒泡排序(从小到大)
#include<stdio.h>
#include<string.h>
int main(void)
{
char str[5][32] = {0};
char *pstr[5] = {str[0], str[1], str[2], str[3],str[4]}; //二级指针
char *tmp = NULL;
int i = 0;
int j = 0;
for(i = 0; i < 5; i++)
{
gets(pstr[i]);
}
for(j = 0; j < 5 – 1; j++)
{
for(i = 0; i < 4 – j; i++)
{
if(strcmp(pstr[i], pstr[i + 1]) > 0)
{
tmp = pstr[i];
pstr[i] = pstr[i + 1];
pstr[i + 1] = tmp;
}
}
}
for(i = 0; i < 5; i++)
{
printf("pstr[%d] = %s\\n",i, pstr[i]);
}
return 0;
}
<三>数组指针
int (*p) [5];
int a[5] = {1,2,3,4,5};
- 1.数组指针 是指针 指向一个数组
- 2.数组的数组名是指向第一个元素的指针
以下情况除外:
- sizeof(a) == 20 sizeof(int *) == 8;
- & a == int (*)[5];
- 3.对一维数组的数组名 & ,(首地址)值不变,类型升级为指向整个数组的指针
- 4.对数组指针 * ,首地址不变,类型降级为指向第一个元素的指针
<四>二维数组传参
二维数组的数组名是指向数组第一行的数组指针
int a[2][3] = {1, 2, 3, 4, 5, 6};
int *p = NULL;
int (*q)[3] = a; //数组a 的首地址 给数组指针,让数组指针指向数组a
p = &a[0][0]; //把数组第一个元素的地址给指针p, 让p指向地址对应的空间
p = a[0]; //第一行数组的首地址
p = *a; //第1个元素的首地址
第m行第n列元素的访问方式:
a[m][n]
*(a[m]+n) // —>*(a+m) + n
*(*(a+m)+n)
*(p+m*N+n) //第m行第n列元素的总偏移量,行数*定义时的总列数+列数
*(*(q+m)+n)
*(q[m]+n)
q[m][n]
<五>指针数组传参
#include<stdio.h>
#include <string.h>
void Input(char (*pstr)[32], int len)
{
int i = 0;
for(i = 0; i < len; i++)
{
gets(pstr[i]);
}
return ;
}
void Output(char (*pstr)[32], int len)
{
int i = 0;
for(i = 0; i < len ; i++)
{
printf("pstr[%d] = %s\\n", i , pstr[i]);
}
return ;
}
void Bubblesort(char (*pstr)[32], int len)
{
int i = 0;
int j = 0;
char tmp[32] = {0};
for(j = 0; j < len – 1; j++)
{
for(i = 0; i <len -1 – j; i++)
{
if(strcmp(pstr[i], pstr[i + 1]) < 0)
{
strcpy(tmp, pstr[i + 1]);
strcpy(pstr[i + 1], pstr[i]);
strcpy(pstr[i], tmp);
}
}
}
return ;
}
int main(void)
{
char str[5][32] = {0};
Input(str, 5);
Bubblesort(str, 5);
Output(str, 5);
return 0;
}






