零基础入门学习C语言009讲:指针(2)

版权声明:转载请标明出处 https://blog.csdn.net/qq_41556318/article/details/89717000

数组与指针

一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。

指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。

所谓数组元素的指针就是数组元素的地址

指向数组元素的指针

定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。

例如:

int a[10];

(定义a为包含10个整型数据的数组)

int *p;   

 (定义p为指向整型变量的指针变量)

应当注意,如果数组为int型,则指针变量的基类型亦应为int型。

下面是对该指针变量赋值:

p=&a[0];

把a[0]元素的地址赋给指针变量p。

也就是使p指向a数组的第0号元素,见图 -->>

通过指针引用数组元素

引用一个数组元素,可以用:

(1) 下标法,如a[i]形式;

(2) 指针法,如*(a+i)或*(p+i)

其中的a是数组名,p是指向数组元素的指针变量,其初值 p=a。

注意:数组名即“翻译成数组的第一个元素的地址!

例  输出数组中的全部元素

假设有一个a数组,整型,有10个元素。要输出各元素的值有三种方法:

(1) 下标法

#include <stdio.h>

void main()
{
	int a[10];
	int i;

	for (i = 0; i < 10; i++)
	{
		scanf("%d", &a[i]);
	}

	printf("\n");

	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
}

(2) 通过数组名计算数组元素地址,找出元素的值。

#include <stdio.h>

void main()
{
	int a[10];
	int i;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", &a[i]);
	}

	printf("\n");

	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(a + i));
	}
}

(3) 用指针变量指向数组元素。

#include <stdio.h>

void main()
{
	int a[10];
	int i;
	int *p;

	for (i = 0; i < 10; i++)
	{
		scanf("%d", &a[i]);
	}

	printf("\n");

	for (p = a; p < (a + 10); p++)
	{
		printf("%d ", *p);
	}
}

思考题:

#include <stdio.h>

void main()
{
	int *p, i, a[10];
	p = a;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", p++);
	}
	printf("\n");
	for (i = 0; i < 10; i++, p++)
	{
		printf("%d", *p);
	}
#if(0)
	for (int j = 0; j< 10; j++)
	{
		printf("%d ", a[j]);
	}
#endif
}

用数组名作函数参数

在前面介绍过可以用数组名作函数的参数

如:

 

f (int arr[ ], int n)

但在编译时是将arr按指针变量处理的,相当于将函数f的首部写成  f (int *arr, int n)

以上两种写法是等价的。

需要说明的是:C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。

实战演练

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

第一个版本:数组名作参数

#include <stdio.h>

void reverse(int x[], int n);   /*形参x是数组名*/

void main()
{
	int i, a[10] = { 3, 7, 9, 11, 0, 6, 7, 5, 4, 2 };

	printf("The original array:\n");

	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	reverse(a, 10);  //作用使得数组重新倒序排放

	printf("The array has been inverted:\n");

	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

}

void reverse(int x[], int n)   /*形参x是数组名*/
{
	int temp, i, j, m;

	m = (n - 1) / 2;

	for (i = 0; i <= m; i++)
	{
		j = n - 1 - i;  //j指向对应的元素

		temp = x[i];
		x[i] = x[j];
		x[j] = temp;
	}

}

第二个版本:指针作参数

#include <stdio.h>

void reserve(int *x, int n);   /*形参x为指针变量*/

void main()
{
	int i, a[10] = { 3, 7, 9, 11, 0, 6, 7, 5, 4, 2 };

	printf("The original array:\n");

	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	reserve(a, 10);

	printf("The array has benn inverted:\n");

	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void reserve(int *x, int n)   /*形参x为指针变量*/
{
	int *p, temp, *i, *j, m;

	m = (n - 1) / 2;
	i = x;         //i指向数组的第一个元素
	j = x - 1 + n;     //j指向的是数组的最后一个元素
	p = x + m;       //指向中间,配对……

	for (; i <= p; i++, j--)
	{
		temp = *i;
		*i = *j;
		*j = temp;
	}
}

课后题

题目:从10个数中找出其中最大值和最小值。

第一种解法:数组名作参数

#include <stdio.h>

int max, min;      /*全局变量*/

void max_min_value(int array[], int n);

void main()
{
	int i, number[10];

	printf("enter 10 integer umbers:\n");

	for (i = 0; i < 10; i++)
	{
		scanf("%d", &number[i]);
	}

	max_min_value(number, 10);

	printf("\nmax=%d, min=%d\n", max, min);

}

void max_min_value(int array[], int n)
{
	int *p, *array_end;

	array_end = array + n;

	max = min = *array;

	for (p = array + 1; p < array_end; p++)
	{
		if (*p > max)
		{
			max = *p;
		}
		else if (*p < min)
		{
			min = *p;
		}
	}
}

体会一下解法,再把它变成第二个版本:用指针作参数!

#include <stdio.h>

int max, min;      /*全局变量*/

void max_min_value(int *x, int n);

void main()
{
	int i, number[10];

	printf("enter 10 integer umbers:\n");

	for (i = 0; i < 10; i++)
	{
		scanf("%d", &number[i]);
	}

	max_min_value(number, 10);

	printf("\nmax=%d, min=%d\n", max, min);

}

void max_min_value(int *x, int n)
{
	int *p, *array_end;

	max = min = *x;

	for (p = x + 1; p < x+n; p++)
	{
		if (*p > max)
		{
			max = *p;
		}
		else if (*p < min)
		{
			min = *p;
		}
	}
}

小结

归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下4种情况:

(1) 形参和实参都用数组名,如:

(2) 实参用数组名,形参用指针变量。如:

(3)实参形参都用指针变量。例如:

(4) 实参为指针变量,形参为数组名。如:

对数组中10个整数按由大到小顺序排序

#include <stdio.h>

void sort(int x[], int n);

void main()
{
	int *p, i, a[10] = { 3, 7, 9, 11, 0, 6, 7, 5, 4, 2 };

	printf("The original array:\n");

	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}


	printf("\n");

	p = a;
	sort(p, 10);

	printf("The result is:\n");

	for (p = a, i = 0; i < 10; i++)
	{
		printf("%d ", *p);
		p++;
	}
	printf("\n");

}

void sort(int x[], int n)
{
	int i, j, k, t;

	for (i = 0; i < n - 1; i++)
	{
		k = i;

		for (j = i + 1; j < n; j++)
		{
			if (x[j] > x[k])
			{
				t = x[j];
				x[j] = x[k];
				x[k] = t;
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41556318/article/details/89717000