指针的定义与使用
1.指针的定义和使用
int point1(){//定义指针int a = 10;//指针定义语法: 数据类型 * 指针变量名int * p;cout << "sizeof (int(*)) --> " << sizeof(p) << endl;//让指针记录变量a的地址 & 取址符p = &a ;cout << "指针p为:" << p << endl;cout << "变量a的地址为:" << &a << endl;cout << "变量a的值为:" << a << endl;/*** 使用指针 通过<br>解引用</br>的方式来找到指针指向的内存* 指针前加 * 代表解引用,找到指针指向的内存中的地址*/*p = 500;int b = *p;cout << "变量b的值为:" << b << endl;cout << "变量a的值为:" << a << endl;cout << "*p的值为:" << *p << endl;cout << "变量a的地址为:" << &a << endl;cout << "变量b的地址为:" << &b << endl;}输出:sizeof (int(*)) --> 8指针p为:0x16ae5f738
变量a的地址为:0x16ae5f738
变量a的值为:10变量b的值为:500
变量a的值为:500
*p的值为:500
变量a的地址为:0x16ae5f738
变量b的地址为:0x16ae5f72c
2.指针常量和常量指针
指针常量
特点:指针的指向不能改,指针指向的值可以改 (内存地址不会变,但是内存地址指向的值会改变)
int a = 20;int b = 30;cout << "变量a的值:" << a << endl;cout << "变量a的地址:" << &a << endl;//指针常量 特点:指针的指向不能改,指针指向的值可以改 (内存地址不会变,但是内存地址指向的值会改变)int * const p1 = &a;cout << "指针p:" << p1 << endl; //输出的地址cout << "指针p:" << *p1 << endl; // 输出地址指向的值// p1 = &b; //报错,*p1 = 50;cout << "指针p:" << p1 << endl; //输出的地址cout << "指针p:" << *p1 << endl; // 输出地址指向的值输出:变量a的值:20
变量a的地址:0x16b303738
指针p:0x16b303738
指针p:20
指针p:0x16b303738
指针p:50
常量指针
特点: 指针的指向可以改,但是指针指向的值不可以改
int a = 50;int b = 30; //常量指针 特点: 指针的指向可以改,但是指针指向的值不可以改const int * p2 = &a;cout << "变量a的值:" << a << endl;cout << "变量a的地址:" << &a << endl;cout << "指针p2:" << p2 << endl;cout << "指针p2指向的值:" << *p2 << endl;//*p2 = 100; //报错p2 = &b;cout << "变量a的值:" << a << endl;cout << "变量a的地址:" << &a << endl;cout << "变量b的值:" << b << endl;cout << "变量b的地址:" << &b << endl;cout << "指针p2:" << p2 << endl;cout << "指针p2指向的值:" << *p2 << endl;输出:变量a的值:50
变量a的地址:0x16b06b738
指针p2:0x16b06b738
指针p2指向的值:50
变量a的值:50
变量a的地址:0x16b06b738
变量b的值:30
变量b的地址:0x16b06b734
指针p2:0x16b06b734
指针p2指向的值:30
3.指针数组 --》 是一个数组
指针数组 -- 存放指针的数组
int* arr[3]; // 整形指针的数组
char* arr1[10]; // 字符型指针的数组
4.数组指针 --》 是一个指针
int main()
{int* p = NULL; // p是整形指针 -- 指向整形的指针 -- 存放整形的地址char* pc = NULL; // pc是字符指针 -- 指向字符的指针 -- 存放字符的地址// 数组指针 -- 是不是指向数组的指针? -- 存放数组的地址int arr[10] = {0,6,0};printf("数组首元素地址 %p \n",arr);printf("数组首元素地址 %p \n",&arr[0]);printf("整个数组的地址 %p \n",&arr);// 如何存放数组地址呢? &arr 指向整个数组的指针// 想让 parr 指向整个数组(而不仅仅是第一个元素),你需要声明 parr 为 int (*)[10] 类型的指针。int (*parr)[10] = &arr;printf("parr %p\n",parr);printf("Second element: %d\n", (*parr)[1]); // 通过数组指针访问第二个元素char pch[10] = {'w','c'};char (*pch1)[10] = &pch;printf("Second element: %c\n", (*pch1)[1]); // 通过数组指针访问第二个元素// 定义一个字符型指针数组char* pc1[10];// 字符指针的地址又该如何存放呢?char* (*pa)[10] = &pc1;}
下面代码哪个是数组指针?
Int* p1[10]; // 存放指针的数组
Int (*p2)[10]; // 存放数组地址的指针 √
int arr5[10] = {1,2,3,4,5,6,7,8,9,10};int (*arr5_2)[10] = &arr5;for (int i = 0; i < 10; i++) {printf("%d ",(*arr5_2)[i]); // 不太容易理解}printf("\n");// 第二种写法for (int i = 0; i < 10; i++) {// *arr5_2 == arr5 ==> 首元素的地址 ==》 arr5_2+i 即表示指针向右移动printf("%d ",*(*arr5_2+i));}printf("\n");
5.函数指针 --》 指向函数的指针
estimate
函数接受一个整数lines
和一个指向函数的指针pf
,这个函数指针指向一个接受int
类型参数并返回double
的函数。
// 函数示例,符合 estimate 的要求
double myFunction(int x) {return x * 1.5;
}void estimate(int lines,double (*pf)(int))
{cout << (*pf)(lines) << endl; // 调用函数指针 pf
}
在
estimate
函数内部,(*pf)(lines)
用于调用函数指针pf
,并将lines
作为参数传递给它。
*pf
是一个函数指针的解引用操作。pf
是一个指向函数的指针,*pf
解引用这个指针,得到指向的函数。例如,如果
pf
是double (*pf)(int)
类型的函数指针,那么*pf
是一个函数,其参数是int
,返回值是double
。你可以用(*pf)(args)
来调用这个函数,传递参数args
。
5.1声明函数指针
函数指针是指向函数的指针,允许你通过指针来调用函数。
// 函数声明
void printMessage();
void anotherFunction();// 函数定义
void printMessage() {
std::cout << "Hello, World!" << std::endl;
}void anotherFunction() {
std::cout << "This is another function." << std::endl;
}// 定义一个函数指针,指向返回类型为 void、参数为无的函数
void (*funcPtr)();// 指向 printMessage 函数
funcPtr = printMessage;
(*funcPtr)(); // 调用 printMessage// 指向 anotherFunction 函数
funcPtr = anotherFunction;
(*funcPtr)(); // 调用 anotherFunction// ------------------
// 第一种写法
typedef int (*ptr1)(int,int);int Add(int a,int b)
{int c = a + b;printf("result is %d\n",c);
}// 一个函数,接受一个整数和一个回调函数
void process(int value1, int value2,ptr1 callback) {// 对值进行某种处理value1 *= 2;value2 *= 2;// 调用回调函数callback(value1,value2);
}process(5,7,Add);// 第二种写法// 指向函数的指针,用于指向一个接受两个 int 参数并返回 int 的函数(例如 Add 函数)int (*ptr1)(int,int);// 将函数指针指向 Add 函数ptr1 = Add;// 通过函数指针调用 Add 函数ptr1(5,6);
声明指向某种数据类型的指针时,必须指定指针指向的类型。同时,声明指向函数的指针时,也必须指定指针指向的函数类型。这意味着声明应指定函数的返回类型以及函数的特征标(参数列表)。也就是说,声明应像函数原型那样指出有关函数的信息。例如,假设Pam leCoder编写一个估算时间的函数,其原型如下:
double pam(int)
则正确的指针类型声明如下:
double (*pf)(int)
这与pam()声明类似,这是将pam替换成了(*pf)。由于pam是函数,因此( *pf)也是函数,而如果( *pf)是函数,则pf就是函数指针