[C++] *argv[] w funkcji main


(system) #1

O ile wiem do czego *argv[] służy, o tyle sposobu jego działania nie do końca rozumiem.

#include 


using namespace std;


int main(int argc, char* argv[])

{

    cout << *argv[0] << "\n"; //tutaj wyświetla się "D"

    cout << argv[0] << "\n"; //a tutaj "D:\c++\start.exe"


    string str_argv = argv[0];


    if(str_argv == "D:\\c++\\start.exe")

        cout << "tak 1\n"; //warunek zostanie spełniony

    if(argv[0] == "D:\\c++\\start.exe")

        cout << "tak 2\n"; //warunek nie zostanie spełniony

    cin.get();

    return 0;

}

*argv[] i argv[] - w jaki sposób to działa? bo zwykłe wskaźniki zachowują się inaczej w przypadku drugiego zapisu.

I dlaczego pierwszy warunek jest spełniony, a drugi nie?


(Fiołek) #2

argv to _tablica wskaźników_ na C-stringi. Pierwszy element to relatywna ścieżka do wykonywanego programu(od aktualnej), reszta - parametry. To co robisz przy pierwszym cout-ie to pobranie ścieżki(el. nr 1) i dereferencja wskaźnika, a jako iż wskaźnik to char* więc dostajesz pierwszy znak w tym c-stringu. Za drugim razem nie robisz dereferencji więc cout wyświetla cały c-string.

Operacje na wskaźnikach i c-stringach się kłaniają.


(Quentin) #3

Zacznijmy od tego, że argv to tablica wskaźników do pokazywania na obiekty typu char.

Wysłanie do strumienia cout adresu takiego wskaźnika powoduje zawsze wypisywanie znaków alfanumerycznych, aż do napotkania nulla.

Ale np. argv[2] to 3-ci wskaźnik. Wskaźnik ten pokazuje na początek C-stringu (C-string jest tutaj nazwą parametru przekazanego do programu), czyli na jego zerowy element. * to dereferencja czyli po prostu wyświetlenie tego zerowego elementu.

W przypadku warunków, to pierwszy jest spełniony ponieważ w klasie string istnieje przeładowany operator ==. Natomiast do samych C-stringów tego operatora użyć nie można.


(Sawyer47) #4

Widać jesteś mocno początkujący w C++.

argv[index] → to tzw. C-string (czyli wskaźnik na ciąg znaków zakończony znakiem NULL)

Pisząc *argv[index] odwołujesz się do pierwszego znaku tego napisu. Analogicznie:

const char *napis = "Napis";

printf("%s", napis); // cały napis

printf("%c", *napis); // pojedynczy znak

Tak jak już wspomniałem, argv[index] to wskaźnik. Pisząc argv[0] == "D:\c++\start.exe" porównujesz dwa wskaźniki (nie to, na co wskazują). Jeśli chciałbyś porównywać C-stringi, użyj funkcji strcmp. Natomiast typ std::string "potrafi się porównać" z C-stringiem, więc działa tak jak chcesz.


(system) #5

Chyba załapałem. Dla sprawdzenie, czy właśnie na takiej zasadzie działa argv?

#include 


using namespace std;


int main()

{

    char tekst[] = "parametr";

    char* wskazniki[10];

    wskazniki[0] = &tekst[0];


    cout << *wskazniki[0] << "\n";

    cout << wskazniki[0] << "\n";


    cin.get();

    return 0;

}

bynajmniej efekt ten sam :slight_smile:

Całkowicie się z Tobą zgadzam :smiley:


(Johny) #6

Pierwszy parametr jest zawsze ścieżką z nazwą programu,albo nazwą samego programu,jest to tablica wskażników do parametrów dlatego wywołuje się z gwiazdką,gdy posługujemy się wskażnikami,potrzebujemy adresów,stąd konieczność stosowania uppersandu &,adresy są wyłuskiwane i przypisywane do wskażników,podobnie są adresowane tablice tab[3] to tak naprawdę *(tab+3)


([alex]) #7

Dokładnie z tym że zamiast &tekst[0] możesz zapisać tekst:

wskazniki[0] = tekst;