Dyskusja:C/Zmienne

Najnowszy komentarz napisał(a) 12 lat temu Adam majewski w wątku zmienna globalna - inicjalizacja

"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)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)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)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)Odpowiedz

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)Odpowiedz

Mógłbyś doprecyzować, o jakie linki wewn. tutaj chodzi? Pozdrawiam --Kj 23:49, 12 cze 2009 (CEST)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)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)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)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)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)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)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)Odpowiedz

Powrót do strony „C/Zmienne”.