你如何在C中创建一个指针数组?

时间:2018-04-24 23:20:18

标签: c arrays pointers

如何创建指针数组,其中每个元素都包含指向其他值的指针

例如,如果我有

int** arr[5] = {0xbfjeabfbfe,0x...}; //is it the right way to do it?

数组类型void意味着什么?比如void **newArray[5];

让我们说我想使用malloc或calloc为一组指针动态分配内存!语法是什么?

3 个答案:

答案 0 :(得分:2)

  

如何在C中创建指针数组?

要在C中创建指针数组,您有一个选项,您声明:

  type *array[CONST];  /* create CONST number of pointers to type */

使用C99 +,您可以创建指针的可变长度数组(VLA),例如

  type *array[var];   /* create var number of pointers to type */

标准在C11 Standard - 6.7.6.2 Array declarators中定义,并在C11 Standard - 6.5.2.1 Array subscripting中讨论下标。

使用指针数组的简短示例,将指向2D数组中每一行的指针指定给指向int的指针数组,例如

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

#define COL 3
#define MAX 5

int main (void) {

    int arr2d[MAX][COL] = {{ 0 }},  /* simple 2D array */
        *arr[MAX] = { NULL },       /* 5 pointers to int */
        i, j, v = 0;

    for (i = 0; i < MAX; i++) {     /* fill 2D array */
        for (j = 0; j < COL; j++)
            arr2d[i][j] = v++;
        arr[i] = arr2d[i];          /* assing row-pointer to arr */
    }

    for (i = 0; i < MAX; i++) {     /* for each pointer */
        for (j = 0; j < COL; j++)   /* output COL ints */
            printf (" %4d", arr[i][j]);
        putchar ('\n');
    }
}

示例使用/输出

$ ./bin/array_ptr2int_vla
    0    1    2
    3    4    5
    6    7    8
    9   10   11
   12   13   14

C的另一个基本原理是指向指针,但它不是&#34;数组&#34;,虽然它通常被称为&#34;动态数组&#34 ;并且可以分配和索引模拟数组。 &#34;数组&#34;之间的区别并且指针的集合是带有数组的指针,所有值都保证在内存中是连续的 - 没有这样的保证,指针集合和它们引用的内存位置。

那么int **arr[CONST]宣告什么?

在你的问题中,你提出了int** arr[5] = {0xbfjeabfbfe,0x...};的声明,那么这声明了什么?你宣布了​​五件事,但是什么?您正在声明五个指向指针指向的指针。你能做到吗?肯定。

那么你用指针指向什么做什么呢?指向poitner的指针构成动态分配和重新分配类型集合的主干。它们通常被称为&#34;动态分配的数组&#34;,但这有点用词不当,因为无法保证所有值都在内存中顺序。您将向数组中的每个int**声明一定数量的指针。您不必分配相同数量的指针。

注意:不能保证指针所指向的内存甚至是连续的,尽管指针本身就是 - 确保你理解这种区别以及&#34 ;数组&#34;保证和指示什么?

int** arr[5]声明五个int**。然后,只要类型为int**,您就可以自由地为五个指针中的每一个指定任何地址。例如,您将为您的指针分配类似于:

的内容
  arr[i] = calloc (ROW, sizeof *arr[i]);  /* allocates ROW number of pointers */

然后你可以自由地分配任意数量的int并将该地址分配给每个指针,例如

  arr[i][j] = calloc (COL, sizeof *arr[i][j]); /* allocates COL ints */

然后,您可以遍历整数分配值:

  arr[i][j][k] = v++;

使用int** arr[5]类型分配的简短示例可能类似于:

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

#define ROW 3
#define COL ROW
#define MAX 5

int main (void) {

    int **arr[MAX] = { NULL },  /* 5 pointer-to-pointer-to-int */
        i, j, k, v = 0;

    for (i = 0; i < MAX; i++) { /* allocate ROW pointers to each */
        if ((arr[i] = calloc (ROW, sizeof *arr[i])) == NULL) {
            perror ("calloc - pointers");
            return 1;
        }
        for (j = 0; j < ROW; j++) { /* allocate COL ints each pointer */
            if ((arr[i][j] = calloc (COL, sizeof *arr[i][j])) == NULL) {
                perror ("calloc - integers");
                return 1;
            }
            for (k = 0; k < COL; k++)   /* assign values to ints */
                arr[i][j][k] = v++;
        }
    }

    for (i = 0; i < MAX; i++) { /* output each pointer-to-pointer to int */
        printf ("pointer-to-pointer-to-int: %d\n\n", i);
        for (j = 0; j < ROW; j++) {     /* for each allocated pointer */
            for (k = 0; k < COL; k++)   /* output COL ints */
                printf ("  %4d", arr[i][j][k]);
            free (arr[i][j]);   /* free the ints */
            putchar ('\n');
        }
        free (arr[i]);      /* free the pointer */
        putchar ('\n');
    }

    return 0;
}

您已经为五个模拟的2D数组分配了指向每个int **arr[5]数组的指针,输出将为:

示例使用/输出

$ ./bin/array_ptr2ptr2int
pointer-to-pointer-to-int: 0

     0     1     2
     3     4     5
     6     7     8

pointer-to-pointer-to-int: 1

     9    10    11
    12    13    14
    15    16    17

pointer-to-pointer-to-int: 2

    18    19    20
    21    22    23
    24    25    26

pointer-to-pointer-to-int: 3

    27    28    29
    30    31    32
    33    34    35

pointer-to-pointer-to-int: 4

    36    37    38
    39    40    41
    42    43    44

希望这有助于区分指针数组和指针数组,并显示如何声明和使用每个指针。如果您有任何其他问题,请不要犹豫。

答案 1 :(得分:1)

指向int的指针数组;

int x = 1;
int y = 42;
int z = 12;

int * array[3];

array[0] = &x;
array[1] = &y;
array[2] = &z;

替代语法

int * array[] = {&x,&y,&z};
保持简单。从那里向上工作

答案 2 :(得分:1)

  

如何创建指针数组,其中每个元素都包含指向其他值的指针

数组数组可以作为3D矩阵

int*** arr;    // Points to an array of arrays (3 Dimensions)
int** arr[0];  // Points to an array           (2 Dimensions)
int* arr[0][0];// Points to a single element   (1 Dimension)

如果您事先知道尺寸,可以像这样初始化3D数组:

int arr[2][2][2] = {
   { {1, 2}, {3, 4} },
   { {5, 6}, {7, 8} },
}

但它对非平凡的n维数组来说不太可读。另一种方法是遍历每个维度。

int*** arr;
int dimensions = 10;

arr = malloc(dimensions * sizeof(int**)); // Allocate an array of 2D arrays

for (int i = 0; i < dimensions; i++) {
  arr[i] = malloc(dimensions * sizeof(int*)); // Allocate an array of arrays 

  for (int j = 0; j < dimensions; j++) {
      arr[i][j] = malloc(dimensions * sizeof(int)); // Allocate array

      for (int k = 0; k < dimensions; k++) {
          arr[i][j][k] = 0; // Fill each element with 0's
      }
  }
}

这种方法还可以动态分配数组。

  

拥有数组类型的void意味着什么?像void ** newArray [5];

void*是指向未知类型的指针。如果int*表示指向int的指针,void*表示指向类型未知的值的指针。