char str1[30] = 'Ala ma kota'; printf("%s", str1); Wskaż, na czym polega błąd w kodzie zapisanym w języku C++.
char str1[30] = 'Ala ma kota'; printf("%s", str1);Wskaż, na czym polega błąd w kodzie zapisanym w języku C++.
A. Napis powinien mieć dokładnie 30 znaków.
B. Napis powinien być ujęty w cudzysłów.
C. Do funkcji printf przekazano zbyt mało argumentów.
D. W funkcji printf nie można stosować formatowania %s.
Pytanie z egzaminu CKE, czerwiec 2023 (arkusz EE.09-SG-23.06).
Błąd polega na tym, że tekst Ala ma kota został zapisany w apostrofach, czyli jako 'Ala ma kota', a w C i C++ napisy, czyli literały tekstowe, zapisuje się w cudzysłowie: "Ala ma kota". Apostrofy służą zasadniczo do pojedynczych znaków, np. 'A'. Gdy wpiszesz kilka znaków w apostrofach, kompilator może potraktować to jako tzw. wieloznakowy literał znakowy, co nie jest zwykłym napisem i na pewno nie nadaje się do poprawnego zainicjowania tablicy char przeznaczonej na tekst. Poprawny zapis wyglądałby tak: char str1[30] = "Ala ma kota"; printf("%s", str1);. Tablica ma 30 elementów, więc spokojnie mieści napis oraz znak końca tekstu '\0', który w stylu C jest bardzo ważny. Moim zdaniem to jeden z tych drobnych błędów, które łatwo przeoczyć, ale w praktyce robią dużą różnicę. W C++ dobrą praktyką jest często używanie std::string i std::cout, jednak jeśli korzystasz z tablicy char i printf, to format %s jest poprawny właśnie dla napisu zakończonego znakiem null.
W tym przykładzie problem nie polega na długości tablicy ani na samej funkcji printf. Tablica char str1[30] oznacza, że można w niej przechować maksymalnie 29 widocznych znaków tekstu oraz jeden znak kończący '\0'. Napis "Ala ma kota" ma mniej znaków niż 30, więc nie musi wcale mieć dokładnie trzydziestu znaków. To częsty błąd myślowy: rozmiar tablicy traktuje się jak wymaganie co do długości tekstu, a on oznacza tylko pojemność bufora. Oczywiście w praktyce trzeba uważać, żeby go nie przepełnić, bo w C i C++ takie pomyłki bywają groźne dla stabilności programu.
Nie ma też problemu z liczbą argumentów funkcji printf. Wywołanie printf("%s", str1); ma argument formatujący oraz wartość podstawianą pod %s, więc jest zgodne z zasadą działania tej funkcji. Format %s jak najbardziej można stosować w printf, również w programie C++, jeśli używamy mechanizmów odziedziczonych z języka C. Oznacza on wypisanie łańcucha znaków zakończonego znakiem null. Prawdziwy błąd siedzi wcześniej: 'Ala ma kota' nie jest poprawnym literałem napisowym. W C++ tekst zapisujemy w cudzysłowie, a apostrofy są dla pojedynczych znaków, np. 'x'. Z mojego doświadczenia warto zapamiętać prostą zasadę: jeden znak — apostrof, cały tekst — cudzysłów. W nowoczesnym C++ jeszcze lepiej byłoby napisać std::string str1 = "Ala ma kota";, bo jest to bezpieczniejsze i wygodniejsze niż ręczne pilnowanie rozmiaru tablicy znaków.
Nie ma też problemu z liczbą argumentów funkcji printf. Wywołanie printf("%s", str1); ma argument formatujący oraz wartość podstawianą pod %s, więc jest zgodne z zasadą działania tej funkcji. Format %s jak najbardziej można stosować w printf, również w programie C++, jeśli używamy mechanizmów odziedziczonych z języka C. Oznacza on wypisanie łańcucha znaków zakończonego znakiem null. Prawdziwy błąd siedzi wcześniej: 'Ala ma kota' nie jest poprawnym literałem napisowym. W C++ tekst zapisujemy w cudzysłowie, a apostrofy są dla pojedynczych znaków, np. 'x'. Z mojego doświadczenia warto zapamiętać prostą zasadę: jeden znak — apostrof, cały tekst — cudzysłów. W nowoczesnym C++ jeszcze lepiej byłoby napisać std::string str1 = "Ala ma kota";, bo jest to bezpieczniejsze i wygodniejsze niż ręczne pilnowanie rozmiaru tablicy znaków.