Kan ik een array van Char-pointers maken in C?

Ik ben nieuw in C en de dingen in C zijn anders dan in elke andere taal die ik heb geleerd. In mijn huiswerk wil ik een reeks tekens maken die naar een reeks tekens verwijzen, maar in plaats van een multidimensionale tekenreeks te maken, denk ik dat ik meer controle zou hebben en tekenreeksen zou maken en elke afzonderlijke in de indexen van de originele char array:

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

Het bovenstaande voorbeeld is ter verduidelijking en een eenvoudig geval. Maar mijn vraag is te wijten aan het onderzoek dat ik heb gedaan, en ik ben in de war over iets. Normaal gesproken zou dit in andere talen werken, maar in C zou het zijn:

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

Maar als ik het via een functie wil verzenden, waarom is dit dan nodig:

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

Zou het doorgeven van de array-pointer niet voldoende zijn?


Antwoord 1, autoriteit 100%

Het lijkt erop dat je in de war bent door de dubbele sterren in

void function(char ** keyword);

De dubbele sterren betekent alleen dat deze functie verwacht dat je een aanwijzer doorgeeft aan een aanwijzer naar een teken. Deze syntaxis bevat geen informatie over het feit dat u een array gebruikt, of dat de char eigenlijk de eerste char is van vele in een string. Het is aan jou als programmeur om te weten naar wat voor soort datastructuur deze char **eigenlijk verwijst.

Stel bijvoorbeeld dat het begin van uw array is opgeslagen op adres 0x1000. Het argument keywordvoor de functie moet een waarde van 0x1000 hebben. Als u de verwijzing naar keywordverwijdert, krijgt u het eerste item in de array, dat een char *is die verwijst naar het eerste char in de string “float”. Als je de verwijzing naar de char *haalt, krijg je de char “f”.

De (verzonnen) code daarvoor zou er als volgt uitzien:

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

Er waren twee aanwijzingen in het bovenstaande voorbeeld. Door een offset aan de eerste aanwijzer toe te voegen voordat u deze loskoppelt, krijgt u toegang tot verschillende tekenreeksen in de array. Door een offset aan de tweede aanwijzer toe te voegen voordat u deze loskoppelt, krijgt u toegang tot verschillende tekens in de tekenreeks.


Antwoord 2, autoriteit 14%

char *keyword[10];

keywordis een array 10 van char *. In een waardecontext werd het omgezet in een pointer naar een char *.

Deze conversie maakt deel uit van wat Chris Torek ‘The Rule’noemt:

“Zoals elders opgemerkt, heeft C een zeer belangrijke regel over arrays en pointers. Deze regel — The Rule — zegt dat, in een waardecontext, een object van het type ‘array of T’ een waarde wordt van het type ‘ pointer naar T’, wijzend naar het eerste element van die array”

Zie hier voor meer informatie: http://web.torek.net/torek/ c/pa.html

De C-FAQ heeft ook een item over deze array naar pointer-conversie:

Vraag 6.3: Dus wat wordt bedoeld met de “equivalentie van pointers en arrays” in C?

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


Antwoord 3, autoriteit 7%

In C kun je array niet echt doorgeven aan een functie. In plaats daarvan geef je een aanwijzer door naar het begin van de array. Aangezien je een array van char*hebt, krijgt de functie een verwijzing naar char*, wat char**is.

Als je wilt, kun je (in het prototype) char *keyword[]schrijven in plaats van char **keyword. De compiler zal het automatisch converteren.

Bovendien kun je in C pointers dereferentie zoals arrays, dus je verliest bijna niets met dat “converteren naar pointer”.


Antwoord 4, autoriteit 7%

Als je wilt

void function(char **keyword);

Andy, bedenk dat een array slechts een aanwijzer is (naar het begin van de array), daarom schrijf je:

void function(char **keyword);

Omdat je een array hebt gemaakt om pointers te karakteriseren.

Als het makkelijker te begrijpen is, probeer dan:

void function(char *keyword[]);

Maar het is meer de C-standaard om de eerste te gebruiken, maar als je een C++-compiler gebruikt, maakt dat niet zoveel uit.


Antwoord 5, autoriteit 7%

Hier is het antwoord.

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

Antwoord 6

char *keywords[10]is een reeks tekenaanwijzers. Dus keywords[0], keywords[1].. enzovoort hebben de adressen van verschillende tekenreeksen.

In printfkunt u %sen keywords[0]gebruiken om de volledige tekenreeks af te drukken waarvan het adres (dwz het adres van de eerste byte in de array) wordt opgeslagen op keywords[0].

Terwijl u naar een functie gaat en u *keywordsopgeeft, verwijst u naar de waarde at(adres opgeslagen op keywords[0])wat weer een adres is. Dus om de waarde in plaats van het adres te krijgen, kun je nog een *toevoegen… Hoop dat dat een beetje verduidelijkt..


Antwoord 7

Ik neem aan dat u uw eerste tekenreeks toewijst:

"float"

naar de eerste indexpositie van zoekwoord[0]

char keyword[0] = "float";

wat de eerste indexpositie van de array is:

char keyword[10];

Als het voorgaande het geval is, creëert u in zekere zin in wezen een gegevensstructuur die een gegevensstructuur bevat. De array van elk type is de ‘kleinste’ gegevensstructuur van dat type in C. Aangezien u in uw voorbeeld een tekenreeks maakt, gebruikt u in feite het kleinste gegevenstype (char=1bit) op elke indexpositie van de kleinste ingebouwde datastructuur (de array).

Dat gezegd hebbende, als je in je voorbeeld probeert een array van arrays te maken; je karakterarray

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

is ontworpen om 10 tekens te bevatten. Eén op elke indexpositie (die u waarschijnlijk al kent). Dus na het declareren van de array met de titel trefwoord, probeer je vervolgens de eerste indexpositie van de array te initialiseren met een andere (de tweede) tekenarray:

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

Met de tweede tekenreeks met een index van 5 posities.

Om uw gewenste doel te bereiken, zou u in wezen een array maken die in feite het effect nabootst van een gegevensstructuur die andere gegevensstructuren ‘vasthoudt’.

OPMERKING: als u plannen had/hebt om te proberen een gegevensstructuur te maken die een gegevensstructuur bevat die een gegevensstructuur bevat. AKA een drievoudig geneste datastructuur en in dit geval denk ik dat dat een Matrix zou zijn, DIE IK NIET ZOU AANBEVELEN!

Desalniettemin zou de matrixstructuur de vorm hebben van de eerste indexpositie van het trefwoord, waarbij de hele reeks trefwoorden wordt toegewezen, inclusief alle gegevens die zijn opgeslagen in elke indexpositie van de trefwoordenarray. Dan zou er waarschijnlijk iets zijn als: trefwoorden1, trefwoorden2, … trefwoorden9,

die in wezen de vorm zou emuleren van:

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

Dus in feite is de trefwoordarray van rechts naar links een reeks aanwijzers die verwijst naar een reeks aanwijzers die naar tekenreeksen verwijst.

Als dat is wat u vertegenwoordigt, kunt u beter een aangepast gegevenstype van struct/record definiëren, en met die aangepaste structuur zou u een ondergeschikt of onderliggend niveau van structuren willen definiëren. U kunt ze ook vooraf declareren en vervolgens initialiseren.

bijv.

typedef *nestedDataStructures {
    struct keyWords[];
    struct keyWords1[];
    struct keyWords2[];
    ... and so on.
}; nestedDataStructures

In plaats van tien structs toe te voegen aan één aangepaste structuur, zou ik het opsplitsen in 3 of 4 (hoeveel structuren en gebruik ook) en een module maken om symmetrische abstractielagen op te leveren terwijl je je dataset manipuleert.

>

Desalniettemin kun je de tekenarray niet maken en mogelijk de andere tekenarray toewijzen op de manier die je hebt gedaan (of wie weet misschien wel), maar op de manier waarop je de array zou willen emuleren die arrays bevat, is het maken van een karakter-pointer-array vooraf, van X-nummerindexposities en vervolgens initialiseren en vervolgens de tekenarrays gebruiken in de vorm van een reeks gedeclareerd met in de initialisatie van de originele verklaring.

Dus in principe zou je je hele array vooraf kunnen declareren, en vervolgens in je programmaontwerp, ofwel elke indexpositie dereferenteren, toewijzing gebruiken, of de indexpositie afdrukken/schrijven.

Zoals je bijvoorbeeld altijd zoiets als dit zou kunnen doen:

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

Of zoiets:

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

De toewijzing van elke indexpositie zoals deze is doorgegeven als 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;
}

of pass by referentie, met een toename van de lus-televariabele:

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

Houd er rekening mee dat dit het geval is als u de array van pointers declareert (char *array[10];), en elke pointer verwijst naar een array van tekens.

Other episodes