返回一个数组,同时告诉他这个数组的长度?

时间:2021-07-09 04:01:57

I want to filter an strings array passed in, something like this:

我想过滤传入的字符串数组,如下所示:

char **
filter_vids(char **vids, size_t n) {
    int i;
    int count = 0;
    char ** filted = malloc(n * sizeof(char *));
    for(i = 0; i < n; i++){
        filted[i] = (char*)malloc(50 * sizeof(char));
    }
    for(i = 0; i < n; i++) {
        if(some_filter(vids[i])) {
            strcpy(filted[count++], vids[i]);
            printf("in filter:%s\n", vids[i]);
        }
    }
    return filted;
}

But the caller may not known the length of return array, it's extractly the counter variable, so what's the best practice of returning an array while telling him the right length of array? such as

但调用者可能不知道返回数组的长度,它可以解析为计数器变量,那么在告诉他数组的正确长度的同时返回数组的最佳做法是什么?如

char **
filter_vids(char **vids, size_t n, int *output_length)

It's the best practice of using output_length?

这是使用output_length的最佳做法?

I edit this function to this, as your suggestions: char ** filter_vids(char **vids, size_t n) { int i; int count = 0; char ** filted = malloc((n + 1) * sizeof(char *)); for(i = 0; i < n; i++) { if(vids[i][0] <= 'f') { filted[count++] = strdup(vids[i]); } } filted[count] = NULL; return filted; }

我编辑这个函数,作为你的建议:char ** filter_vids(char ** vids,size_t n){int i; int count = 0; char ** filted = malloc((n + 1)* sizeof(char *)); for(i = 0; i ;>

2 个解决方案

#1


1  

To pass a pointer to an integer length variable whose value is then set in the function is certainly a good way. As Malcolm said, it is also general and can be used for sets of values which do not have an "invalid" member.

要传递一个指向整数长度变量的指针,该变量的值然后在函数中设置肯定是一个好方法。正如Malcolm所说,它也是通用的,可以用于没有“无效”成员的值集。

In the case of pointers with their invalid null pointer value one can mark the end of valid entries with a null pointer. For example, the array of string pointers which the C run time uses to pass command line arguments to main is thus terminated.

对于具有无效空指针值的指针,可以使用空指针标记有效条目的结尾。例如,C运行时用于将命令行参数传递给main的字符串指针数组因此终止。

Which method to choose depends a little on how the caller wants to use the resulting array. If it is processed sequentially, a (while *p){ ..; ++p; } feels idiomatic. If, on the other hand, you need random access and must perform the equivalent of a strlen before you can do anything with the array, then it is probably better to return the length via a pointed-to length variable right away.

选择哪种方法取决于调用者如何使用结果数组。如果按顺序处理,则a(而* p){..; ++磷;感觉惯用。另一方面,如果您需要随机访问并且必须在对数组执行任何操作之前执行等效的strlen,那么最好通过指向长度的变量返回长度。

Two remarks:

First, note the difference between

首先,注意区别

  • a valid pointer to an empty string (if somebody called, let's say, myProg par1 "" par2, argv[2] could be a valid pointer to a zero byte);
  • 一个指向空字符串的有效指针(如果有人调用,让我们说,myProg par1“”par2,argv [2]可能是一个指向零字节的有效指针);

  • and a null pointer which is pointing nowhere; in the example, argv[4] would be the null pointer, indicating the end of the argument list.
  • 和一个无处指向的空指针;在示例中,argv [4]将是空指针,指示参数列表的结尾。

Second, You malloc more memory than you need which is wasteful in the case of longer strings and/or strict filters. You could instead allocate the string on demand inside the if clause.

其次,你需要更多的内存而不是你需要的东西,这在更长的字符串和/或严格的过滤器的情况下是浪费的。您可以在if子句中按需分配字符串。

#2


1  

These are common options:

这些是常见选项:

  1. Receive the allowed size as parameter by pointer, overwrite it with the actual size, return the array as return value.
  2. 通过指针接收允许的大小作为参数,用实际大小覆盖它,返回数组作为返回值。

  3. Receive the output array as parameter by pointer, update as required, return the actual size as return value.
  4. 通过指针接收输出数组作为参数,根据需要更新,返回实际大小作为返回值。

  5. Append a sentinel value to the output array (here a null pointer), as suggested in the other answer.
  6. 将sentinel值附加到输出数组(此处为空指针),如另一个答案中所建议的那样。

  7. Use a more sophisticated data structure as a return value. You could use a struct, which stores the size alongside the array or a linked list.
  8. 使用更复杂的数据结构作为返回值。您可以使用结构,该结构存储数组旁边的大小或链接列表。

Example (untested):

typedef char* mystring;
typedef mystring* mystringarray;
typedef struct { mystringarray *arr; size_t size } mysizedstringarray;

/* returns filtered array, size will be updated to reflect the valid size */
mystringarray* myfun1(mystringarray in, size_t* size);

/* out will be allocated and populated, actual size is returned */
size_t myfun2(mystringarray in, size_t size, mystringarray* out);

/* output array contains valid items until sentinel value (NULL) is reached */
mystringarray* myfun3(mystringarray in, size_t size);

/* returns filtered array with actual size */
mysizedstringarray myfun4(mystringarray in, size_t size);

#1


1  

To pass a pointer to an integer length variable whose value is then set in the function is certainly a good way. As Malcolm said, it is also general and can be used for sets of values which do not have an "invalid" member.

要传递一个指向整数长度变量的指针,该变量的值然后在函数中设置肯定是一个好方法。正如Malcolm所说,它也是通用的,可以用于没有“无效”成员的值集。

In the case of pointers with their invalid null pointer value one can mark the end of valid entries with a null pointer. For example, the array of string pointers which the C run time uses to pass command line arguments to main is thus terminated.

对于具有无效空指针值的指针,可以使用空指针标记有效条目的结尾。例如,C运行时用于将命令行参数传递给main的字符串指针数组因此终止。

Which method to choose depends a little on how the caller wants to use the resulting array. If it is processed sequentially, a (while *p){ ..; ++p; } feels idiomatic. If, on the other hand, you need random access and must perform the equivalent of a strlen before you can do anything with the array, then it is probably better to return the length via a pointed-to length variable right away.

选择哪种方法取决于调用者如何使用结果数组。如果按顺序处理,则a(而* p){..; ++磷;感觉惯用。另一方面,如果您需要随机访问并且必须在对数组执行任何操作之前执行等效的strlen,那么最好通过指向长度的变量返回长度。

Two remarks:

First, note the difference between

首先,注意区别

  • a valid pointer to an empty string (if somebody called, let's say, myProg par1 "" par2, argv[2] could be a valid pointer to a zero byte);
  • 一个指向空字符串的有效指针(如果有人调用,让我们说,myProg par1“”par2,argv [2]可能是一个指向零字节的有效指针);

  • and a null pointer which is pointing nowhere; in the example, argv[4] would be the null pointer, indicating the end of the argument list.
  • 和一个无处指向的空指针;在示例中,argv [4]将是空指针,指示参数列表的结尾。

Second, You malloc more memory than you need which is wasteful in the case of longer strings and/or strict filters. You could instead allocate the string on demand inside the if clause.

其次,你需要更多的内存而不是你需要的东西,这在更长的字符串和/或严格的过滤器的情况下是浪费的。您可以在if子句中按需分配字符串。

#2


1  

These are common options:

这些是常见选项:

  1. Receive the allowed size as parameter by pointer, overwrite it with the actual size, return the array as return value.
  2. 通过指针接收允许的大小作为参数,用实际大小覆盖它,返回数组作为返回值。

  3. Receive the output array as parameter by pointer, update as required, return the actual size as return value.
  4. 通过指针接收输出数组作为参数,根据需要更新,返回实际大小作为返回值。

  5. Append a sentinel value to the output array (here a null pointer), as suggested in the other answer.
  6. 将sentinel值附加到输出数组(此处为空指针),如另一个答案中所建议的那样。

  7. Use a more sophisticated data structure as a return value. You could use a struct, which stores the size alongside the array or a linked list.
  8. 使用更复杂的数据结构作为返回值。您可以使用结构,该结构存储数组旁边的大小或链接列表。

Example (untested):

typedef char* mystring;
typedef mystring* mystringarray;
typedef struct { mystringarray *arr; size_t size } mysizedstringarray;

/* returns filtered array, size will be updated to reflect the valid size */
mystringarray* myfun1(mystringarray in, size_t* size);

/* out will be allocated and populated, actual size is returned */
size_t myfun2(mystringarray in, size_t size, mystringarray* out);

/* output array contains valid items until sentinel value (NULL) is reached */
mystringarray* myfun3(mystringarray in, size_t size);

/* returns filtered array with actual size */
mysizedstringarray myfun4(mystringarray in, size_t size);