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

拼搏现实的明天。 2022-04-25 03:30 386阅读 0赞

数组与指针

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

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

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

指向数组元素的指针

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

例如:

int a[10];

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

int *p;

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

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

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

p=&a[0];

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

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

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTU2MzE4_size_16_color_FFFFFF_t_70

通过指针引用数组元素

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

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

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

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

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

例 输出数组中的全部元素

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

(1) 下标法

  1. #include <stdio.h>
  2. void main()
  3. {
  4. int a[10];
  5. int i;
  6. for (i = 0; i < 10; i++)
  7. {
  8. scanf("%d", &a[i]);
  9. }
  10. printf("\n");
  11. for (i = 0; i < 10; i++)
  12. {
  13. printf("%d ", a[i]);
  14. }
  15. }

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

  1. #include <stdio.h>
  2. void main()
  3. {
  4. int a[10];
  5. int i;
  6. for (i = 0; i < 10; i++)
  7. {
  8. scanf("%d", &a[i]);
  9. }
  10. printf("\n");
  11. for (i = 0; i < 10; i++)
  12. {
  13. printf("%d ", *(a + i));
  14. }
  15. }

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

  1. #include <stdio.h>
  2. void main()
  3. {
  4. int a[10];
  5. int i;
  6. int *p;
  7. for (i = 0; i < 10; i++)
  8. {
  9. scanf("%d", &a[i]);
  10. }
  11. printf("\n");
  12. for (p = a; p < (a + 10); p++)
  13. {
  14. printf("%d ", *p);
  15. }
  16. }

思考题:

  1. #include <stdio.h>
  2. void main()
  3. {
  4. int *p, i, a[10];
  5. p = a;
  6. for (i = 0; i < 10; i++)
  7. {
  8. scanf("%d", p++);
  9. }
  10. printf("\n");
  11. for (i = 0; i < 10; i++, p++)
  12. {
  13. printf("%d", *p);
  14. }
  15. #if(0)
  16. for (int j = 0; j< 10; j++)
  17. {
  18. printf("%d ", a[j]);
  19. }
  20. #endif
  21. }

用数组名作函数参数

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

如:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTU2MzE4_size_16_color_FFFFFF_t_70 1

f (int arr[ ], int n)

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

以上两种写法是等价的。

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

实战演练

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

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTU2MzE4_size_16_color_FFFFFF_t_70 2

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

  1. #include <stdio.h>
  2. void reverse(int x[], int n); /*形参x是数组名*/
  3. void main()
  4. {
  5. int i, a[10] = { 3, 7, 9, 11, 0, 6, 7, 5, 4, 2 };
  6. printf("The original array:\n");
  7. for (i = 0; i < 10; i++)
  8. {
  9. printf("%d ", a[i]);
  10. }
  11. printf("\n");
  12. reverse(a, 10); //作用使得数组重新倒序排放
  13. printf("The array has been inverted:\n");
  14. for (i = 0; i < 10; i++)
  15. {
  16. printf("%d ", a[i]);
  17. }
  18. printf("\n");
  19. }
  20. void reverse(int x[], int n) /*形参x是数组名*/
  21. {
  22. int temp, i, j, m;
  23. m = (n - 1) / 2;
  24. for (i = 0; i <= m; i++)
  25. {
  26. j = n - 1 - i; //j指向对应的元素
  27. temp = x[i];
  28. x[i] = x[j];
  29. x[j] = temp;
  30. }
  31. }

第二个版本:指针作参数

  1. #include <stdio.h>
  2. void reserve(int *x, int n); /*形参x为指针变量*/
  3. void main()
  4. {
  5. int i, a[10] = { 3, 7, 9, 11, 0, 6, 7, 5, 4, 2 };
  6. printf("The original array:\n");
  7. for (i = 0; i < 10; i++)
  8. {
  9. printf("%d ", a[i]);
  10. }
  11. printf("\n");
  12. reserve(a, 10);
  13. printf("The array has benn inverted:\n");
  14. for (i = 0; i < 10; i++)
  15. {
  16. printf("%d ", a[i]);
  17. }
  18. printf("\n");
  19. }
  20. void reserve(int *x, int n) /*形参x为指针变量*/
  21. {
  22. int *p, temp, *i, *j, m;
  23. m = (n - 1) / 2;
  24. i = x; //i指向数组的第一个元素
  25. j = x - 1 + n; //j指向的是数组的最后一个元素
  26. p = x + m; //指向中间,配对……
  27. for (; i <= p; i++, j--)
  28. {
  29. temp = *i;
  30. *i = *j;
  31. *j = temp;
  32. }
  33. }

课后题

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

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

  1. #include <stdio.h>
  2. int max, min; /*全局变量*/
  3. void max_min_value(int array[], int n);
  4. void main()
  5. {
  6. int i, number[10];
  7. printf("enter 10 integer umbers:\n");
  8. for (i = 0; i < 10; i++)
  9. {
  10. scanf("%d", &number[i]);
  11. }
  12. max_min_value(number, 10);
  13. printf("\nmax=%d, min=%d\n", max, min);
  14. }
  15. void max_min_value(int array[], int n)
  16. {
  17. int *p, *array_end;
  18. array_end = array + n;
  19. max = min = *array;
  20. for (p = array + 1; p < array_end; p++)
  21. {
  22. if (*p > max)
  23. {
  24. max = *p;
  25. }
  26. else if (*p < min)
  27. {
  28. min = *p;
  29. }
  30. }
  31. }

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

  1. #include <stdio.h>
  2. int max, min; /*全局变量*/
  3. void max_min_value(int *x, int n);
  4. void main()
  5. {
  6. int i, number[10];
  7. printf("enter 10 integer umbers:\n");
  8. for (i = 0; i < 10; i++)
  9. {
  10. scanf("%d", &number[i]);
  11. }
  12. max_min_value(number, 10);
  13. printf("\nmax=%d, min=%d\n", max, min);
  14. }
  15. void max_min_value(int *x, int n)
  16. {
  17. int *p, *array_end;
  18. max = min = *x;
  19. for (p = x + 1; p < x+n; p++)
  20. {
  21. if (*p > max)
  22. {
  23. max = *p;
  24. }
  25. else if (*p < min)
  26. {
  27. min = *p;
  28. }
  29. }
  30. }

小结

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

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

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTU2MzE4_size_16_color_FFFFFF_t_70 3

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

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTU2MzE4_size_16_color_FFFFFF_t_70 4

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

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTU2MzE4_size_16_color_FFFFFF_t_70 5

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

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTU2MzE4_size_16_color_FFFFFF_t_70 6

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

  1. #include <stdio.h>
  2. void sort(int x[], int n);
  3. void main()
  4. {
  5. int *p, i, a[10] = { 3, 7, 9, 11, 0, 6, 7, 5, 4, 2 };
  6. printf("The original array:\n");
  7. for (i = 0; i < 10; i++)
  8. {
  9. printf("%d ", a[i]);
  10. }
  11. printf("\n");
  12. p = a;
  13. sort(p, 10);
  14. printf("The result is:\n");
  15. for (p = a, i = 0; i < 10; i++)
  16. {
  17. printf("%d ", *p);
  18. p++;
  19. }
  20. printf("\n");
  21. }
  22. void sort(int x[], int n)
  23. {
  24. int i, j, k, t;
  25. for (i = 0; i < n - 1; i++)
  26. {
  27. k = i;
  28. for (j = i + 1; j < n; j++)
  29. {
  30. if (x[j] > x[k])
  31. {
  32. t = x[j];
  33. x[j] = x[k];
  34. x[k] = t;
  35. }
  36. }
  37. }
  38. }

发表评论

表情:
评论列表 (有 0 条评论,386人围观)

还没有评论,来说两句吧...

相关阅读