integer/structure 数组结束?

End of integer/structure array?

Consider the following functions
void alloco(int **ppa)
{
    int i;
    printf("inside alloco %d\n",ppa); /*this function allocates and fills 20 * sizeof(int) bytes */
    *ppa = (int *)malloc(20 * sizeof(int));
    /*fill all 20 * sizeof(int) bytes */
}

int main()
{
    int *app = NULL;
    int i;
    printf("inside main\n");
    alloco(&app);
    for(i=0;i<20;i++) /*ISSUE::how will i know to traverse only 20 indexes?*/
    printf("app[%d] = %d \n", i, app[i]);
    return(0);
}

基本上 main() 将如何知道要遍历的字节数,即 alloco() 函数分配的内存。字符数组中是否有NULL之类的分隔符?

那是不可能的,您需要将该值保存在某处,例如您可以这样做,

void alloco(int **ppa, int count)
{
    int i;

    printf("inside alloco %d\n",ppa);
    *ppa = malloc(count * sizeof(int));
    if (*ppa == NULL)
        return;
    for (i = 0 ; i < count ; ++i)
        /* fill it here. */
}

int main()
{
    int *app;
    int  i;
    int  count;

    count = 20;
    app = NULL;
    printf("Inside main\n");
    alloco(&app, count);
    if (app == NULL)
        return -1;    
    for (i = 0 ; i < count ; i++)
        printf("app[%d] = %d \n", i, app[i]);
    /* done with `app' */
    free(app);
    return 0;
}

许多其他组合也可以,例如

int alloco(int **ppa)
{
    int i;

    printf("inside alloco %d\n",ppa);
    *ppa = malloc(20 * sizeof(int));
    if (*ppa == NULL)
        return;
    for (i = 0 ; i < count ; ++i)
        /* fill it here. */
    return 20;
}

int main()
{
    int *app;
    int  i;
    int  count;

    printf("Inside main\n");

    app = NULL;
    count = alloco(&app);
    if (app == NULL)
        return -1;    
    for (i = 0 ; i < count ; i++)
        printf("app[%d] = %d \n", i, app[i]);
    /* done with `app' */
    free(app);
    return 0;
}

但我个人不喜欢这样,因为如果要有固定数量的整数,那么只使用 malloc() 并不是一个好主意,

int main()
{
    int  app[20];
    int  i;

    printf("Inside main\n");    
    for (i = 0 ; i < sizeof(app) / sizeof(app[0]) ; i++)
        printf("app[%d] = %d \n", i, app[i]);
    return 0;
}

Is there any delimiter like NULL in character arrays?

如果你定义一个,是的。

但这只有在您的用例不需要所有可能的整数值时才有可能。

例如,如果您只需要包括 0 在内的正值,您可以将 -1 的值定义为 "End-of-Array" 标记。

然后,您将再分配一个元素给数组,然后将 -1 分配给这个额外的最后一个数组元素。

示例:

#include <stdlib.h> /* for malloc */
#include <errno.h> /* for errno */

#define EOA (-1)

int array_allocate(int ** ppi)
{
  int result = 0;

  if (NULL = ppi)
  {
    result = -1;
    errno = EINVAL;
  }
  else
  {
    size_t number_of_elements = ...; /* Assign some positive value here. */

    *ppi = malloc((number_of_elements + 1) * sizeof ** ppi);
    if (NULL == *ppi)
    {
      result = -1;
    }
    else
    {
      (*ppi)[number_of_elements] = EOA;
    }
  }

  return result;
}

ssize_t array_number_of_elements(int * pi)
{
  int result = 0;

  if (NULL == pi)
  {
    result = -1;
    errno = EINVAL;
  }
  else
  {
    int * pi_tmp = pi;
    while (EOA != *pi_tmp)
    {
      ++pi_tmp;
    }

    result = pi_tmp - pi;
  }

  return result;
}

这样使用:

#include <stdlib.h> /* for size_t and ssize_t */
#include <stdio.h> /* for printf and perror */

int array_allocate(int **);
ssize_t array_number_of_elements(int *);

int main(void)
{
  int result = EXIT_SUCCESS;
  int * pi = NULL;

  if (-1 == array_allocate(&pi))
  {
    result = EXIT_FAILURE;
    perror("array_allocate() failed");
  }
  else
  {
    ssize_t result_number_of_elements = array_number_of_elements(pi);
    if (-1 == result_number_of_elements)
    {
      result = EXIT_FAILURE;
      perror("array_number_of_elements() failed");
    }
    else
    {
      size_t number_of_elements = result_number_of_elements;
      printf("The number of array's elements is %zu.\n", 
        number_of_elements);
    }
  }

  free(pi); /* Clean up. */

  return result;
}

需要成为三星级程序员

您可以轻松地在函数中分配一些固定数量的元素(小于最大值),而无需在调用函数和被调用方之间传递元素数量。但是,它需要创建一个 指向类型 How/Why 的指针的指针数组?本质上,您将数组视为以空字符结尾的字符串,最初将数组中所有指向类型的指针分配给 NULL 并仅在需要时为它们分配 space 。 (使用 calloc 进行分配使这变得轻而易举)当数组在调用方中重新使用时,它允许迭代所有 filled 值,直到到达第一个空指针。

现在授予,

simply passing a pointer to size as an additional argument to your function makes much more sense [1]

并消除了对三星级评级的需求,但出于示例目的,请暂时享受成为 3 星程序员 的乐趣:

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

#define INITSZ 21

void alloco (int ***ppa)
{
    printf("inside %s\n", __func__);

    int i = 0;

    /* allocate 21 pointers-to-int */
    if (!(*ppa = calloc (INITSZ, sizeof **ppa))) {
        fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
        exit (EXIT_FAILURE);
    }

    /* allocate/fill 20 values (or anything less than 21) */
    for (i = 0; i < INITSZ - 1; i++) {
        if (!((*ppa)[i] = calloc (1, sizeof ***ppa))) {
            fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
            exit (EXIT_FAILURE);
        }
        *((*ppa)[i]) = i * 2;
    }
}

int main()
{
    int **app = NULL;
    int i = 0;

    printf ("inside main\n");
    alloco (&app);

    /*ISSUE::how will i know to traverse only 20 indexes?*/

    while (app[i]) {
        printf("app[%d] = %d \n", i, *(app[i]));
        i++;
    }

    return(0);
}

Use/Output

$ ./bin/alloc_array+1
inside main
inside alloco
app[0] = 0
app[1] = 2
app[2] = 4
app[3] = 6
app[4] = 8
app[5] = 10
app[6] = 12
app[7] = 14
app[8] = 16
app[9] = 18
app[10] = 20
app[11] = 22
app[12] = 24
app[13] = 26
app[14] = 28
app[15] = 30
app[16] = 32
app[17] = 34
app[18] = 36
app[19] = 38

脚注 [1]: 为清楚起见,在引用中添加了强调,即此解决方案旨在展示什么是可能的,而不是什么是最有效或最实用的。