目录
一、多重指针
int a = 10;
int* p = &a;
int** p2 = &pl;//int*是基类型
二、指针函数和函数指针
1)指针函数
指针型函数:是一个函数,只不过这个函数的返回值是指针。(本质是函数)
#include<stdio.h>
//返回值是一个指针。
int* fun()
{
int b = 20;
return &b;
}
int main()
{
int a = 10;
int* p = &a;
p = fun();
printf("%d", *p);//优化结果
printf("%d", *p);//变量b被释放了,拿到地址也没用
}
//符合语法但不符合逻辑
2)函数指针
函数指针变量:是一个指针变量,一个指向函数的指针变量。(本质是指针)
#include<stdio.h>
用typedef给函数指针取别名
//typedef int(*P)(int, int);//P是一个函数指针类型
int ADD(int x, int y)
{
return x + y;
}
int SUB(int x, int y)
{
return x - y;
}
int MUL(int x, int y)
{
return x * y;
}
//又叫回调函数
void fun(int(*P)(int, int), int x, int y)
{
printf("%d\n", P(x, y));
}
int main()
{
int a = 10, b = 20;
fun(SUB, 2, 6);//修改第一个参数来选择调用的函数
}
3)回调函数
回调函数:如果把函数的地址作为参数传递给另外一个函数,当这个指针变量被用来调用其所指向的函数时,就称这是回调函数。
三、指针常量与常量指针
1)指针常量
指针常量:就是指针的指向不能够改变的指针,也就是指针类型的常量,指针中存储的地址不可被改变(指向的地址上的值可以改变)。
定义的一般格式:int * const p
#include<stdio.h>
//const使...变成常量
int main()
{
//指针常量
int a = 10;
int* const p = &a;
int b = 20;
//p = &b; //p为指针常量不可以改变指向 *p可以改变地址上的值
*p = 20;
printf("%d", *p);
}
2)常量指针:
常量指针:就是指向常量的指针,也就是指针指向的地址内的值不可被改变,又被称为只读指针(指向的地址可以改变)。
定义的一般格式:int const *p或者const int * p
#include<stdio.h>
//const使...变成常量
void fun(int const* q)//常量指针可以保护实参不被函数修改
{
//*q = 10; //*q不可以修改实参
q = 20;
printf("%d\t", q);
}
int main()
{
//常量指针
int a = 10;
int const* p = &a; //int const *p或者const int * p都可以
int b = 30;
p = &b;//*p不可修改是常量 p可以修改是变量
fun(a);
printf("%d", a);
}
四、指针数组和数组指针
1)指针数组
指针数组:本质上是一个数组,数组中的每一个元素都是指针类型的,都可以指向对应数据类型地址。
定义的一般格式:数据类型*指针数组名【指针数组个数】
如:int* p[4]
#include<stdio.h>
#include<string.h>
int main()
{
int a = 1, b = 2, c = 3;
int* p1 = &a, p2 = &b, p3 = &c;
int* pArr[3] = { p1,p2,p3 };
printf("%d\n", *(pArr[1]));//为2
int arr[10] = { 1,2,3,4,5,6,7,8,9 };
int* p = arr + 6;
int* parr[2] = { p };
//输出7
printf("%d\t", *((*parr)-1));//6为arr[5] *(parr[0])为p=6
//解引用*(6-1) 则为arr[5]的值
//定义一个数组str,数组的元素类型是char*
char* str[4] =
{
"aaa",
"bbb",
"ccc",
"ddd"
};
for (int i = 0; i < 4; i++)
{
printf("%s\n", str[i]);//str中保存的是地址
}
}
2)数组指针
数组指针:本质上是一个指针,是一个用于指向地址的指针。
定义的一般格式:所指向的数组的数据类型(*指针变量名)【所指向数组的大小】
如:int arr[2][4]
int (*p)[4] //定义了一个整形数组指针p,用于指向列数为4的整型二维数组p=arr;
//将整型数组指针p指向二维数组arr
#include<stdio.h>
#include<string.h>
void fun(int (*p)[4]) // int p[][4] int ()*p[4] p是指针变量
//*p=arr[] []解引用
{
for (int i = 0; i < 2; i++)
{
for(int j=0;j<4;j++)
{
printf("%d\t", p[i][j]);//*((*p+i)+j)也可以
//(*p+i)代表p[i] 加j后再次解引用
}
}
//p++;//加了16字节
//输出6 在a[2][1]
printf("%d\t", *(*(p +1) +1));//*(p+1)指向第二层数组再加一之后解引用
//再加一之后解引用 代表往后一个元素
}
int main()
{
//int a = 10;
//int* p = a;
//printf("%d", *p);
/*char str[5] = { "bbbb"};
strcpy_s(str,5,"aaa");
printf("%s", str);*/
int* arr[2][4] ={1,2,3,4,5,6,7,8};
fun(arr);
}