进阶指针
文章目录
- 进阶指针
-
- 一、字符指针
-
- 1. 单个字符指针
- 2. 常量字符串指针
- 二、指针数组
-
- 1. 存放整型指针
- 2. 存放常量字符串指针
- 三、数组指针
-
- 1. 数组指针实现打印一维数组
- 2. 数组指针实现打印二维数组
- 如何判断是数组指针还是指针数组
一、字符指针 1. 单个字符指针
2. 常量字符串指针char ch = 'x'; char* p = &ch;
二、指针数组char* p = "asdwjwd"; //后面一串数字为常量字符串
常量字符串单独存在,不是字符串数组
p中存放的是常量字符串中首元素a的地址
打印*p也只会打印首元素,同时验证了上面的猜想
printf("%s", p); //打印整个字符串,只需要首字母地址就行
就像数组
char arr[] = "asbdjw"; printf("%s", arr);
但是
常量字符串存储在内存的常量区,不能进行修改
所以常量字符串指针修改数值时候在不同的编译器可能会报错
我们在定义常量字符串指针的时候会加个const
const char* p = "adwdfe";
重点区分
const char* p = "asa"; const char* r = "asa";
因为常量字符串存储在内存的常量区,指针所指向的地址永远是字符串第一个字符的地址,所以p = r
存放指针的数组1. 存放整型指针
int* arr[3];
//存放整型指针的数组
数组中每个元素的类型都是整型指针int*
//打印指针数组
printf("%d", *(arr[1]));
利用(p+i) = p[i]去理解
int arr1[] = {1,2,3};
int arr2[] = {3,3,5,6};
int* p[] = {arr1,arr2};
printf("%d", p[1][2]);
//打印5
//其中p[1][2] = *(p + 1)[2] = arr2[2] = *(arr2 + 2) = 5
2. 存放常量字符串指针
const char* p[2] = {"abs", "ashw", "swnd"};
打印 打印字符串只需要给予数组的首元素地址即可
printf("%s", p[1]);
//打印ashw
三、数组指针
指向数组的指针
数组指针加1跳过一个数组
int arr[4] = { 0 };
int* p = arr;
//指向数组首元素地址
int(*p)[4] = &arr;
//这里[]的优先级比*高,所以需要加括号
//指针指向整个数组,把(*p)去掉就是指向数组中元素的类型
如何判断类型:把名字去掉即为类型
加深印象
int main()
{
int* arr[10];
//这里是指针数组
int* (*p)[10] = &arr;
}
*先确定指针指向的元素的类型,再写(p)1. 数组指针实现打印一维数组
void print(int (*p)[4], int sz)
//传参形式,数组指针p指向一个arr[4],传进去的数是&arr
{
int i = 0;
for(i = 0;
i < sz;
i++)
{
printf("%d", p[0][i]);
//p[0] = *(p + 0) = arr 数组(首元素地址)
//p[0][i] = arr[i] = (*(p + 0))[i] = (*p)[i]
}
}
2. 数组指针实现打印二维数组
void print(int (*p)[4], int line, int column)
//传参形式,数组指针p指向一个arr[4]
//传进去的数是arr,这里arr指的是二维数组第一行数组的数组名
{
int i = 0;
int j = 0;
for(i = 0;
i < line;
i++)
{
for(j = 0;
j < column;
j++)
{
printf("%d", p[i][j]);
//p[i] = *(p + i) = arr[i] (arr的i行数组地址)
//p[0][i] = arr[i] = (*(p + 0))[i] = (*p)[i]
}
}
}
思路再解读:如何判断是数组指针还是指针数组
传参传的是arr
而二维数组中的arr代表,二维数组中,arr的第一行这一行的数组名
所以传参相当于传了一个一维数组
需要int (*p)[4] 的数组指针去接收
要想打印整个数组
int(*p)[4] = arr; 这里的arr是指的二维数组中第一行的数组名
p指向的是二维数组中第一行的地址
假如我们需要 arr [0] [2]
*(p + 0) 指的是二维数组中第一行的数组名
*(p + 1) 指的是二维数组中第二行的数组名
(*(p + 0) + 2)指的是二维数组中第一行,第二列数字的地址
再换个更容易理解的方式:
传参没传进去的时候,arr指的是二维数组中第一行的数组名
传参传进去的时候,p也是指的是二维数组中第一行的数组名
【c|指针进阶——字符指针、指针数组和数组指针如何辨别和判断】所以直接用就行,外面的arr [i] [j] 和 里面的 p [i] [j] 差不多
int* arr[10]; int (*arr)[10]; int * (*arr) [10];
分析:
1:[]的优先级比()高,所以arr与[10]先结合,arr是数组,有10个元素,每个元素类型是int*
2:()的优先级更高,arr和*先结合,所以arr是指针,指向的类型是int[10]是一个有10个int类型的整型数组
3:arr与*先结合,所以arr是指针,指向的类型是int *[10],这是一个有10个元素的数组,每个元素的类型是int *
推荐阅读
- 笔记|C语言进阶——3.二维指针
- C语言进阶|【C语言进阶6——指针的进阶(3)-总结数组和指针】
- 牛客网-替换空格简单解答
- 浅谈C语言中的文件操作函数
- C/C++中的头文件介绍及其用法示例
- C中的char s[]和char *s有什么区别()
- C语言学习笔记_实现简单的猜数字小游戏
- C和C++之间有什么区别(有哪些区别?)
- c++|c语言和c++中的动态内存申请与释放