简体   繁体   English

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

[英]How do you create an array of pointers in C?

How do I create an array of pointers where each element holds a pointer to some other value 我如何创建一个指针数组,其中每个元素都包含一个指向其他值的指针

For example if I have 例如,如果我有

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

And what it means to have an array type of void ? 数组类型为void意味着什么? like void **newArray[5]; void **newArray[5];

And let's say I want to dynamically allocate memory for an array of pointers using malloc or calloc!! 假设我想使用malloc或calloc为指针数组动态分配内存! What will be the syntax be? 语法是什么?

How do you create an array of pointers in C? 您如何在C中创建一个指针数组?

To create an array of pointers in C, you have one option, you declare: 要在C中创建一个指针数组,您有一个选择,您需要声明:

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

With C99+ you can create a Variable Length Array (VLA) of pointers, eg 使用C99 +,您可以创建指针的可变长度数组 (VLA),例如

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

The standard defines both in C11 Standard - 6.7.6.2 Array declarators and discusses subscripting in C11 Standard - 6.5.2.1 Array subscripting . 该标准在C11标准6.7.6.2数组声明符中进行了定义,并讨论了C11标准6.5.2.1数组下标中的下标

A short example using an array of pointers, assigning a pointer to each row in a 2D array to an array of pointers to int , eg 一个使用指针数组的简短示例,将指向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');
    }
}

Example Use/Output 使用/输出示例

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

Another fundamental of C is the pointer-to-pointer , but it is not an "Array", though it is routinely called a "dynamic array" and can be allocated and indexed simulating an array. C的另一个基础是指针到指针 ,但它不是“数组”,尽管它通常被称为“动态数组”,并且可以模拟数组来进行分配和索引。 The distinction between an "Array" and a collection of pointers is that with an Array, all values are guaranteed to be sequential in memory -- there is no such guarantee with a collection of pointers and the memory locations they reference. “数组”和指针集合之间的区别在于,使用数组时,保证所有值在内存中都是顺序的—指针集合和它们引用的内存位置没有这样的保证。

So What Does int **arr[CONST] Declare? 那么int **arr[CONST]声明什么呢?

In your question you posit a declaration of int** arr[5] = {0xbfjeabfbfe,0x...}; 在您的问题中,您提出了一个int** arr[5] = {0xbfjeabfbfe,0x...}; , so what does that declare? ,那说明什么呢? You are declaring Five of something, but what? 您是在声明五件事,但是呢? You are declaring five pointer-to-pointer-to-int . 您要声明五个指向int的指针 Can you do that? 你能做到吗? Sure. 当然。

So what do you do with a pointer-to-pointer-to-something ? 那么,如何使用指针指向某物呢? The pointer-to-poitner forms the backbone of dynamically allocated and reallocated collection of types. 指向指针的指针构成了动态分配和重新分配的类型集合的主干。 They are commonly termed "dynamically allocated arrays", but that is somewhat a misnomer, because there is no guarantee that all values will be sequential in memory. 它们通常被称为“动态分配的数组”,但这有点用词不当,因为不能保证所有值在内存中都是顺序的。 You will declare a given number of pointers to each int** in the array. 您将为数组中的每个int**声明给定数量的指针。 You do not have to allocate an equal number of pointers. 您不必分配相等数量的指针。

( note: there is no guarantee that the memory pointed to by the pointers will even be sequential, though the pointers themselves will be -- make sure you understand this distinction and what an "Array" guarantees and what pointers don't) 请注意:尽管指针本身是可以保证的,但不能保证指针所指向的内存甚至是顺序的。请确保您了解这种区别,并确保“数组”可以保证什么,而指针不能做到)

int** arr[5] declares five int** . int** arr[5]声明了五个int** You are then free to assign any address to you like to each of the five pointers, as long as the type is int** . 然后,您可以随意为五个指针中的每一个分配任意地址,只要类型为int** For example, you will allocate for your pointers with something similar to: 例如,您将使用类似于以下内容的指针分配指针:

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

Then you are free to allocate any number of int and assign that address to each pointer, eg 然后,您可以自由分配任意数量的int并将该地址分配给每个指针,例如

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

You can then loop over the integers assigning values: 然后,您可以遍历分配值的整数:

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

A short example using your int** arr[5] type allocation could be similar to: 一个使用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;
}

You have allocated for five simulated 2D arrays assigning the pointer to each to your array of int **arr[5] , the output would be: 您已分配了五个模拟的2D数组,将每个指针分配给您的int **arr[5]数组,其输出为:

Example Use/Output 使用/输出示例

$ ./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

Hopefully this has helped with the distinction between an array of pointers, and an array of pointers-to-pointer and shown how to declare and use each. 希望这有助于区分指针数组和指针对指针数组,并说明了如何声明和使用每个指针。 If you have any further questions, don't hesitate to ask. 如果您还有其他问题,请随时提出。

An array of pointers to ints; 指向int的指针数组;

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

int * array[3];

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

alternate syntax 替代语法

int * array[] = {&x,&y,&z};

keeping it simple. 保持简单。 Work upwards from there 从那里向上工作

How do I create an array of pointers where each element holds a pointer to some other value 我如何创建一个指针数组,其中每个元素都包含一个指向其他值的指针

An array of arrays can be though of as a 3D matrix 数组的数组可以看作是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)

If you know the size before hand you can initialize a 3D array like this: 如果您事先知道大小,则可以像这样初始化3D数组:

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

But its not very readable for non trivial n-dimensional arrays. 但是对于非平凡的n维数组,它的可读性不是很高。 Another approach is to loop over each dimension. 另一种方法是遍历每个维度。

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
      }
  }
}

This approach also lets to dynamically allocate the arrays. 这种方法还可以动态分配数组。

And what it means to have an array type of void? 数组类型为void意味着什么? like void **newArray[5]; 像void ** newArray [5];

void* is a pointer to an unknown type. void*是指向未知类型的指针。 If int* means a pointer to an int, void* means a pointer to a value who's type is unknown. 如果int*表示指向int*的指针,则void*表示指向类型未知的值的指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM