指针和数组的纠缠

指针和数组的纠缠

1. 指针表示法和数组表示法
数组完全可以使用指针来访问, days[3] 和 *(days+3) 等同

#include <stdio.h>
#include <stdlib.h>

void print_months(int days[], int months) {
	int index = 0;
	for (index = 0; index < months; index++) {
		// Array notation
		// printf("month %2d has %d days.\n", index+1, days[index]);
		// Pointer notation
		printf("Month %2d has %d days.\n", index+1, *(days+index));
	}
}

void print_months2(int *days, int months) {
	int index = 0;
	for (index = 0; index < months; index++) {
		// Pointer notation
		printf("Month %2d has %d days .\n", index+1, *(days+index));
		// Array notation
		printf("Month %2d has %d days. \n", index+1, days[index]);
	}

}

int main() {
	int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	int index = 0;
	/*for (index = 0; index < 12; index++) {
		// Array notation
		printf("Month %2d has %d days.\n", index+1, days[index]);

		// Pointer notation
		printf("Month %2d has %d days.\n", index+1, *days+index);
	}
	*/

	print_months(days, 6);
	//print_months2(days, 12);
	
	return 0;
}

运行结果:
在这里插入图片描述

存储指针的数组

定义: 类型 *指针数组名[元素个数] ;

#include <stdio.h>
#include <stdlib.h>

int main() 
{
	int girls[4][3] = {
			{173, 158, 166},
			{168, 155, 171},
			{163, 164, 165},
			{163, 164, 172}};

	int *qishou[2];

	if (girls[0][0] > girls[0][1]) {
		qishou[0] = &girls[0][0];
		qishou[1] = &girls[0][1];
	}else {
		qishou[0] = &girls[0][1];
		qishou[1] = &girls[0][0];
	}


	for (int i = 2; i < 12; i++) {
		if (*qishou[1] >= girls[i/3][i%3]) {
			continue;
		}

		// 候选者高于第二位棋手候选女兵
		// 1.候选者比"冠军"矮
		if (girls[i/3][i%3] <= *qishou[0]) {
			qishou[1] = &girls[i/3][i%3];
		}else {
			qishou[1] = qishou[0];
			qishou[0] = &girls[i/3][i%3];
		}
	}
	printf("Highest female soldier height: %d, Second highest female soldier height: %d\n", *qishou[0], *qishou[1]);

	return 0;
}

运行结果:
在这里插入图片描述

指针和二维数组

1. 指向数组的指针
int (*p)[3]; //定义一个指向三个成员的数组的指针
访问元素的两种方式:
数组法: (*p)[j]
指针法: *((*p)+j)

#include <stdio.h>
#include <stdlib.h>

int main() {
	/*据同学们报告,A 栋学生楼有学生用高倍望眼镜偷看别人洗澡, 
	宿管办领导决定逐个宿舍排查,得到的线报是 A0 到 A3 宿舍的 
	某个子最矮的男生。 */

	int A[4][3] = {
			{173, 158, 166},
			{168, 155, 171},
			{163, 164, 165},
			{163, 164, 172}};

	//定义一个指向三个成员的数组的指针
	int (*p)[3];
	int * boy = NULL;

	p = &A[0];

	// The first kind of
	/*for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 3; j++) {
			// (*p) 等同于 a[0] ,a[0][0]等同于 (*p)[0]
			printf(" %d", (*p)[j]);
		}
		printf("\n");
		p++;
	}*/

	boy = &(*p)[0];
	// boy = (*p);

	// The second //int a[3]; int * p ; p = a; Array members: *p *(p+1) *(p+2)
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 3; j++) {
			printf(" %d", *((*p)+j));
			if (*boy > *((*p)+j)) {
				boy = (*p) + j;
			}
		}

		printf("\n");
		p++;
	}

	printf("The student who peeps is: %d\n", *boy);

	return 0;
}

运行结果:
在这里插入图片描述
使用普通指针访问二维数组
int A[4][3];
int *p; //定义一个指针
p = A[0]; 或者 p=&A[0][0];
访问元素的两种方式:

#include <stdio.h>
#include <stdlib.h>

int main() {

	/*据同学们报告,A 栋学生楼有学生用高倍望眼镜偷看别人洗澡, 
	宿管办领导决定逐个宿舍排查,得到的线报是 A0 到 A3 宿舍的 
	某个子最矮的男生。 */

	int A[4][3] = {{173, 158, 166},
				{168, 155, 171},
				{163, 164, 165},
				{163, 164, 172}};

	int *boy = NULL; 
	int *p = NULL;

	//p = A[0];
	p = &A[0][0];
	boy = p;

	for (int i = 1; i < 4*3; i++, p++) {
		//*p 可以替换成 A[i/3][i%3]
		if (*boy > *p) {
			boy = p;
		}
	}

	printf("The students were: %d\n", *boy);

	// Calculate the index according to the pointer
	int pos = boy - A[0];

	printf("index: %d\n", pos);
	printf("locate A[%d] dormitory\n", pos/3);
	printf("Is the first %d Is the first\n", pos%3);
	
	return 0;
}

运行结果:
在这里插入图片描述

“我们不一样“之数组与指针的区别

数组:数组是用于储存多个相同类型数据的集合。
指针:指针是一个变量,但是它和普通变量不一样,它存放的是其它变量在内存中的地址。
1. 赋值
数组:只能一个一个元素的赋值或拷贝 指针:指针变量可以相互赋值
2. 表示范围
数组有效范围就是其空间的范围,数组名使用下表引用元素,不能指向别的数组
指针可以指向任何地址,但是不能随意访问,必须依附在变量有效范围之内
3. sizeof
数组:数组所占存储空间的内存:sizeof(数组名)
数组的大小:sizeof(数组名)/sizeof(数据类型)
指针:在 32 位平台下,无论指针的类型是什么,sizeof(指针名)都是 4.
在 64 位平台下,无论指针的类型是什么,sizeof(指针名)都是 8.

指针数组和数组指针

***针指数组:*** 
    int *qishou[2];//定义一个有两个元素的指针数组,每个元素都是一个指针变量 
    int girl1= 167; 				     
	int girl2 = 171; 
	qishou[0] = &girl1; 
	qishou[1] = &girl2; 
***数组指针:*** 
int (*p)[3]; //定义一个指向三个成员的数组的指针 
访问元素的两种方式: 
int A[4][3]={{173, 158, 166}, 
				{168, 155, 171}, 
				{163, 164, 165}, 
				{163, 164, 172}};
p = &A[0]; 
数组法: (*p)[j] 
指针法: *((*p)+j)

传参

数组传参时,会退化为指针!
(1)退化的意义:C 语言只会以值拷贝的方式传递参数,参数传递时,如果只拷贝整个数 组,效率会大大降低,并且在参数位于栈上,太大的数组拷贝将会导致栈溢出。
(2)因此,C 语言将数组的传参进行了退化。将整个数组拷贝一份传入函数时,将数组名 看做常量指针,传数组首元素的地址。

发布了33 篇原创文章 · 获赞 33 · 访问量 241

猜你喜欢

转载自blog.csdn.net/m0_45867846/article/details/105559155