Cprogramming 简明教程

Applications of Pointers in C

C 最重要的特点之一是它通过 pointers 的概念提供低级别内存访问。 pointer 是一个变量,它存储内存中另一个变量的地址。

指针的规定有许多应用,例如将数组和结构类型传递给函数和动态内存分配等。在本章中,我们将解释 C 中指针的一些重要应用。

To Access Array Elements

还可以通过指针来访问 Array 元素。您需要声明和初始化一个 pointer to an array 并使用它,您可以通过将指针变量增加 1 来访问每个元素。

指向数组的指针是其第 0 个元素的地址。当数组指针增加 1 时,它指向数组中的下一个元素。

Example

以下示例演示了如何借助它的指针遍历数组。

#include <stdio.h>

int main(){

   int arr[] = {1,2,3,4,5};
   int *ptr = arr;

   for(int i = 0; i <= 4; i++){
      printf("arr[%d]: %d\n", i, *ptr);
      ptr++;
   }

   return 0;
}

运行代码并检查其输出:

arr[0]: 1
arr[1]: 2
arr[2]: 3
arr[3]: 4
arr[4]: 5

For Allocating Memory Dynamically

C 指针最主要的一个应用是动态声明变量的内存。静态内存分配无法解决很多情况,比如处理大量数组、结构有 n 个学生和员工等。

因此,每当需要动态分配内存时,指针都能发挥非常重要的作用。C 语言提供了一些函数来动态分配和释放内存。这些函数包括:

1. The malloc() Function

该函数定义在“stdlib.h”头文件中。它分配一块所需大小的内存块,并返回一个 void 指针。

void *malloc (size)

大小参数表示以字节为单位的内存块。要为指定的数据类型分配必需的内存,需要使用强制类型转换运算符。例如,以下代码片段分配存储 int 类型的必需内存。

int *ptr;
ptr = (int * ) malloc (sizeof (int));

这里我们需要定义一个指向字符的指针,而不需要定义所需的内存量,之后,可以根据需求分配内存。

在这个示例中,我们使用 malloc() 函数分配存储字符串的必需内存(而不是声明固定大小的 char 数组)-

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

int main(){

   char *name;
   name = (char *) malloc(strlen("TutorialsPoint"));

   strcpy(name, "TutorialsPoint");

   if(name == NULL) {
      fprintf(stderr, "Error - unable to allocate required memory\n");
   } else {
      printf("Name = %s\n", name );
   }
}

编译并执行上述代码会产生以下输出:

Name = TutorialsPoint

2. The calloc() Function

C 库函数 "calloc" (代表连续分配)分配请求的内存,并返回指向它的指针。

void *calloc(n, size);

其中 "n" 是要分配的元素数量, "size" 是每个元素的字节大小。

下面的代码段分配存储 10 个整数类型的必需内存。

int *ptr;
ptr = (int *) calloc(25, sizeof(int));

3. The realloc() Function

C 语言中的 realloc() 函数用来动态更改之前分配的内存的内存分配。可以通过调用 realloc() 函数来增加或减少已分配内存块的大小。

void *realloc(*ptr, size);

第一个参数 "ptr" 是一个内存块的指针,之前用 malloc, callocrealloc 分配过要重新分配的内存。

动态内存分配技术在复杂线性及非线性数据结构(比如链表和树)中被广泛使用,这些数据结构被用于操作系统软件中。

For Passing Arguments as Reference

当按引用调用函数时,将传递实际参数变量的地址,而不是它们的值。

Passing a pointer to a function 有两个 advantages

第一,它克服了传值限制。对调用函数中值的更改直接在指针中存储的地址中完成。因此,我们可以在其他地方操作一个范围中的变量。

第二,它也克服了函数仅能返回一个表达式的限制。通过传递指针,处理函数的效果直接在该地址发生。其次,如果我们返回数组或结构变量的指针,可以返回多个值。

Example

以下函数接收两个变量的引用,这些变量的值要互换。

/* function definition to swap the values */

int swap(int *x, int *y){
   int z;
   z = *x;    /* save the value at address x */
   *x = *y;   /* put y into x */
   *y = z;    /* put z into y */

   return 0;
}

Example

main() function 有两个变量“a”和“b”,它们的地址作为参数传递给 swap() 函数。

#include <stdio.h>

int swap(int *x, int *y);

int main(){

   /* local variable definition */
   int a = 10;
   int b = 20;

   printf("Before swap, value of a : %d\n", a);
   printf("Before swap, value of b : %d\n", b);

   /* calling a function to swap the values */
   swap(&a, &b);

   printf("After swap, value of a: %d\n", a);
   printf("After swap, value of b: %d\n", b);

   return 0;
}

执行后,它将生成以下输出:

Before swap, value of a: 10
Before swap, value of b: 20
After swap, value of a: 20
After swap, value of b: 10

在本程序中,我们已经能够交换传递给它的函数作用域之外的两个变量的值,并且我们能够克服该函数只能传递一个表达式的限制。

For Passing an Array to Function

让我们通过引用对 passing the array 使用这些特性。在 main() 函数中,我们声明一个数组并将它的地址传递给 max() 函数。

max() 函数使用指针遍历数组并将数组中最大的数字返回给 main() 函数。

Example

请看以下示例:

#include <stdio.h>

int max(int *arr, int length);

int main(){

   int arr[] = {10, 34, 21, 78, 5};
   int length = sizeof(arr)/sizeof(int);

   int maxnum = max(arr, length);
      printf("max: %d", maxnum);
}

int max(int *arr, int length){

   int max = *arr;

   for (int i = 0; i < length; i++){
      printf("arr[%d]: %d\n", i, (*arr));

      if ((*arr)>max)
         max = (*arr);
      arr++;
   }
   return max;
}

运行代码并检查其输出:

arr[0]: 10
arr[1]: 34
arr[2]: 21
arr[3]: 78
arr[4]: 5
max: 78

max() 函数从 main() 函数接收数组的地址,并将其存储在指针 "arr". 中。每次该指针递增时,它都会指向原始数组中的下一个元素。

For Returning Multiple Values from a Function

在 C 语言中,函数只能有一个 return statement ,一次只返回一个值。借助 C 指针,您可以通过将参数作为引用传递,从一个函数返回多个值。

Example

下面的示例演示了如何借助 C 指针返回多个值。

#include <stdio.h>

// Creating a function to find
// addition and subtraction
// of two numbers
void funAddSub(int a, int b, int* add, int* sub) {
  *add = a + b;
  *sub = a - b;
}

int main() {
  int num1 = 10;
  int num2 = 3;

  // Variables to store results
  int res1, res2;

  // Calling function to get add and sub
  // by passing the address of res1 and res2
  funAddSub(num1, num2, &res1, &res2);

  // Printing the result
  printf("Addition is %d and subtraction is %d", res1, res2);

  return 0;
}
Addition is 13 and subtraction is 7