Witam i witam ponownie. W tym
wykładzie chcę porozmawiać o tworzeniu łańcucha, a konkretnie o
tym, jak można to zrobić w c przy użyciu tablicy znaków.
Mam tendencję do używania zamiennie terminów łańcuch i ciągi znaków.
Ale tak naprawdę ciąg znaków jest tablicą znaków, o której będziemy mówić.
To bardzo ważna koncepcja.
Będziemy mogli teraz używać słów i tekstu w naszym programie do robienia różnych rzeczy.
Teraz samo c nie ma żadnego typu danych, który reprezentuje ciąg.
Nic tam nie ma. Wiele języków obsługuje
obiekt lub typ danych typu string.
Ponieważ w łańcuchu nie ma danych typu c, nie można
użyć żadnego z operatorów w ciągu.
Skończymy więc na tym, że skończymy na standardowej bibliotece i mamy do czynienia z
różnymi funkcjami tekstowymi, o których będziemy mówić.
Mamy trzy wykłady poświęcone różnym funkcjom strun, które możesz wykorzystać.
A to pomoże nam manipulować strunami, uzyskać informacje o strunach.
Ale nie możesz używać operatorów na łańcuchach, żadnych ciągów
dodawania lub minusów, nic takiego.
Łańcuchy w c są przechowywane w tablicy typu char.
Wiemy, czym jest tablica. Wiemy, czym jest typ char.
Typ char to pojedynczy znak, tablica, w której można po prostu
przechowywać wiele elementów o tej samej nazwie.
Dlatego sensowne jest, aby ciąg znajdował się wewnątrz tablicy znaków, ponieważ
łańcuch składa się z wielu wielu znaków.
Tak więc znaki łańcucha są przechowywane w sąsiednich komórkach pamięci, po jednym znaku na komórkę.
Możesz uzyskać do niego dostęp tak samo, jak do tablicy.
Ale jak w rzeczywistości zadeklarowałbyś łańcuch i zobaczyłbyś, że po prostu użyjesz typu
char, a następnie nawiasów kwadratowych, aby wskazać rozmiar, tak jak zwykła
tablica, gdybyś utworzył ją innego typu.
Char, a następnie cokolwiek masz na imię, a następnie rozmiar
tablicy znaków w nawiasach kwadratowych.
W ten sposób możesz zadeklarować ciąg w c.
Teraz, gdy deklarujesz ciąg w c w ten sposób, nie
ma żadnych rzeczywistych danych powiązanych z. Po prostu określasz rozmiar.
To najprostszy sposób.
Tak więc zmienna może pomieścić ciąg zawierający do 19 znaków.
Zapamiętaj ten znak zerowy.
Jeśli powiesz, że rozmiar twojego ciągu będzie wynosić 20, oznacza to, że w rzeczywistości
można przechowywać tylko 19 znaków, ponieważ
musisz mieć ten jeden dodatkowy znak dla wartości null.
Pamiętaj, że zadeklarowanie tablicy znaków jako 20 oznacza, że można
w niej przechowywać 19 znaków.
Kiedy określasz wymiar tablicy, której zamierzasz użyć przed łańcuchem - aby przechowywać ciąg,
musi on być
co najmniej o jeden większy niż liczba znaków w ciągu, który chcesz przechowywać.
Kompilator automatycznie doda terminator zerowy na końcu każdej stałej łańcuchowej.
Więc to, co naprawdę powinieneś zrobić, to kiedy
tworzysz te ciągi znaków, powinieneś je inicjalizować.
Możesz więc zainicjować zmienną łańcuchową, tak jak możesz zainicjować tablicę.
Umieszczasz każdy znak w tych nawiasach.
Więc wygląda to bardzo podobnie do inicjalizacji elementów w tablicy liczb całkowitych.
Ale jeśli powiesz słowo char, a następnie
wewnątrz nawiasów falistych, umieścisz każdy pojedynczy znak, który
utworzy tablicę znaków.
Jest to więc to samo, co każda inna inicjalizacja tablicy.
W przypadku braku podania rozmiaru,
kompilator c automatycznie oblicza liczbę elementów w tablicy, a następnie dodaje jeden dla terminatora null.
Jest więc oparty na liczbie inicjatorów, które masz między nawiasami,
nawiasami klamrowymi.
Ta instrukcja zarezerwuje miejsce i pamięć na dokładnie siedem
znaków, wykrzyknik h-e-l-l-o, a
następnie terminator zerowy, a ten mały diagram po prawej pokazuje ci to.
Automatycznie i dodając ten zerowy terminator. Teraz byłoby naprawdę
upierdliwe, gdybyś zawsze musiał inicjować
tablice znaków pojedynczymi cudzysłowami, po których następowałyby przecinki.
Więc to, co możesz zrobić, to nawet skrótowa notacja, możesz po prostu umieścić wokół tego podwójne cudzysłowy.
Możesz więc określić ciąg jawnie, tak jak w pierwszym przykładzie,
a następnie musiałbyś faktycznie użyć funkcji ciągu, aby
zastosować do niego dane,
lub możesz pozwolić kompilatorowi zrobić to za Ciebie.
Problem z robieniem tego jawnie polega na tym, że zawsze musisz pamiętać o dodaniu tego dodatkowego znaku
do wartości null.
Więc to, co naprawdę powinieneś zrobić, to pozwolić kompilatorowi rozwiązać to za Ciebie.
Więc nie umieszczaj żadnych liczb w tych nawiasach dla rozmiaru.
Ponieważ jeśli podany rozmiar jest zbyt mały, kompilator nie może dopasować
kończącego znaku null na końcu tablicy i nie umieszcza go tam i nie
powie Ci, że go tam nie umieścił.
Więc będziesz mieć błąd w swoim programie, którego nawet nie będziesz wiedzieć.
Najlepszą praktyką jest użycie literału tekstowego i
inicjowanie ciągu, aby kompilator po prostu obliczył rozmiar za Ciebie.
Zrób to większy rozmiar lub coś w tym stylu, a następnie po prostu włóż to tam, a on wymyśli rozmiar dla Ciebie.
Więc nie określaj rozmiaru. Pozwól kompilatorowi to rozgryźć.
W ten sposób możesz mieć pewność, że będzie to poprawne.
Po prostu zostaw te nawiasy jako puste nawiasy
i przypisz je operatorowi przypisania, a następnie w podwójnych cudzysłowach
możesz po prostu je umieścić. Nie potrzebujesz nawet nawiasów kwadratowych.
To jest najlepsza praktyka. Przejdziemy przez przykład.
Możesz również zainicjować tylko część
tablicy elementów typu char za pomocą łańcucha.
Więc jeśli faktycznie utworzyłeś rozmiar, który był naprawdę duży i
przypisałeś tylko kilka znaków, to też jest
w porządku, inicjalizujesz tylko niektóre znaki. Wszystkie inne postacie będą po
prostu puste.
Więc co się tutaj stanie, to kompilator zainicjuje pierwsze pięć elementów.
Od zera do czwartego, wszystkie te
znaki stałej łańcuchowej, a następnie łańcuch sub 5 będą
zawierały znak null.
Przestrzeń nadal będzie przydzielana dla wszystkich 40 elementów
w tablicy, ale tylko pięć z nich będzie używanych, cztery plus znak null.
Więc znowu, twoja najlepsza praktyka tak naprawdę nie określa liczby w rozmiarze,
po prostu przypisz jej literał ciągu, używając podwójnych cudzysłowów.
To właśnie zobaczysz.
Teraz, jeśli nie zainicjowałeś i właśnie utworzyłeś
tablicę znaków z rozmiarem, jak wstawisz do niej datę.
Cóż, ponieważ jest to tablica, nie można po prostu przypisać danych.
Wiemy, że gdybyśmy mieli tablicę liczb całkowitych, nie moglibyśmy
po prostu przypisać tablicy liczb całkowitych liczby pięć,
to nie ma sensu. Musisz określić rzeczywiste elementy.
Musisz określić indeksy.
Nie możesz więc zrobić czegoś takiego, jak zadeklarowanie tablicy znaków zawierającej 100 znaków, a następnie powiedzenie,
że s równa się cześć. To nie zadziała.
Ponownie, s jest tablicą. Mimo że jest to ciąg umieszczony w cudzysłowie, nadal jest tablicą w pamięci.
Więc jeśli wykonujesz operację przypisania, nie możesz przypisać jednej
tablicy znaków do innej tablicy znaków, jak powyżej.
Jeśli chcesz przypisać dane do
tablicy znaków po jej zadeklarowaniu i zainicjowaniu, musisz użyć
specjalnej funkcji o nazwie str copy.
Porozmawiamy o tym w innym wykładzie.
A więc do tego momentu, kiedy tworzysz swoje łańcuchy, będą one literałami łańcuchowymi,
będą znajdować się w podwójnych cudzysłowach i nigdy ich nie zmodyfikujesz.
Więc jest to również całkowicie poprawne. W rzeczywistości możesz po prostu uzyskać
dostęp do tych znaków lub każdego elementu tablicy przez indeks i określić każdy znak.
Więc s sub 0, s sub 1, a następnie umieść pojedynczy znak w pojedynczych cudzysłowach.
Możesz to przypisać w ten sposób. Ale wyobraź sobie, że masz ciąg o długości 100 bajtów.
To zajmie wiele linii kodu. Więc nie chcesz tego robić.
To, co będziesz chciał zrobić, to zainicjować go, gdy
zadeklarujesz go bez rozmiaru, a następnie określ, czy
kiedykolwiek chcesz go zmodyfikować, kopiuj str.
Jeśli chodzi o wyświetlanie ciągu jako danych wyjściowych, nadal będziemy używać tej funkcji printf.
Jeśli chcesz odwołać się do łańcucha w dowolnym miejscu w programie, po prostu
użyj samej nazwy tablicy.
Nie musisz określać indeksów.
Ponieważ indeksy wewnątrz tablicy będą określać pojedynczy znak.
Jeśli chcesz mieć cały ciąg, po prostu użyj nazwy tablicy.
Więc jeśli używasz funkcji printf do wyświetlania danych wyjściowych,
po prostu wykonaj następujące czynności. W podwójnych cudzysłowach
użyłbyś procenta s jako specyfikatora formatu, a następnie tylko nazwy tablicy znaków.
Więc nie traktujesz go jak innych tablic, gdy chcesz uzyskać do niego dostęp. Jeśli chcesz uzyskać do niego dostęp, wystarczy nazwa,
bez rzeczywistych indeksów lub nawiasów.
Procent jako specyfikator formatu służy do wyprowadzania
ciągu zakończonego znakiem null. Pamiętaj, że zanim użyliśmy procenta d
dla liczb całkowitych, możesz użyć procenta c dla znaków.
W przypadku łańcuchów używasz procentów s, a są to tablice znaków.
Oczekuje łańcucha zakończonego znakiem null.
Więc jednak inicjalizujesz łańcuch, jeśli zrobiłeś to bez rozmiaru i terminator null jest
dodawany automatycznie lub jeśli utworzyłeś
go z określonym rozmiarem i dodałeś go lub jeśli dodałeś go
jawnie, nie ma to znaczenia. Po prostu musi zostać zakończona zerem.
Funkcja printf zakłada, że napotykamy specyfikator formatu procent s,
że odpowiadający mu argument jest łańcuchem znaków zakończonym znakiem null.
Tego się spodziewa, więc tak musi być.
Aby wprowadzić ciąg, wiemy, jak wprowadzić inne
zestawy danych za pomocą klawiatury za pomocą funkcji scanf.
Zrobimy to samo przy wprowadzaniu ciągów.
Użyjemy funkcji scanf. Z funkcją scanf będzie
tak samo, z wyjątkiem tego, że zamierzasz użyć innego specyfikatora formatu.
Więc dla łańcuchów użyjesz procentów jako danych wejściowych.
I to jest używane do wprowadzania łańcucha.
Inną rzeczą, na którą należy zwrócić uwagę, jest brak znaku ampersand dla nazwy
zmiennej, ponieważ jest to znak. Pamiętaj, wspomnieliśmy, że musisz podać
tylko ampers i adres operatora w łańcuchach.
Powodem jest to, że kiedy mówimy o wskazówkach, będzie to bardziej jasne.
Ale wejście char, mimo że jest
tablicą znaków, jest wskaźnikiem, a scanf jako drugi argument pobiera wskaźnik.
Dlatego nie musisz tego robić. Kiedy deklarujesz liczby całkowite i podwójne, nie są
to wskaźniki i. Więc jeśli
chcesz czytać dane wejściowe z klawiatury za pomocą scanf, drugi argument oczekuje wskaźnika,
który musisz przekazać w adresie.
Teraz z scanf kiedy robisz
łańcuch, scanf będzie czytać tylko do spacji.
Więc jeśli zrobisz scanf i wpiszesz Jason
jest instruktorem.
Jedyne, co zostanie zapisane na wejściu, to Jason. Ponieważ kiedy trafi
w to miejsce, nie odczyta reszty ciągu.
Są więc inne funkcje, których możesz użyć do odczytania całego ciągu.
Niektóre z przykładów, których będziemy używać, prawdopodobnie to zrobią. Możesz zrobić takie rzeczy jak f get
s, co jest innym sposobem odczytu danych wejściowych z klawiatury i spowoduje odczytanie całego
ciągu niezależnie od spacji.
Ale jest jeszcze jeden, który myślę, że nazywa
się get underscore s dla
C11, ale porozmawiamy o tym więcej, ale to tylko jedna rzecz
do zapamiętania, gdy czytasz dane wejściowe dla ciągów. Będzie czytać tylko do końca.
Co powiesz na sprawdzenie, czy dwa ciągi są równe.
Cóż, do tego momentu testowaliśmy wszystkie zmienne,
aby sprawdzić, czy są równe, używamy po prostu równa się równa się.
Ale ze sznurkami to nie zadziała.
Operator równości, pamiętaj, powiedzieliśmy, że łańcuchy to tablice znaków, więc nie możesz używać na nich operatorów.
Operator równości może być stosowany tylko do liczb całkowitych i podwójnych,
liczb zmiennoprzecinkowych lub znaków.
Nie działa na strukturach ani tablicach. Nie możesz porównać dwóch tablic.
Więc to nie zadziała ze strunami. Jeśli chcesz ustalić, czy dwa ciągi
są równe, musisz jawnie porównać dwa ciągi znaków znak po znaku.
Więc musiałbyś spojrzeć na każdy element w indeksie
tablicy według indeksu.
Jednak to naprawdę duży problem, ponieważ byłoby to naprawdę żmudne.
Więc porozmawiamy o tym, jak możesz to zrobić bardzo
łatwo, używając funkcji porównywania str z biblioteki standardowej, ale nie możesz
użyć równa się równa się, pamiętaj o tym.
I znowu, dla przypomnienia, powiedziałem to kilka razy, chcę to powtórzyć, stała
łańcuchowa x wewnątrz podwójnych cudzysłowów nie
jest tym samym, co stała znakowa x wewnątrz pojedynczych cudzysłowów.
X w pojedynczych cudzysłowach to typ podstawowy, to po prostu znak
lub troska.
X wewnątrz podwójnych cudzysłowów to typ napędu, to tablica typu char.
X wewnątrz podwójnych cudzysłowów tak naprawdę składa się z dwóch znaków,
x i terminatora null, znaku null, więc miej to na uwadze.
Oto przykład, w
jaki sposób możemy tworzyć łańcuchy, deklarując
je rozmiarem lub inicjalizując je w tej samej linii.
To jest najlepsza praktyka. Jeśli zamierzasz używać literałów łańcuchowych,
zrobiłbym to, co
jest tutaj napisane, tworząc tablicę znaków, nie określając rozmiaru,
a następnie po prawej stronie operatora przypisania umieszczam podwójne cudzysłowy.
Kompilator automatycznie utworzy odpowiedni ciąg i doda do niego terminator zerowy.
Jeśli określisz rozmiar, a nie masz wystarczającej liczby znaków, nie zapisze go.
Po prostu utwórz literały ciągu znaków,
używając typu danych char,
nazwy zmiennej, a następnie pustych nawiasów.
Myślę, że ten program policzy znaki
w tablicy, więc zasadniczo uzyska długość ciągu.
To, co tutaj robimy, to tworzymy zmienną o nazwie count w dwóch tablicach znaków
z dwoma różnymi łańcuchami, być albo nie być, a
następnie przecinek - oto jest pytanie.
Char str jeden będzie miał alternator po b, a
str będzie miał alternatywę po pytaniu.
Mamy więc pętlę, która przejdzie przez pierwszą tablicę,
od count równa się zero aż do momentu, gdy zobaczymy terminator zerowy.
W tym przypadku możemy użyć argumentu nie równa się, ponieważ porównujemy znak.
Terminator zerowy jako znak. Porównywanie postaci jest w porządku.
Więc nasza pętla while będzie działać aż do momentu, gdy zobaczymy terminator zerowy.
Kiedy zobaczymy zerowy terminator, wyskoczymy.
Liczba będzie równa liczbie znaków w tym ciągu.
Więc to jest długość tego ciągu.
Robimy to dla obu strun. Zauważysz, że zasadniczo oba struny
będą miały prawidłową długość, ponieważ po prostu przechodzimy przez każdy z nich.
To b czy nie b będzie miało około
18 znaków.
Teraz nigdy nie będziesz musiał robić czegoś takiego,
ponieważ mamy fajną funkcję pomocniczą z długością str do znalezienia długości łańcuchów.
Ale znowu, to, co to pokazuje, to fakt, że jest to tablica.
A jeśli chcesz porównać lub znaleźć długość łańcucha, możesz użyć argumentu
nie równa się i spojrzeć na znak, terminator zerowy.
Mam nadzieję, że to było pomocne. Oto jak zamierzamy zdefiniować i zainicjować literały łańcuchowe.
Dziękuję Ci.