Dyskusja:C/Zmienne

Z Wikibooks, biblioteki wolnych podręczników.
Przejdź do nawigacji Przejdź do wyszukiwania

"W przeciwieństwie do języka C++, w C stała to cały czas zmienna, której kompilator pilnuje, by nie zmieniła się. Z tego powodu w C nie można użyć stałej do określenia wielkości tablicy i należy się w takim wypadku odwołać do wcześniej wspomnianej dyrektywy #define." Czy ktoś mógłby mi wyjaśnić o co chodzi w tym akapicie? Bo np. niniejszy kod kompiluje się całkiem poprawnie:

int main(void) {
    int b[10];
    const int a = sizeof b / sizeof *b;
    return 0;
}

odp: Zauważ, że w tym kodzie wielkość tablicy określasz stałą 10, a nie zmienną a (która jest const). W tym akapicie chodzi o to, że niedopuszczana jest taka operacja:

int main(void) {
    const int a = 10;
    int b[a];
    return 0;
}

Natomiast w linijce dalej masz jedynie nadanie początkowej wartości zmiennej z modyfikatorem const, co jest jak najbardziej dozwolone. Pozdro.

W ogóle w C++ stałą to także zmienna. W końcu można pobrać adres stałej zarówno w C jaki w C++.

"Język C nie inicjalizuje zmiennych. Oznacza to, że w nowo zadeklarowanej zmiennej znajdują się śmieci - to, co wcześniej zawierał przydzielony zmiennej fragment pamięci. Aby uniknąć ciężkich do wykrycia błędów, dobrze jest inicjalizować wszystkie zmienne w momencie zadeklarowania."

Moim zdaniem C inicjalizuje zmienne globalne (tzn. jest to zapewnione przez C99, jeśli chcecie mogę grzebnąć standard ansi czy na pewno, choć nie chce mi się. ;D A jestem prawie pewien.) Spróbuję to tam dziś dopisać, chyba, że zaprotestujecie. Tomasz bla Fortuna 14:50, 14 maj 2007 (CEST)Reply[odpowiedz]

ad.1 raczej chodzi tutaj o kod:
const int a = 2;
int b[a];
ad.2 poniższy kod:
#include <stdio.h>
int main()
{
int a;
printf ("%d\n",a);
}
przy kompilacji z opcją -std=c99 w GCC daje losowe liczby.
kod:
#include <stdio.h>
int a;
int main()
{
printf ("%d\n",a);
}
daje już tylko 0. --Kj 15:56, 14 maj 2007 (CEST)Reply[odpowiedz]

No to dokładnie tak - lokalne losowe, w końcu leżą na stosie który co chwile się zmienia, a globalne - są zerowane. Tylko tekst uogólnie określenie "c nie inicjalizuje zmiennych" na wszystkie typy. I co do GCC to jestem pewien, że tak jest. Nie wiem tylko jak to się przekłada na inne kompilatory (bardziej egzotyczne) jak standard wymaga - no to nie ma mocy. Najwyżej kompilator jest źle napisany. Tomasz bla Fortuna 22:54, 15 maj 2007 (CEST)Reply[odpowiedz]

Tak przy okazji - jeśli widzisz jakieś ewidentne błędy, niedociągnięcia, niedomówienia lub innego rodzaju niedoskonałości, to śmiało edytuj i poprawiaj zauważone pomyłki ;-). --Kj 16:52, 16 maj 2007 (CEST)Reply[odpowiedz]

Uwagi[edytuj]

Chciałbym poruszyć dosyć ważną kwestie otóż czy konieczne jest odnoszenie się do języka C++ w każdym rozdziale tej książki ? w końcu jest to książka związana z językiem proceduralnym jakim jest C, a nie porównywanie go z innymi językami. Rozumiem w niektórych przypadkach warto zwrócić na to uwagę że nie które koncepcje zapożyczone z innych języków czasem mogą działać ( w zależności od użytego kompilatora) np. komentarze // i że to nie jest standardem C ale można z tego w niektórych przypadkach skorzystać. Ale takie odnoszenie się jak np. w tym dziale, akapit Uwagi, nie widzę najmniejszego sensu zamieszczać takich informacji. Może to prowadzić do wprowadzania czytelnika w błąd. POzdrawiam >>mtfk

linki wew.[edytuj]

Modyfikator (...) przydaje się w wąskich zastosowaniach, jak współbieżność i współdzielenie zasobów oraz przerwania systemowe. -- może przydałyby się tu linki wewnętrzne ? __ 77.65.160.223 15:25, 11 cze 2009 (CEST)Reply[odpowiedz]

Mógłbyś doprecyzować, o jakie linki wewn. tutaj chodzi? Pozdrawiam --Kj 23:49, 12 cze 2009 (CEST)Reply[odpowiedz]

Pytanie[edytuj]

Dlaczego nie ma ani słowa o kwalifikatorze restrict? Pozdrawiam, Karol

Zmienna bool[edytuj]

Dlaczego nigdzie nie ma mowy o zmiennych typu bool. Może wymagają korzystania z dodatkowych bibliotek, ale wypadało by o nich coś powiedzieć. 87.207.201.179

Zmienna char[edytuj]

Zmieniłem dwie rzeczy, z których się chciałbym wytłumaczyć.

1. W kontekście znaku ' użyty był na przemian "pojedynczy cudzysłów" oraz "cudzysłów" (zapewne jako skrót). Ponieważ często spotykam się (i sam używam) określenia "apostrof" (czyli inaczej niż było napisane), to zrobiłem małe rozpoznanie w temacie poprawności nazewnictwa. I tak, w standardzie ANSI C można znaleźć:

single-quote '       \'

Single quote to jeden ze znaków oznaczających cytowanie (quotation marks), czyli oczywiście cudzysłowów, a konkretniej "pojedynczy cudzysłów" (tak jest to również przetłumaczone w pierwszym zdaniu o zmiennej char). Skąd więc pomysł z apostrofem? Otóż w przypadku ASCII, korzystamy w C ze znaku 0x27, którym (wg. angielskiej wiki) jest właśnie apostrof. Na polskiej wiki możemy natomiast natknąć się na następujący opis: Zastępczy znak apostrofu i pojedynczego cudzysłowu.

Z uwagi na powyższe, sądzę, iż obie wersje, tj. pojedynczy cudzysłów oraz apostrof są poprawne. Nie używałbym natomiast w tym kontekście samego "cudzysłów", ponieważ może zostać to odczytane dosłownie (tj. jako podwójny cudzysłów) i wprowadzić w błąd.

2. Było napisane, ze znak kończący string (chodzi o ASCIIZ) to NULL, co jest nieprawidłowe. Wg. standardu znak ten nazywa się null:

A byte with all bits set to 0, called the null character, shall exist in the basic
execution character set; it is used to terminate a character string literal.

Jeśli zaś chodzi o NULL (pisane z wielkiej litery), to w standardzie jest zapis:

[...] NULL, which expands to an implementation-defined null pointer constant [...]

Można również spotkać się z użyciem NUL zamiast null - w tym wypadku jest to skrót od pełnej nazwy znaku ASCII o kodzie zero (ASCII control characters) i również w tym kontekście jest poprawny.

Podsumowując, NULL to pointer, null to bajt z wyzerowanymi wszystkimi bitami, a NUL to znak ASCII o kodzie 0. W kontekście dyskusji jedynie DWA OSTATNIE są poprawne.

Zachęcam do zgłaszania uwag, komentarzy :) gynvael.coldwind//vx 00:26, 17 cze 2010 (CEST)Reply[odpowiedz]

Typy zmiennych[edytuj]

Hmm, tutaj moim zdaniem jest kilka rzeczy do poprawy, ale przyznaje szczerze, że nie wiem za bardzo jak to poprawić (coś tam już poprawiłem btw, o tym za chwilę). Ale po kolei:

1. W języku C wyróżniamy 4 podstawowe typy zmiennych (i tutaj wymienione char, int, float i double) - przyznaje, że zaskoczyło mnie to zdanie. Tj. OK, rozumiem potrzebę podziału podstawowych typów (żeby nie klepać wszystkich short int, int, long long, etc etc), ale dlaczego w takim wypadku mamy tutaj zarówno float jak i double, które należą do tej samej grupy (posłużę się cytatem ze standardu ANSI C):

There are three floating types, designated as float , double , and
long double .  The set of values of the type float is a subset of the
set of values of the type double ; the set of values of the type
double is a subset of the set of values of the type long double. 

Rozumiem, że float i double wizualnie (jako słowa) wyglądają zupełnie różnie, niemniej jednak należą do tej samej grupy i moim zdaniem powinno się poprzestać na wymienieniu tylko float. Jakie jest Wasze zdanie na ten temat?

Przy okazji wyszła druga sprawa tutaj - mianowicie w części o float i double nie ma opisanego long double, który jest zdefiniowany przez standard (patrz powyższy cytat). Sądzę, że można (trzeba) to dopisać.

Trzecią sprawą są te oto dwa zdania:

float - typ zmiennopozycyjny (4 bajty 6 miejsc po przecinku); 
double - typ zmiennopozycyjny podwójnej precyzji (8 bajtów 15 miejsc po przecinku); 

W obu usunąłem informacje o N miejsc po przecinku, ponieważ są one błędne. Floating pointy, jak sama nazwa wskazuje, mają "pływający przecinek" (w przeciwieństwie do Fixed pointów, tj. liczb stałoprzecinkowych), tj. przy niektórych wartościach mamy 2 miejsca po przecinku, a przy innych 10. Błędnym jest pisanie, że float ma (w domyśle: zawsze) tyle, a double tyle miejsc po przecinku. Natomiast jak najbardziej jestem za tym, żeby dopisać tam coś o precyzji, przy czym przyznaję, że nie mam pomysłu jak to w przystępny sposób zrobić. Trochę zastanawia mnie też informacja w bajtach o wielkości float i double - zazwyczaj podaje się ją w bitach.

OK, tyle. Zachęcam do wypowiedzenia się co do powyższych uwag. gynvael.coldwind//vx 01:03, 17 cze 2010 (CEST)Reply[odpowiedz]

file scope[edytuj]

Witam,

gdy inicjalizuje zmienne globalne :

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
const int iSide = 1001;
int iXmax = iSide;/* height of image in pixels */

to pojawia się błąd :

c.c:32: error: initializer element is not constant

Znalazłem takie wytłumaczenie :

"It is important that all file-scope declared variables are initialised with constant expressions, not expressions involving constant variables."

Tego nie ma w teksćie. Pzdr. --Adam majewski (dyskusja) 22:16, 17 paź 2011 (CEST)Reply[odpowiedz]

  • No dobrze, błąd jest w 32 linijce kodu... Tylko gdzie ta linijka? I jaki to ma związek z modułem? --Lethern (dyskusja) 23:16, 17 paź 2011 (CEST)Reply[odpowiedz]
    • Błąd jest w instrukcji
 int iXmax = iSide;

w której zmienna globalna iXmax ma nadawaną wartość za pomocą innej zmiennej a nie bezpośredniej wartości. Przykład rzeczywiście mało czytelny, ten jest chyba lepszy :


#include <stdio.h>
/* nasze zmienne globalne */
int a =1;
int b = a;
int main ()
{  return 0;
}

Kompilacja

gcc t.c -Wall
t.c:4: error: initializer element is not constant

--Adam majewski (dyskusja) 18:45, 21 paź 2011 (CEST)Reply[odpowiedz]

  • No tak, ale const int iSide = 1001; nie jest stałą - w C nie ma stałych --Lethern (dyskusja) 20:04, 21 paź 2011 (CEST)Reply[odpowiedz]
    • chyba moje przykłady były zbyt chaotyczne i wątek się rozmył ( z mojej winy). Zadam pytanie jeszcze raz w nowym wątku. --Adam majewski (dyskusja) 08:23, 23 paź 2011 (CEST)Reply[odpowiedz]

zmienna globalna - inicjalizacja[edytuj]

Witam,

gdy inicjalizuje zmienne globalne :

#include <stdio.h>
/* nasze zmienne globalne */
int a =1;
int b = a; /* tu powstaje błąd */
int main ()
{  return 0;
}

to podczas kompilacji

gcc t.c -Wall


powstaje błąd :

t.c:4: error: initializer element is not constant

Znalazłem takie wytłumaczenie :

"It is important that all file-scope declared variables are initialised with constant expressions, not expressions involving constant variables."

Tego nie ma w teksćie.

Tego błędu nie będzie jak zmienię instrukcję :

int b = a; /* tu powstaje błąd */

na :

int b = 3; /* inicjowanie z użyciem wartości a nie innej zmiennej */

Pzdr. --Adam majewski (dyskusja) 08:27, 23 paź 2011 (CEST)Reply[odpowiedz]

W C++ żadna zmienna nie jest "wartością stałą", w szczególności słówko "const" nie robi ze zmiennej wartości stałej. Nie wiem, co powinniśmy dopisać do podręcznika w tej kwestii? Hm, że inicjować globalnych zmiennych nie można zmiennymi? --Lethern (dyskusja) 16:33, 23 paź 2011 (CEST)Reply[odpowiedz]

Tak wynika z tego przykładu, kompilator gcc nie skompiluje takiego kodu ( przynajmniej u mnie ). --Adam majewski (dyskusja) 20:28, 23 paź 2011 (CEST)Reply[odpowiedz]