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

9wbgstp7  于 2023-08-03  发布在  其他
关注(0)|答案(7)|浏览(114)

我是C的新手,C和我学过的任何其他语言都不一样。在我的作业中,我想创建一个字符数组,它指向一个字符数组,但与其创建一个多维字符数组,我认为我会有更多的控制权,并创建字符数组,并将每个字符数组放入原始字符数组的索引中:

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

字符串
上面的例子是为了澄清和一个简单的情况。但我的问题是由于我一直在做的研究,我对一些事情感到困惑。通常情况下,这在其他语言中也可以工作,但在C中它将是:

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


但是当我想通过函数发送时,为什么需要这样做:

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


只传递数组指针还不够吗?

jhiyze9q

jhiyze9q1#

看起来你被里面的双星搞糊涂了

void function(char ** keyword);

字符串
双星号只是意味着这个函数希望你传递一个指向char的指针。这种语法不包含任何关于使用数组的信息,也不包含关于字符串中的第一个字符的信息。作为程序员,您需要知道这个char **实际上指向哪种数据结构。
例如,假设数组的开头存储在地址0x1000。函数的keyword参数的值应为0x1000。如果取消引用keyword,则会得到数组中的第一个条目,即指向字符串“float”中第一个字符的char *。如果取消引用char *,则会得到字符“f”。
这段代码看起来像这样:

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


上面的例子中有两个指针。通过在解引用第一个指针之前向其添加偏移量,可以访问数组中的不同字符串。通过在解引用第二个指针之前向其添加偏移量,可以访问字符串中的不同字符。

6ojccjat

6ojccjat2#

char *keyword[10];

字符串
keywordchar *的阵列10。在值上下文中,它转换为指向char *的指针。
这种转换是Chris Torek称之为**“规则”**的一部分:
正如在其他地方提到的,C有一个关于数组和指针的非常重要的规则。这条规则--规则--说,在值上下文中,“T的数组”类型的对象成为“指向T的指针”类型的值,指向该数组的第一个元素。
更多信息,请参见此处:http://web.torek.net/torek/c/pa.html
C-FAQ中也有一个关于数组到指针转换的条目:
问题6.3:那么,C中的“指针和数组的等价性”是什么意思呢?
http://c-faq.com/aryptr/aryptrequiv.html

62lalag4

62lalag43#

在C语言中,你不能把数组传递给函数。相反,您传递一个指向数组开头的指针。因为你有一个char*的数组,所以这个函数会得到一个指向char*的指针,也就是char**
如果需要,可以编写(在原型中)char *keyword[]而不是char **keyword。编译器将自动转换它。
另外,在C中,你可以像数组一样解引用指针,所以你几乎不会因为“转换为指针”而失去任何东西。

qrjkbowd

qrjkbowd4#

如果你想在

void function(char **keyword);

字符串
Andy,想想看,数组只是一个指针(指向数组的开头),这就是为什么你写:

void function(char **keyword);


因为您已经创建了一个char指针数组。
如果更容易理解,请尝试:

void function(char *keyword[]);


但是使用第一个更符合C标准,尽管如果使用C++编译器也没什么关系。

mzillmmw

mzillmmw5#

这就是答案。

#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);
}

字符串

enyaitl3

enyaitl36#

char *keywords[10]是一个字符指针数组。所以keywords[0]keywords[1] ..等等将具有不同字符数组的地址。
printf中,你可以使用%skeywords[0]来打印整个字符数组,它的地址(即数组中第一个字节的地址)存储在keywords[0]
当传递给一个函数时,如果你给予*keywords,你引用的是 * 值(存储在keywords[0]的地址)*,它也是一个地址。因此,要获取值而不是地址,您可以添加另一个* ...希望能澄清一点。

u59ebvdq

u59ebvdq7#

我假设你正在分配你的第一个字符串:

"float"

字符串
到关键字[0]的第一个索引位置

char keyword[0] = "float";


这是数组的第一个索引位置:

char keyword[10];


如果是前面的情况,那么在某种意义上,您实际上是在创建一个包含数据结构的数据结构。任何类型的数组都是C中该类型的“最小”数据结构。考虑到在你的例子中你正在创建一个字符数组,那么你实际上是在最小的内置数据结构(数组)的每个索引位置使用最小的数据类型(char=1bit)。
如果在你的例子中,你试图创建一个数组的数组;你的字符数组

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


被设计为容纳10个字符。每个索引位置一个(您可能已经知道)。因此,在声明了数组titled关键字之后,您可以尝试使用另一个(第二个)字符数组初始化数组的第一个索引位置:

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


其中第二字符数组具有大小为5个位置的索引。
为了实现您想要的目标,您实际上需要创建一个数组,该数组基本上模拟了“保存”其他数据结构的数据结构的效果。
注意:如果您有/有计划尝试创建一个包含一个包含一个数据结构的数据结构。A.K.A.一个三重嵌套的数据结构,在这种情况下,我认为这将是一个矩阵,我不会推荐!
然而,矩阵结构将是关键字的第一索引位置的形式,被分配关键字的整个阵列,其将包括存储在关键字阵列的每个索引位置中的所有数据。然后可能会有这样的东西:关键字1,关键字2,...关键字9,
其将基本上模拟以下形式:

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

                   };


所以基本上从右到左,关键字array,是一个指针数组,它指向一个指针数组,指针数组指向字符数组。
如果这就是你所表示的,你最好定义一个自定义的数据类型结构/记录,并在该自定义结构中定义一个从属或子级别的结构。您也可以预先声明它们,然后初始化它们。
例如,在

typedef *nestedDataStructures {

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

    ... and so on.
}; nestedDataStructures


我不会在一个自定义结构中添加10个结构,而是将其分解为3或4个(有多少结构和用途)并创建一个模块,以便在操作数据集时产生对称的抽象层。
尽管如此,您不能创建字符数组并可能以您所做的方式分配其他字符数组(或者谁知道你可能可以),但是你想要模拟保存数组的数组的方法是在前面创建一个字符指针数组,然后初始化,然后用字符数组的形式声明一个字符串,在初始化时用宣言。
所以基本上你可以预先声明你的整个数组,然后在你的程序设计中,或者解引用每个索引位置,使用赋值,或者打印/写入索引位置。
例如,你总是可以这样做:

/* 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 :-)


或者类似这样的东西:

/* 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;
    } 
}


每个索引位置作为参数传递时的赋值:

/* 
 * 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;
}


或者通过引用传递,循环计数变量递增:

/*
 * 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);

}


请记住,如果声明指针数组(char *array[10];),并且每个指针都指向一个字符数组。

相关问题