简体   繁体   English

如何将字符串数组传递给 function?

[英]How to pass a string array to a function?

I've declared:我已经宣布:

char array_slave_1[128][128];


int array_length(char *a[]){
    int i = 0;
    while(a[i] != NULL){
        i++;
    }
    return i;
}

    int x = array_length(array_slave_1);

I obtain:我得到:

main.c:101:26: warning: passing argument 1 of ‘array_length’ from incompatible pointer type [-Wincompatible-pointer-types]
  101 |     int x = array_length(array_slave_1);
      |                          ^~~~~~~~~~~~~
      |                          |
      |                          char (*)[128]
main.c:16:24: note: expected ‘char **’ but argument is of type ‘char (*)[128]’
   16 | int array_length(char *a[]){

I'm not sure if it is correct the way of passing the argument to the function I declared...I think the the problem is this one, but I don't know how to correctly implement the function array_lenght.我不确定将参数传递给我声明的 function 的方式是否正确......我认为问题出在这个问题上,但我不知道如何正确实现 function array_lenght。

char array_slave_1[128][128]

This is 2-dimensional array of char as paramter:这是 char 作为参数的二维数组:

int array_length(char *a[])

This is array of pointers to char (which might be C strings, but could be other char/byte buffers, or single chars too).这是指向 char 的指针数组(可能是 C 字符串,但也可能是其他字符/字节缓冲区或单个字符)。 Except because it is a function parameter, it really is pointer to pointer, so if you are a novice you'd be better off writing what it really is, to avoid getting confused:除了因为它是一个 function 参数外,它实际上是指向指针的指针,所以如果您是新手,最好写出它的真正含义,以免混淆:

int array_length(char **a)

Types of array_slave_1 and a are fundamentally different, and incompatible. array_slave_1a的类型根本不同,并且不兼容。


If you want to make your function take the array as parameter, you could do:如果你想让你的 function 将数组作为参数,你可以这样做:

int array_length(char a[][128])

which is same as this (note the extra () compared to code in question, they matter,), because array parameters really are pointers, so you have a pointer to one or more char[128] buffers:这与此相同(请注意与相关代码相比额外的() ,它们很重要),因为数组参数确实是指针,因此您有一个指向一个或多个char[128]缓冲区的指针:

int array_length(char (*a)[128])

Then you need a different way to determine the array length , though.但是,您需要一种不同的方法来确定数组长度 Perhaps empty string means end of strings?也许空字符串意味着字符串的结尾? That's up to you, really.这取决于你,真的。


Alternative is to change your array to be array of pointers:另一种方法是将您的数组更改为指针数组:

char *array_slave_1[128]; // 128 pointers to char buffer or C string
// remember that you must allocate the space of each string!

Perhaps you are just "over complicating" things.也许你只是“过于复杂”的事情。

Here is a "best guess" at what you might be trying to achieve (based on allocating room for 128x strings, each up to 127 bytes (plus a null terminator.)这是您可能要实现的目标的“最佳猜测”(基于为 128x 字符串分配空间,每个字符串最多 127 个字节(加上 null 终止符。)

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

int main() {
    char array_slave_1[ 128 ][ 127 + 1 ]; // notation helps signify this is a string

    strcpy( array_slave_1[ 0 ], "Hello World!" );
    strcpy( array_slave_1[ 1 ], "Foobar" );

    for( int i = 0; i < 2; i++ )
        printf( "'%s' length %d\n", array_slave_1[ i ], strlen( array_slave_1[ i ] ) );

    return 0;
}

Output Output

'Hello World!' length 12
'Foobar' length 6

strlen() has already been done in the standard C library. strlen()已经在标准 C 库中完成。

  • char array_slave_1[128][128]; is an array of arrays of char , often called 2D array.char的 arrays 的数组,通常称为二维数组。
  • char *a[] is an array of pointers to char . char *a[]是指向char的指针数组。 It is not compatible with a 2D array.它与二维数组不兼容。

When an array in C used in most expressions, or when declared as a function parameter, it "decays" into a pointer to it's first element.当 C 中的数组在大多数表达式中使用时,或者当声明为 function 参数时,它“衰减”为指向它的第一个元素的指针。

  • For a plain char array[x] , the first element is char and so it decays to a pointer to char : char* .对于普通的char array[x] ,第一个元素是char ,因此它衰减为指向char的指针: char*
  • For an array of arrays char array[x][y] , the first element is an array char [y] .对于 arrays char array[x][y]的数组,第一个元素是数组char [y] So it decays into a pointer to such an array, char (*)[y] .所以它衰减成一个指向这样一个数组的指针, char (*)[y] This decay happens to the array you pass as argument, as well as to any 2D array declared as function parameter.这种衰减发生在您作为参数传递的数组以及声明为 function 参数的任何二维数组上。

Thus:因此:

void func (char array[128][128]);
...
char array [128][128];
func(array);

Which is 100% equivalent to: 100% 相当于:

void func (char (*array)[128]);
...
char array [128][128];
char(*ptr)[128] = array;
func(array);

So for accepting a 2D array, you may declare the function using either of the above equivalent forms, though the latter is less readable.因此,为了接受二维数组,您可以使用上述等效的 forms 中的任何一个来声明 function,尽管后者的可读性较差。 The most generic and readable form of all might however be a variable-length array:然而,最通用和可读的形式可能是可变长度数组:

void func (size_t x, size_t y, char array[x][y]);

Please also note that while(a[i] != NULL) will only work for arrays of pointers , where the last pointer was assigned to NULL, a so-called "sentinel value".另请注意, while(a[i] != NULL)仅适用于指针的 arrays ,其中最后一个指针分配给 NULL,即所谓的“哨兵值”。 You cannot use this unless you keep the function as char* arr[n] and then pass an array of pointers as argument instead.除非您将 function 保留为char* arr[n]然后将指针数组作为参数传递,否则您不能使用它。

How to pass a string array to a function?如何将字符串数组传递给 function?

That depends on what you mean by "string array", because it turns out that there are, sort of, two completely different types of "string" in C.这取决于您所说的“字符串数组”是什么意思,因为事实证明 C 中有两种完全不同类型的“字符串”。 Formally, a string is an array of characters.形式上,字符串是一个字符数组。 But since arrays almost always decay into pointers when you use them, it is extremely common to think about char * — that is, pointer-to- char — as also being a "string type" in C.但是由于 arrays 在使用它们时几乎总是衰减为指针,因此非常普遍地认为char * (即指向char的指针)也是 C 中的“字符串类型”。

char array_slave_1[128][128];

This is an array of arrays of char .这是char的 arrays 数组。 So it is usefully an array of strings, using the array definition of "string".所以它是一个有用的字符串数组,使用“字符串”的数组定义。 It does have the limitation that none of the strings it contains can ever be longer than 127 characters.它确实有一个限制,它包含的任何字符串都不能超过 127 个字符。

int array_length(char *a[]) {...

This function accepts an array of pointers to char .这个 function 接受指向char的指针数组。 So it is also usefully an array of strings, using the pointer definition of "string".所以它也是一个有用的字符串数组,使用“字符串”的指针定义。 It is further apparent that you are trying to use an array of pointers here given that you are looking for a NULL pointer to mark the end of the array.更明显的是,鉴于您正在寻找NULL指针来标记数组的结尾,因此您正在尝试在此处使用指针数组。

But!但! In this case, the two different types of "array of string" are not compatible.在这种情况下,两种不同类型的“字符串数组”是兼容的。 An array of arrays is completely different from an array of pointers, There are no automatic conversions that will let you start with one. arrays 数组与指针数组完全不同,没有自动转换可以让您从一个开始。 and treat it as if it was the other.并把它当作另一个。

(This is by contrast to the situation with simple, single strings, since the array-decay-to-pointer rule always lets you treat an array-string as if it were a pointer-string.) (这与简单的单个字符串的情况形成对比,因为数组衰减到指针规则总是让您将数组字符串视为指针字符串。)

Your best bet is probably to change你最好的选择可能是改变

char array_slave_1[128][128];

to

char *array_slave_1[128];

Now you have an array of 128 pointer-strings.现在你有一个包含 128 个指针字符串的数组。 This will be compatible with your array_length function, and it will remove the limitation on the lengths of the individual strings in the array.这将与您的array_length function 兼容它将消除对数组中各个字符串长度的限制。 On the other hand, you will need to change any code you have for initializing and manipulating the string in array_slave_1 : Some of that code may still be fine, but anything that involves something like strcpy(array_slave_1[i], ...) will have to change.另一方面,您将需要更改用于初始化和操作array_slave_1中的字符串的任何代码:其中一些代码可能仍然可以,但是任何涉及诸如strcpy(array_slave_1[i], ...)之类的代码都会必须改变。 Depending on your needs, you may also need to call malloc to allocate space for each element in the array to point to.根据您的需要,您可能还需要调用malloc为数组中要指向的每个元素分配空间。

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

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