P41-指针进阶1、2
1.字符指针
2.数组指针
3.指针数组
4.数组传参和指针传参
5.函数指针
6.函数指针数组
7.指向函数指针数组的指针
8.回调函数
9.指针和数组面试题的解析
指针的主题,我们在初级阶段的《指针》章节已经接触过了,我们知道了指针的概念
1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
⒉.指针的大小是固定的4/8个字节( 32位平台/64位平台)。
3.指针是有类型,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。
4.指针的运算。
字符指针
在指针的类型中我们知道有一种指针类型为字符指针char*
一般使用
还有另一种使用方式如下:
举一个例子:
str1和str2是两个字符数组,比较str1和str2时,相当于比较数组str1和数组str2的首元素地址,而str1与str2是两个不同的字符数组,创建数组str1和数组str2是会开辟两块不同的空间,它们的首元素地址当然不同。
这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。
注意:常量字符串与普通字符串最大的区别是,常量字符串是不可被修改的字符串,既然不能被修改,那么在内存中没有必要存放两个一模一样的字符串,所以在内存中相同的常量字符串只有一个。
指针数组
在《指针》章节我们也学习了指针数组,指针数组是一个存放指针的数组
数组指针
数组指针是一个指针,指向数组的指针
&数组名VS数组名
数组名是数组首元素地址,但是也有两个例外:
****1.**sizeof(数组名)**
** 这里的数组名表示整个数组,计算的大小也是整个数组的大小,单位为字节**
2.**&数组名**
** 数组名表示整个数组,取出的是整个数组的地址**
数组指针的使用
数组指针一般应用于二维数组及以上
分析下面的代码
int arr[5]; //整型数组
int *parr1[10]; //整型的指针数组
int (*parr2)[10]; //数组指针,该指针指向一个数组,数组为10个元素,每个元素的类型为int
int (*parr3[10])[5]; //parr3是一个指针数组,该数组能够存放十个数组指针
//每个数组指针能够指向一个数组,数组5个元素,每个元素是int类型
这段代码定义了一个指针数组 parr3,该数组有10个元素,每个元素都是一个指向含有5个整数的数组的指针。
让我们分解一下这个定义:
- parr3[10]:这是一个包含10个元素的数组。
- (*parr3[10]):这里的星号表示这是一个指针数组,即数组的每个元素都是一个指针。
- (*parr3[10])[5]:这表示数组的每个元素(即每个指针)都指向一个包含5个整数的数组。
所以,parr3 是一个指针数组,每个指针都指向一个大小为5的整数数组。
数组参数、指针参数
如何将数组
或者指针
传给函数呢?
一维数组传参
#include <stdio.h>
void test(int arr[])//ok? 传数组名,用数组接收,数组元素个数可省略 正确
{}
void test(int arr[10])//ok? 同上的道理 正确
{}
void test(int *arr)//ok? 数组名是首元素地址,用指针接收 正确
{}
void test2(int *arr[20])//ok? 用同样的指针数组接收 正确
{}
void test2(int **arr)//ok? 数组名是首元素地址,而该数组元素是指针,所以地址是int**类型,
// 用二级指针接收 正确
{}
int main()
{
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
}
二位数组传参
void test(int arr[3][5])//ok? 用二维数组接收 正确
{}
void test(int arr[][])//ok? 用二维数组接收,行可以省略,但列不能省略 错误
{}
void test(int arr[][5])//ok? 用二维数组接收 正确
{}
void test(int *arr)//ok? 这里不能用一级指针接收 错误
{}
void test(int* arr[5])//ok? 这是个指针数组,不能传首地址 错误
{}
void test(int (*arr)[5])//ok? 用数组指针接收 正确
{}
void test(int **arr)//ok? 这里不能用二级指针接收 错误
{}
int main()
{
int arr[3][5] = {0};
test(arr); //这里传入的是首元素地址
}