C语言基础之指针3

二级指针和多级指针

二级指针存储的是一级指针的地址

二级指针定义格式

数据类型  * *  指针名

注意:指针数据类型跟指向的空间中数据类型是保持一致的

二级指针的作用:可以操作一级指针记录的地址

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值