【笔记】C_数组类型与指针类型的区别

本文探讨了C语言中数组和指针的区别,包括数组类型的长度计算、数组下标的指针理解、函数参数传递时的隐式转换,以及指针数组和二维数组的使用方法。通过实例解析,阐述了如何通过指针遍历二维数组。

1.数组类型与指针类型

int a[6] = {1,2,3,4,5,6};
int* p = a;
int lenA = sizeof(a)/sizeof(int);
int lenP = sizeof(p)/sizeof(int);
printf("lenA=%d,lenP=%d.\n",lenA,lenP);

lenA=6;lenP=1;
因为两种类型是不同的,虽然在他们都是指向a数据的a[0]。
数组类型:int[6],我们可以知道这个a指针指向的是一个数组,他的长度为6,所以数据长度会等于:64=24。
指针类型:int
,我们只知道他是指向a[0],是个int类型,并不知道他是指向一个数组,所以最后长度等于:14 = 4。

int a[3][3] = {0};//长度为:3*3*4 = 36

2.数组下标用指针来理解

实际上,数组下标,是通过指针与偏移量来确定数组各个位置的数据。
a[3]实际上可以用*(a+3)来表示。实际上还能用3[a]来表示,即*(3+a)。编译器会自动去换算实际类型的大小,例如:

int a[3] = {1,2,3};//a[2]是从a[0]跳两个int大小,即8
char a[] = "hello";//a[2]是从a[0]跳两个char大小,即2

3.数组在函数传值时的隐式转换

void func(int* arr);
void func(int arr[]);
void func(int arr[6]);

三种情况最终结果都是一样的,函数传入数组不会直接把整个数组拷贝进去,开销太大,而是隐式转换,将数组转换成指向a[0]的一个指针,所以一般在数组作为形参的函数中,会有第二个形参n来指定数组的长度。

void func(int arr[]){
	printf("%d",sizeof(arr));
}

输出为4。不会输出数组长度,在标题1中已经有说到。

4.指针数组

以整型指针数组为例:

int a = 1,b = 2,c = 3;
int* arr[3] = {&a,&b,&c};
int** p = arr;
printf("a=%d,b=%d,c=%d.\n",*arr[0],*arr[1],*arr[2]);
printf("a=%d,b=%d,c=%d.\n",**p,**(p+1),**(p+2));

定义的arr[3]中存放这a,b,c的地址,创建一个二级指针p指向arr数组的第0个元素,以两种方式都能输出。

以字符指针数组为例:

const char* a = "hello1";
const char* b = "world2";
const char* c = "!3";
const char* str[3] = { a,b,c };
printf("str1=%s,str2=%s,str3=%s.", str[0], str[1], str[2]);

5.二维数组与指针

int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int (*p)[4] = a;
printf("%d",*(*(p+1)+1));

输出结果:5
输出的是宏观上第1行(下标)的第1个元素5。
定义的p指针指向的数据类型是int[4],即是一行。
(p+1),即指向第1行。
*(p+1)+1,指向第1行第1元素。
所以,要遍历一个二维数组:

int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
for(int i=0;i<3;i++){
	for(int j=0;j<4;j++){
		printf("%-3d ",a[i][j]);
	}
	printf("\n");
}

用指针来遍历二维数组:

int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int (*p)[4] = a;
for(int i=0;i<3;i++){
	for(int j=0;j<4;j++){
		printf("%-3d ",*(*(p+i)+j));
	}
	printf("\n");
}

可以理解为,p指向的是(指向第0行第0个数据的指针),所以*p应该是指向0的指针,所以**p会等于0。
p+1,则指向指向第1行第0个元素的指针,
*(p+1)则获得这个指针,+1后获得第1行第1个元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值