2016-11-12 13 views
7

Nie mogę wydawać się owinąć głowę wokół problemu. czego mi brakuje?Drukowanie wartości w tablicy wskaźnika w C

Rozważmy następujący

int main(int argc, char *argv[]) { 
    while (*argv) { 
     printf("argv[] is: %s\n", *argv); 
     ++argv; 
    } 

    return 0; 
} 

drukuje się każdą wartość argv. Więc wiersz polecenia, takie jak ./example arg1 arg2 byłoby wyjście następuje:

`argv[] is: ./example` 
`argv[] is: arg1` 
`argv[] is: arg2` 

Rozważmy teraz następujący (co mam problemy z):

int main(void) { 
    char *days[] = { 
     "Sunday", 
     "Monday", 
     "Tuesday" 
    }; 
    while (*days) { 
     printf("day is %s\n", *days); 
     *days++; 
    } 

    return 0; 
} 

Gdy próbuję skompilować, otrzymuję błąd cannot increment value of type 'char *[3]'

Jeśli zmienię *days++ na (*days)++, to kompiluje. Jeśli go uruchomię, będzie działać wiecznie i ostatecznie zakończy się niepowodzeniem z bus error.

Jednak nie wykonuje iteracji po każdej wartości days[]. Próbowałem nawet wstawić wskaźnik zerowy w postaci '\0' i "\0" w tablicy dni bez efektu.

Czego mi brakuje?

+0

http://ideone.com/GM4wIN – BLUEPIXY

+0

Zobacz '++ argv;' '* vs dni ++;'! – alk

Odpowiedz

7

Masz kilka błędów w kodzie:

  1. Istnieje różnica między zmienną argv i stałej days. Zmienna może być zmieniona, stała tablica tablicowa - nie może.

  2. W twojej tablicy brakuje terminatora NULL na końcu tablicy.

  3. *days++; jest bezsensowny w tym przypadku. To jest manekin i zwraca wartość days, a następnie zwiększa się o days. Wystarczy użyć tylko days++.

Zatem, kod musi być jak:

#include <stdio.h> 

int main(void) { 
    char *days[] = { 
     "Sunday", 
     "Monday", 
     "Tuesday", 
     NULL 
    }; 
    char **d = days; 
    while (*d) { 
     printf("day is %s\n", *d); 
     d++; 
    } 

    return 0; 
+0

ok, więc kiedy zadeklarowałem char * days [] nie utworzyłem wskaźnika, utworzyłem tablicę? czy właśnie dlatego musisz umieścić tablicę w wskaźniku o nazwie * d? więc w ten sposób mogę użyć wskaźnika arithmnatic? –

+0

Tak. Jeśli chcesz poznać szczegóły, skompiluj swój program za pomocą opcji -S i przejrzyj kod zespołu. – maxihatop

0

Zamiast próbować zwiększać wskaźnik postaci, prawdopodobnie powinieneś przechodzić przez każdy element w tablicy znaków.

Na przykład:

char *days[] = { 
    "Sunday", 
    "Monday", 
    "Tuesday" 
}; 
int i;  
for (i = 0; i < 3; i++) 
    printf("day is %s\n", days[i]); 
+0

Powinno być możliwe zastąpienie 3 przez 'sizeof (days)/sizeof (days [0])' lub stałą wyliczenia 'enum {NUM_DAYS = sizeof (days)/sizeof (days [0])};' lub coś podobnego . Lub użyj znacznika NULL do oznaczenia końca danych, tak jak w argv, po przekazaniu do 'main()' - ale zauważ, że argumenty 'main()' są nadmiarowe, ponieważ możesz określić 'argc' przez iterowanie poprzez 'argv' (lub możesz pominąć element NULL na końcu' argv'), ale wygodniej jest mieć nadmiarowość. –

1
  1. days jest 2D tablica znaków. Chociaż nazwa tablicy wskazuje na pierwszy adres, nie jest wskaźnikiem. Nie można wykonać arytmetycznej wskaźnika na nazwie tablicy.
  2. while (*days) nigdy nie będzie fałszywy. Powinieneś zmienić logikę.

W poniższym kodzie zachowałem większość kodu.

#include <stdio.h> 

    int main(void) { 
     char *days[] = { 
      "Sunday", 
      "Monday", 
      "Tuesday" 
     }; 

     for(int i=0; i < 3; i++) { 
      printf("day is %s\n", (days[i])); 
     } 

     return 0; 
5

argv [] struktura zawiera null pointer jako ostatni wpis, który jest dlaczego Twój kod działa.Możesz dodać zerowy wskaźnik do swojej struktury danych. Musisz również zrozumieć, że argv jest parametrem (podobnie jak zmienna lokalna), który wskazuje na wewnętrzną strukturę danych z argumentami wiersza poleceń. Musisz utworzyć podobną zmienną lokalną, która może iterować przez tablicę.

Oto rozwiązanie:

#include <stdio.h> 
int main(void) { 
    char *days[] = {"Sunday", "Monday", "Tuesday", 0 }; 
    char **v = days; 

    while (v) { 
    printf("day is %s\n", *v); 
    v++; 
    } 

    return 0; 
} 
+0

ok, dlaczego podwójna asterix ** v? czy jest wskaźnikiem do wskaźnika? nie widziałem jeszcze ** w żadnym z przykładów –

+1

@fizzydrink: W twoim kodzie masz definicję parametru funkcji 'char * argv []', której kontekst jest taki sam jak 'char ** argv'. Wystarczy go wymienić, skompilować i stać się oświeconym. – alk

+0

@alk Będę musiał spróbować dzięki –

Powiązane problemy