Mam odpowiedzieć na pytanie o pracę domową dla jednej z moich klas. W szczególności mam powiedzieć, czy niektóre tablice w C są uważane za łańcuchy, czy nie. Na podstawie tego artykułu ( https://www.geeksforgeeks.org/strings-in-c-2/ ) wiem, że ciągi znaków to tablica znaków z zakończeniem zerowym na końcu.
Moje główne zawieszenie jest częścią pytania, które dotyczy tablicy, która wygląda następująco:
char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };
Jest to oczywiście tablica znaków ze znakiem kończącym na zero na końcu. Czy jednak nadal jest uważany za ciąg, ponieważ ma również znak kończący na zero w środku? Jak to wpłynie na ciąg?
EDYCJA: Na podstawie komentarzy podałem rzeczywiste brzmienie pytania:
„Które z poniższych tablic można uznać za„ ciągi ”w celu wykorzystania ich jako argumentów funkcji strcpy (), strncpy (), strcmp (), strncmp () i podobnych funkcji ciągu (wskazać wszystkie obowiązujące)?”
EDYCJA: Wysłałem e-mail do mojego profesora na ten temat, ponieważ pytanie wydawało się dwuznacznie sformułowane (jak zauważyło kilka osób). Jeśli ktoś jest ciekawy, powiedział mi: „Tak, to ciąg znaków. Kluczem jest to, że istnieje znak zerowy. Ale oczywiście będzie to miało wpływ na wszelkie operacje na łańcuchach; łańcuch kończy się na znaku zerowym”.
źródło
"CS"
z dołączonymi kilkoma bajtami śmieci (w takim przypadku końcowy znak NUL nie ma znaczenia). Ale to nie jest ciąg „jako całość”. - Niemniej jednak karmienie tegostrcpy
itp. Nie spowoduje wybuchu komputera, ponieważ funkcje te będą „widzieć” tylko"CS"
część.strcmp()
. To, czy można go użyć jako argumentu do mutowania funkcji łańcuchowych, zależy od dodatkowych czynników, których nie podano.c1
jest zmienna, więc nie rozumiem, dlaczego nie byłby prawidłowym argumentem docelowymstrcpy
lub podobnym, chyba że nie był wystarczająco duży, aby pomieścić łańcuch źródłowy. To nie oznaczałoby, że nie byłby to sznurek, tylko nieodpowiedni do określonego celu.c1
spełniałoby podstawowe wymagania dotyczące argumentów łańcuchowych dla wszystkich funkcji łańcuchowych biblioteki standardowej (wąskich), w tym wszystkich tych specjalnie nazwanych, ale zachowanie może nie być tym, czego osoba wywołująca oczekuje lub chce (nawet ignorując niezdefiniowane zachowania, które można wywołać).char
. Wystarczy dowolny typ postaci .Odpowiedzi:
c1
jest zasadniczo [1] równoważna&c1[0]
, która posiada jeden łańcuch,"CS"
.Jest to drugi ciąg czai się tam
"324"
, zaczynając&c1[3]
- ale tak długo, jak masz dostępc1
jakoc1
, łańcuch"CS"
ma wszystkie funkcjestrcpy()
et al. zobaczyłby.[1]:
c1
jest tablicą,&c1[0]
jest wskaźnikiem.źródło
c1
ciągu docelowego wstrcpy()
poleceniu? Pytanie jest niejednoznaczne - w najlepszym razie.c1
jako argumentu dostrcpy()
. Jest to całkowicie zwyczajna struna pod każdym względem. Zwykłe ciągi znaków często zawierają resztki śmieci po ich terminatorach. Fakt, że te śmieci są zakodowane na stałe w programie, sprawia wrażenie, że autor zamierza użyć ichc1
w sposób nieciągowy, ale nie było to częścią pytania.c1
jest równoważne z&c1[0]
” wprowadzającymi w błąd.c1
jest tablicą.&c1[0]
jest wskaźnikiem.Jeśli chcesz poznać specyfikę definicji łańcucha w C, przejdź do źródła.
Od standardu C90 :
(Nie wprowadzono żadnych istotnych zmian w późniejszych standardach).
Tak więc
c1
zawiera dwa kolejne ciągi „CS” i „324”, ale sam nie jest ciągiem.Jeśli przekażemy tablicę do funkcji, rozkłada się ona na wskaźnik do jej pierwszego elementu, a tym samym
+c1
wskazuje na ciąg znaków (pierwszy), który jest wystarczający dla każdej funkcji oczekującej wskaźnika na ciąg. Nie wskazuje na ciąg „CS \ 0324”, ale prawdopodobnie wystarcza to na pytanie instruktora, co jest dwuznaczne.źródło
+c1
wskazuje na ciąg, ponieważc1
zaczyna się od ciągu. Nie ma to jednak żadnego kształtu, kształtu ani formyc1
.Dodając do odpowiedzi @ DevSolar, coś odkryłem po zabawie danym ciągiem, jeśli miałoby to być:
Jeśli wypiszesz ten ciąg, otrzymasz,
CS03240
a jego rozmiar wynosi 7. O ile mi wiadomo,\\0
jest używany do oznaczenia znaku zerowego ( tj\0
.). Jeśli zrobisz:Nic nie widać w dzienniku wyjściowym, ale jeśli:
Widzisz
\0
coś, co jest oczekiwane, ponieważ aby wypisać znaki specjalne, takie jak ukośniki odwrotne lub cudzysłowy, musisz użyć\
wraz z nimi.Coś, co mnie zastanawia, to wynik
CS03240
i jego rozmiar 7. Powszechnie rozumie się, że rozmiar łańcucha to liczba znaków plus jeden (dla znaku zerowego). Również rozmiar jest 7 nawet do łańcucha,char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };
.Więc może kontynuacja tego pytania, co się tutaj dzieje?
źródło
'\\0'
nie jest znakiem zerowym . Jest to stała wieloznakowa. Ma określoną wartość implementacyjną z pewnością poza zakresemchar
.c1[]
nie jest łańcuchem, ponieważ nie ma znaku zerowego . „wyprowadzasz ten ciąg” prawdopodobnie spowoduje niezdefiniowane zachowanie .char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };
ma rozmiar 7, ponieważ jest inicjowany 7 wartościami. To wielkość nie ma nic wspólnego ze strun .char c1[] = { 1, 2, 3, 4, 5, 6, 7 };
nadal miałby rozmiar 7.c1
zawiera żądło? To osobny problem. Zobacz także