二级指针和多级指针
二级指针存储的是一级指针的地址
二级指针定义格式
数据类型 * * 指针名
注意:指针数据类型跟指向的空间中数据类型是保持一致的
二级指针的作用:可以操作一级指针记录的地址
#include<stdio.h>
int main() {
/*
二级指针
格式:数据类型 ** 指针名*/
//定义变量
int a = 10;
//定义一级指针
int* p = &a;
//定义二级指针
int** pp = &p;
return 0;
}
#include<stdio.h>
int main() {
/*
二级指针
格式:数据类型 ** 指针名*/
//定义变量
int a = 10;
int b = 20;
//定义一级指针
int* p = &a;
//定义二级指针
int** pp = &p;
//利用二级指针修改一级指针里面记录的内存地址
*pp = &b;
printf("%p\n", &a);
printf("%p\n", &b);
printf("%d\n", *p);//20
printf("%d\n", **pp);//20
return 0;
}
数组和指针
数组指针:指向数组的指针叫做数组指针
作用:方便操作数组中的各种数据
#include<stdio.h>
int main() {
//利用指针遍历数组
//定义数组
int arr[] = { 10, 20, 30, 40, 50 };
int len = sizeof(arr) / sizeof(int);
//获取数组的指针,实际上是获取数组的首地址
int* p1 = arr;
int* p2 = &arr[0];
//printf("%p\n", p1); //0000007B88F8F718
//printf("%p\n", p2);//0000007B88F8F718
//printf("%d\n", *p1);//10
//printf("%d\n", *(p1 +1));//20
//printf("%d\n", *(p1 +2));//30
//printf("%d\n", *(p1 +3));//40
/*for (int i = 0; i < len; i++) {
printf("%d\n", *p1);
p1++;
}*/
for (int i = 0; i < len; i++) {
printf("%d\n", *p1++);
}
return 0;
}
细节:数组arr参与计算的时候,会退化为第一个元素的指针,但是在这两种情况下不会退化:1.sizeof运算的时候,arr还是整体;2.&arr获取地址的时候,步长:数据类型*数组长度
#include<stdio.h>
int main() {
//定义数组
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//sizeof运算的时候,不会退化,arr还是整体
printf("%zu\n", sizeof(arr));//40
//&arr的时候不会退化,记录的内存地址第一个元素的首地址,也是数组的首地址,步长:数据类型*数组长度
//arr参与计算的时候,会退化为第一个元素的指针,记录的内存地址是第一个元素的首地址,也是数组的首地址,步长:数据类型 如:int 4
printf("%p\n", arr);
printf("%p\n", &arr);
printf("%p\n", arr + 1);
printf("%p\n", &arr + 1);
//运行结果:
//000000EF764FFA08
// 000000EF764FFA08
// 000000EF764FFA0C
// 000000EF764FFA30
return 0;
}
二维数组
概念:把多个小数组,放到一个大的数组中去
定义格式:
数据类型 arr[m][n] =
{
{1,2,3,4....},
{1,2,3,4....},
{1,2,3,4....}
}
m:二维数组的长度
n:一维数组的长度
举例并遍历数组
#include<stdio.h>
int main() {
//定义一个二位数组
//1.
/*int arr[3][5] =
{
{1,2,3,4,5},
{11,22,33,44,55},
{111,222,333,444,555}
};*/
//利用索引的方式进行遍历
// //1.
//arr[0]:表示二维数组当中的第一个一维数组
//arr[1]:表示二维数组当中的第二个一维数组
//arr[2]:表示二维数组当中的第三个一维数组
/*for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}*/
//2.
int arr1[3] = { 1,2,3 };
int arr2[5] = { 11,22,33,44,55 };
int arr3[9] = { 1,2,3,4,5,6,7,8,9 };
//把三个一维数组放入到二位数组当中
// 数组的数据类型跟内部存储的元素保持一致
int* arr[3] = { arr1, arr2, arr3 };
int len1 = sizeof(arr1) / sizeof(int);
int len2 = sizeof(arr2) / sizeof(int);
int len3 = sizeof(arr3) / sizeof(int);
int lenArr[3] = { len1, len2, len3 };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < lenArr[i]; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
注意:上面第二个代码内层循环中不能写成这样
int len = sizeof(arr[i])/sizeof(int);
for(int j = 0; j < len; j++){
...}
因为sizeof(arr[i])得到的是指针的大小(在64位系统中通常是8个字节)
二维数组(指针操作)
数组指针:指向数组的指针
int * p = arr;步长:int (4个字节)
int (*p)[5] = &arr;步长:int * 5
#include<stdio.h>
int main() {
//二维数组
//利用指针遍历二维数组
//定义一个二维数组
int arr[3][5] = {
{1,2,3,4,5},
{11,22,33,44,55},
{111,222,333,444,555},
};
//利用指针遍历二维数组
//数组指针的数据类型:要跟数组内部元素的数据类型保持一致
//二维数组里面存储的是一维数组int[5]
int (*p)[5] = arr;//p指向包含5个整数的数组的指针
printf("%p\n", arr);
printf("%p\n", arr+1);//相差20个字节
for (int i = 0; i < 3; i++) {
//遍历一维数组
for (int j = 0; j < 5; j++) {
printf("%d ", *(*p + j));
}
printf("\n");
p++;
}
}
指针数组:存放指针的数组
#include<stdio.h>
int main() {
//定义三个一维数组
int arr1[5] = { 1,2,3,4,5 };
int arr2[5] = { 11,22,33,44,55 };
int arr3[5] = { 111,222,333,444,555 };
//把三个一维数组的内存地址放入二维数组当中
int* arr[3] = { arr1,arr2,arr3 };
//获取指针
int** p = arr;//p 存放的是 arr 数组的首地址
//遍历数组
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
printf("%d ", *(*p + j));
}
printf("\n");
p++;
}
return 0;
}
2045

被折叠的 条评论
为什么被折叠?



