第八章 指针(第二部分)

8.3通过指针引用数组

引用一个数组元素可以使用:
(1)下标法:如a[i]
(2)指针法 :如*(p+i)和 *(a+i) a是数组名,p是指针变量

#include<stdio.h>
int main() {
	int a[10] = { 1,2,3,4,5,6,7,8,9,0 };
	int* p = a;//p的值是数组首元素(a[0])的值
	
	for (int i = 0; i < 10; i++) {
	printf("%d", *(p + i));//指针法	
	}
	printf("\n");
	for (int i = 0; i < 10; i++) {
	printf("%d", a[i]);//数组法
	}
	printf("\n");
	for (int i = 0; i < 10; i++) {
    printf("%d", *(a+i));//数组名和元素序号计算元素地址,再找到该元素
	}
	return 0;
}
*(p+i)和 *(a+i) 以及a[i]三者等价,
实际上,在编译时,对数组元素a[i]就是按照 *(a+i)处理的,
按照数组首元素地址加上相对位移量找到地址,然后找到内容。

在这里插入图片描述

在这里插入图片描述
例题:输入十个数并输出

#include<stdio.h>
int main()
{
	int a[10];
	int* p = a;
	int i = 0;
	printf("请输入10个整数");
	for (i = 0; i < 10; i++)
		scanf_s("%d", p+i);
	for (i = 0; i < 10; i++) {
		printf(" %d", *(p + i));
	}
	printf("\n");
	while(p<a+10) {  //注意,一定要写成p<a+10
		printf(" %d", *p++);//*p++和*(p + i)是一样的
	}

	return 0;
}

在这里插入图片描述
*p++:等价于 *(p++)。先引用p的值,实现 *p的运算,再让p自增。
在这里插入图片描述

8.3.4用数组名作函数参数

以数组名作函数参数,通过函数调用能改变实参数组的值。
实参数组名代表一个固定的地址,或者说是指针常量,但形参数组名并不是一个固定的地址,而是按指针变量处理。
在函数调用进行虚实结合后,形参的值就是实参数组元素的地址。在函数执行期间,它可以再被赋值。

例题:将数组a中n个整数按相反顺序存放:

#include<stdio.h>
//数组
//void inv(int x[], int n)
//{
//	int temp, i, j, m = (n - 1) / 2;
//	for (i = 0; i <=m; i++) {   //m是对换次数,如果已经知道需要对换数字的个数n,算出m直接写数字即可
//		j = n - i - 1;
//		temp = x[i];
//		x[i] =x[j];
//		x[j] = temp;
//	}
//}
//指针变量
void inv(int* x, int n)
{
	int m = (n - 1) / 2, temp;
	int *i = x; int *j = x + n - 1; int *p = x+m;
	for (; i <= p; i++, j--) {
		temp = *i;
		*i =*j;
		*j= temp;
		}
	
}
int main()
{
	//void inv(int x[], int n);
	void inv(int *x, int n);
	int i, a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	printf("原来的顺序\n");
	for (int i = 0; i < 10; i++) {
		printf("%d ", a[i]);
	}
	inv(a, 10);
	printf("现在的顺序");
	for (i = 0; i < 10; i++) {
		printf("%d ", a[i]);
	}
	return 0;
}
将函数inv中的形参x改成指针变量。
相应的实参仍为数组名a,即数组a首元素的地址,
将它传给形参指针变量x,这时x就指向a[0]。x+m是a[m]的地址。
*i与*j交换就是使a[i]与a[j]交换。

改变上面例子,用指针变量作实参:

#include<stdio.h>
void inv(int* x, int n)
{
	int m = (n - 1) / 2, temp;
	int* i = x; int* j = x + n - 1; int* p = x + m;
	for (; i <= p; i++, j--) {
		temp = *i;
		*i = *j;
		*j = temp;
	}

}
int main()
{
	
	void inv(int* x, int n);
	int i, a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	int *p = a;
	printf("原来的顺序\n");
	for (int i = 0; i < 10; i++) {
		printf("%d ", * (p+i));
	}
	inv(p, 10);
	printf("现在的顺序");
	for (p = a; p < a + 10; p++) {
		printf("%d ", *p);
	}
	return 0;
}

在这里插入图片描述

用指针方法排序从大到小

//十个数从大到小排序,使用选择排序
#include<stdio.h>
void sort(int x[], int n) {
	int k, i, j, t;
	for (i = 0; i <n-1; i++) {
		k = i;//决定排序次数,从a[0]到a[n-1]
		for (j = i + 1; j < n; j++) {//比较大小,交换数值,从自己的下一个比较到末尾寻找一个最大值
			if (x[k] < x[j]) k = j;
			if (k!= i) {
				t = x[i];
				x[i] = x[k];
				x[k] = t;
			}
	}
	}
}
int main() {
	void sort(int x[],int n);
	int x[10] = {1,5,6,7,9,12,5,6,3,4};
	int i;
	int *p = x;
	sort(p, 10);
	for (p = x, i = 0; i < 10; i++) {//输出排序后的十个元素
		printf("%d ", *(p+i));
		
	}
	return 0;

}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值