简体   繁体   English

我可以在 C 中创建一个 Char 指针数组吗?

[英]Can I create an Array of Char pointers in C?

I am new to C, and things are different in C than in any other language I've learned.我是 C 的新手,C 中的东西与我学过的任何其他语言都不同。 In my homework I want to create an array of chars which point to an array of chars, but rather than make a multidimensional char array, I figure I'd have more control and create char arrays and put each individual one into the indexes of the original char array:在我的作业中,我想创建一个指向字符数组的字符数组,而不是创建一个多维字符数组,我想我会有更多的控制权并创建字符数组并将每个单独的数组放入索引中原始字符数组:

char keywords[10];
keywords[0] = "float";

The above example is to clarify and a simple case.上面的例子是为了澄清一个简单的案例。 But my question is due to the research I've been doing, and I am confused about something.但我的问题是由于我一直在做的研究,我对某些事情感到困惑。 Normally this would work in other languages, but in C it would be:通常这适用于其他语言,但在 C 中将是:

char *keyword[10];
keywords[0] = "float";

But when I want to send it through a function, why is this necessary:但是当我想通过一个函数发送它时,为什么有必要:

void function(char **keyword); //function prototype

Wouldn't just passing the array pointer be enough?仅仅传递数组指针是不够的吗?

It looks like you're confused by the double stars in看起来你被里面的双星搞糊涂了

void function(char ** keyword);

The double stars just means that this function expects you to pass a pointer to a pointer to a char .双星只是意味着这个函数希望你传递一个指向 char 的指针的指针 This syntax doesn't include any information about the fact that you are using an array, or that the char is actually the first char of many in a string.此语法不包含有关您正在使用数组或字符实际上是字符串中许多字符的第一个字符这一事实的任何信息。 It's up to you as the programmer to know what kind of data structure this char ** actually points to.作为程序员,您需要知道这个char **实际上指向什么样的数据结构。

For example, let's suppose the beginning of your array is stored at address 0x1000.例如,假设数组的开头存储在地址 0x1000。 The keyword argument to the function should have a value of 0x1000.函数的keyword参数的值应为 0x1000。 If you dereference keyword , you get the first entry in the array, which is a char * that points to the first char in the string "float".如果取消引用keyword ,则会得到数组中的第一个条目,它是指向字符串“float”中第一个char * If you dereference the char * , you get the char "f".如果取消引用char * ,则会得到字符“f”。

The (contrived) code for that would look like:那个(人为的)代码看起来像:

void function(char **keyword)
{
    char * first_string = *keyword;   // *keyword is equivalent to keyword[0]
    char first_char = *first_string;  // *first_string is equivalent to first_string[0]
}

There were two pointers in the example above.上面的例子中有两个指针。 By adding an offset to the first pointer before dereferencing it, you can access different strings in the array.通过在取消引用之前向第一个指针添加偏移量,您可以访问数组中的不同字符串。 By adding an offset to the second pointer before dereferencing it, you can access different chars in the string.通过在取消引用之前向第二个指针添加偏移量,您可以访问字符串中的不同字符。

char *keyword[10];

keyword is an array 10 of char * . keywordchar *的数组 10。 In a value context, it converted to a pointer to a char * .在值上下文中,它转换为指向char *的指针。

This conversion is a part of what Chris Torek calls "The Rule" :这种转换是 Chris Torek 所说的“规则”的一部分

"As noted elsewhere, C has a very important rule about arrays and pointers. This rule -- The Rule -- says that, in a value context, an object of type 'array of T' becomes a value of type 'pointer to T', pointing to the first element of that array" “正如在别处提到的,C 有一个关于数组和指针的非常重要的规则。这条规则——规则——说,在值上下文中,类型为“T 的数组”的对象变成类型为“指向 T 的指针”的值',指向该数组的第一个元素”

See here for more information: http://web.torek.net/torek/c/pa.html请参阅此处了解更多信息: http : //web.torek.net/torek/c/pa.html

The C-FAQ also has an entry on this array to pointer conversion: C-FAQ 也有关于这个数组到指针转换的条目:

Question 6.3: So what is meant by the "equivalence of pointers and arrays'' in C?问题 6.3:那么 C 中“指针和数组的等价性”是什么意思?

http://c-faq.com/aryptr/aryptrequiv.html http://c-faq.com/aryptr/aryptrequiv.html

Here is the answer.这是答案。

#include<stdio.h>

int main(void)
{
        char *CharPtr[3];
        char a[4]="abc";
        char b[4]="def";
        char c[4]="ghi";
        CharPtr[0]=a;
        CharPtr[1]=b;
        CharPtr[2]=c;

        printf("\n content of CharPtr[0] =%s",CharPtr[0]);
        printf("\n content of CharPtr[1] =%s",CharPtr[1]);
        printf("\n content of CharPtr[2] =%s\n",CharPtr[2]);

        printf(" \n content of char a[4]=%s",a);
        printf(" \n content of char b[4]=%s",b);
        printf(" \n content of char c[4]=%s\n",c);
}

In C, you can't really pass array to a function.在 C 中,您不能真正将数组传递给函数。 Instead, you pass a pointer to the beginning of the array.相反,您传递一个指向数组开头的指针。 Since you have array of char* , the function will get a pointer to char* , which is char** .由于您有char*数组,该函数将获得一个指向char*的指针,即char**

If you want, you can write (in the prototype) char *keyword[] instead of char **keyword .如果需要,您可以(在原型中)编写char *keyword[]而不是char **keyword The compiler will automatically convert it.编译器会自动转换它。

Also, in C you can dereference pointers like arrays, so you loose almost nothing with that "converting to pointer".此外,在 C 中,您可以像数组一样取消引用指针,因此“转换为指针”几乎不会丢失任何内容。

If you want to如果你想

void function(char **keyword);

Andy, think about that an array is just a pointer(to the beginning of the array), that's why you write:安迪,想想数组只是一个指针(指向数组的开头),这就是你写的原因:

void function(char **keyword);

Because you have create an array to char pointers.因为您已经创建了一个指向字符指针的数组。

If it's easier to understand try:如果更容易理解,请尝试:

void function(char *keyword[]);

But it's more C standard to use the first one, though if you use a C++ compiler won't really matter.但是使用第一个更符合 C 标准,尽管如果您使用 C++ 编译器并不重要。

char *keywords[10] is an array of character pointers. char *keywords[10]是一个字符指针数组。 So keywords[0] , keywords[1] .. and so on will have the addresses to different character arrays.因此, keywords[0]keywords[1] .. 等将具有不同字符数组的地址。

In printf you can use %s and keywords[0] to print the entire character array whose address(ie address of the first byte in the array) is stored at keywords[0] .printf您可以使用%skeywords[0]打印整个字符数组,其地址(即数组中第一个字节的地址)存储在keywords[0]

While passing to a function, if you give *keywords , you are referring to the value at(address stored at keywords[0] ) which is again an address.在传递给函数时,如果你给出*keywords ,你指的是at(address stored at keywords[0] )值,它也是一个地址。 So, to get the value instead of address, you can add another * ... Hope that clarifies a bit..因此,要获取值而不是地址,您可以添加另一个* ...希望能澄清一点..

I am assuming that you are assigning your first string:我假设您正在分配第一个字符串:

"float"

to the first index position of keyword[0]到关键字[0]的第一个索引位置

char keyword[0] = "float";

which is the first index position of the array:这是数组的第一个索引位置:

char keyword[10];

If the previous is the case, then in a sense, you are essentially creating a data structure that holds a data structure.如果是前一种情况,那么从某种意义上说,您实际上是在创建一个包含数据结构的数据结构。 The array of any type is the 'smallest' data structure of that type in C. Considering that in your example you are creating a character array, then you are actually utilizing the smallest data type (char=1bit) at each index position of the smallest built in data structure (the array).任何类型的数组都是 C 中该类型的“最小”数据结构。考虑到在您的示例中您正在创建一个字符数组,那么您实际上是在每个索引位置使用最小的数据类型(char=1bit)最小的内置数据结构(数组)。

With that said, if in your example, you are attempting to create an array of arrays;话虽如此,如果在您的示例中,您正在尝试创建一个数组数组; your character array你的字符数组

/* Hold ten characters total */
char keyword[10];  

was designed to hold 10 characters.旨在容纳 10 个字符。 One at each index position (which you probably already know).每个索引位置一个(您可能已经知道)。 So after declaring the array titled keyword, you then try to initialize the first index position of the array with another (the second) character array:因此,在声明数组 titled 关键字后,您尝试使用另一个(第二个)字符数组初始化数组的第一个索引位置:

/* I believe this is what you had stated */
char keywords[0] = "float";

With the second character array having an index of 5 positions in size.第二个字符数组的大小索引为 5 个位置。

In order to achieve your desired goal, you would essentially be creating an array that basically emulates the effect of a data structure that 'holds' other data structures.为了实现您想要的目标,您实际上是在创建一个数组,该数组基本上模拟了“包含”其他数据结构的数据结构的效果。

NOTE: If you had/have plans on trying to create a data structure that holds a data structure that holds a data structure.注意:如果您有/有计划尝试创建一个包含数据结构的数据结构,该数据结构包含一个数据结构。 AKA a triple nested data structure and in this case I think that would be a Matrix, WHICH I WOULDN'T RECOMMEND! AKA 三重嵌套数据结构,在这种情况下,我认为这将是一个矩阵,我不推荐!

None the less, the matrix structure would be in the form of the first index position of keyword, being assigned the whole array of keywords, which would include all of the data stored in each index position of the keywords array.尽管如此,矩阵结构将采用关键字的第一个索引位置的形式,被分配到整个关键字数组,其中包括存储在关键字数组每个索引位置的所有数据。 Then there would something probably like: keywords1, keywords2, ... keywords9,然后可能会有类似的东西:keywords1,keywords2,...keywords9,

which would essentially emulate the form of:这将基本上模仿以下形式:

char *keyword[10] = { 
                        char *keywords0[10] = {"float", etc, etc, etc.};
                        char *keywords1[10] = {"keyword1", "secondIndexOfThisArray", etc, etc, etc.}; 
                       and so

                   };

So basically from right to left, the keyword array, is an array of pointers that points to array of pointers that points to character arrays.所以基本上从右到左,关键字array,是一个指向指向字符数组的指针数组的指针数组。

If that is what you are representing you would be better defining a custom data type of struct/record, and with in that custom structure you would want to define a subordinate or child level of structures.如果这就是您所表示的,您最好定义结构/记录的自定义数据类型,并且在该自定义结构中您可能希望定义结构的从属或子级。 You could also pre-declare them then initialize them.您也可以预先声明它们然后初始化它们。

eg例如

typedef *nestedDataStructures {

    struct keyWords[];
    struct keyWords1[];
    struct keyWords2[];

    ... and so on.
}; nestedDataStructures

Instead of adding ten structs to one custom structure I would break down into 3 or 4 (how ever many structures and use) and create a module in order to yield symmetrical layers of abstraction as you manipulate your data set.我不会将 10 个结构添加到一个自定义结构中,而是将其分解为 3 或 4 个(有多少结构和使用)并创建一个模块,以便在您操作数据集时产生对称的抽象层。

None the less, you can not create the character array and potentially assign the other character array in the fashion that you did (or who knows maybe you can), but the way you would want to emulate the array that holds arrays, is to create a character pointer array up front, of X number index positions and then initialize then use the character arrays in the form of a strings declared with in the initialization of the original declaration.尽管如此,您无法创建字符数组并可能以您所做的方式(或者谁知道您可以)分配另一个字符数组,但是您想要模拟包含数组的数组的方法是创建前面有一个字符指针数组,X 个索引位置,然后初始化,然后在原始声明的初始化中以字符串的形式使用字符数组。

So basically you could declare your whole array upfront, then with in your program design, either dereference each index position, use assignment, or print/write the index position.所以基本上你可以预先声明你的整个数组,然后在你的程序设计中,要么取消引用每个索引位置,使用赋值,要么打印/写入索引位置。

Like for instance you could always do something like this:例如,你总是可以做这样的事情:

/* Example of the program and declaration with out a function */
#include <stdio.h>

int main(){

    /* 
     * A character pointer array that contains multiple 
     * character arrays.
     */

    char *grewMe[2] = {"I want to ", "grow to be bigger"};

    int w = 0;

    for(; w < 2;) {
        printf("%s", grewMe[w]);
        ++w;
    }

    printf(" :-)\n");
    w = 0;
    return 0;
}
// Output:
// I want to grow to be bigger :-)

Or something like this:或者像这样:

/* Example of program: function passed arguments 
 * of a pointer to the array of pointers 
 */
#include <stdio.h>

void mygrowth(char *growMe[]);

int main(){

    char *growMe[2] = {"I want to ", "grow to be bigger"};

    mygrowth(growMe);  
    printf(" :-)\n");

    return 0;

}
void mygrowth(char *growMe[])
{

    int w = 0;
    for (; w < 2;) {
        printf("%s", growMe[w]);
        ++w;
    } 
}

The assignment of each index position as it's passed as an argument:每个索引位置作为参数传递时的分配:

/* 
 * This program compiles, runs and outputs properly
 * Example of a program with a function of 
 * arguments pnt2pnter 
 */

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

void thoughtAsAFunction(char **iThink);

int main()
{

    char *iThink[10] = {"I am trying to grow, but it's a hard task to ",
                        "accomplish. My father is short ", 
                        "my mother is even shorter than him, ", 
                        "what is the probability of me getting taller? ", 
                        "Well both my grandfather's were Six ",
                        "Foot Five, and both my grandmother's ", 
                        "were over 5 foot 8 inches tall! If my ",  
                        "grandparent's genes point to my parents, and my ", 
                        "parent's genes point to mine I might have a chance ",
                        "of being 6 foot. Do you know what I mean? "};

    thoughtAsAFunction(iThink);

    printf(":-)\n");

    return 0;
}
void thoughtAsAFunction(char **iThink) {

    int andy = 0;
    for (; andy < 10;) {
        char * pntThroughPnt = iThink[andy];
        printf("%s", pntThroughPnt);
        ++andy;
    }
    andy = 0;
}

Or pass by reference, with an increment of the loop count variable:或者通过引用传递,增加循环计数变量:

/*
 * This program compiles, runs, and outputs all of the character
 * arrays. 
 * 
 */
#include <stdio.h>
#include <stdlib.h>

void thoughtAsAFunction(char **iThink);

int main()
{

    char *iThink[10] = {"I am trying to grow, but it's a hard task to ",
                        "accomplish. My father is short ", 
                        "my mother is even shorter than him, ", 
                        "what is the probability of me getting taller? ", 
                        "Well both my grandfather's were Six ",
                        "Foot Five, and both my grandmother's ", 
                        "were over 5 foot 8 inches tall! If my ",  
                        "grandparent's genes point to my parents, and my ", 
                        "parent's genes point to mine, then I might have a chance ",
                        "of being 6 foot. Do you know what I mean? "};

    int andy = 0;
    for (; andy < 10;) {
        // pass by reference and increment.
        thoughtAsAFunction(&iThink[andy]);
        ++andy;

    }

    printf(":-)\n");
    andy = 0;

    return 0;
}
void thoughtAsAFunction(char **iThink) {

    char * pntThroughPnt = *iThink;
    printf("%s", pntThroughPnt);

}

Keep in mind that this is the case if you declare the array of pointers (char *array[10];), and each pointer points to an array of characters.请记住,如果您声明指针数组 (char *array[10];),并且每个指针指向一个字符数组,就会出现这种情况。

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

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