🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.c
26 messages
26 total messages Started by Qrczak Tue, 20 Jan 1998 18:39
Re: fscanff i sekwencja formatujaca
#692
Author: Qrczak
Date: Tue, 20 Jan 1998 18:39
105 lines
5291 bytes
On Fri, 16 Jan 1998, Tomasz Cichacki wrote:

>   fscanf(plik,"%5c%*c%s[^|]%s[^|]%s[^|]",ind,imie,nazwisko,kierunek);
[...]
> plik dane.dxt zawiera taka linie
> 
> 22334|Jan|Nowak|info

Trochę namieszałeś. Nie ma czegoś takiego jak %s[...] - po %s pole się
kończy i nawiasy są potraktowane jako tekst, który musi wystąpić w danym
miejscu. Powinno być %[...]. Na dodatek nie wiem, którędy chciałeś
przepuszczać znaki |.

Można np. tak:

fscanf (plik, "%5c|%[^|]|%[^|]|%[^|]", ind, imie, nazwisko, kierunek);

On Tue, 20 Jan 1998, Marek Kotowski wrote:

> Natomiast &nazwisko nie jest typu char**. W RATIONALE wyraznie
> podkreslono, ze dla celow zachowania ogolnej spojnosci standardu
> przyjeto, ze operator & powinien byc stosowalny takze do tablic.
> Zwieksza sie jego abstrakcyjnosc (mozna go stosowac do kazdego
> obiektu). Kompilator moze oczywiscie wysunac zastrzezenie, ale kod nie
> jest niepoprawny (w istocie kompilator moze wypisywac rozne
> ostrzezenia - jest to sprawa implementacji jezyka).

Kręcisz.

Jeśli nazwisko jest typu char *, to &nazwisko _jest_ typu char **.
Nazwisko jest wartością zmiennej, a &nazwisko jest adresem tej zmiennej
(i jest stałą o ile to jest zmienna globalna).

Jeśli natomiast nazwisko jest typu char[WIELKOŚĆ] (co jest kompatybilne
z char *), to &nazwisko jest typu char (*)[WIELKOŚĆ], czyli jest
wskaźnikiem na tablicę danej WIELKOŚCi. Wartości nazwisko i &nazwisko są
takie same, ale są innego typu - nazwisko jest wskaźnikiem na znak, a
&nazwisko jest wskaźnikiem na całą tablicę znaków. Adres tej tablicy nie
jest trzymany w żadnej zmiennej - jest stały o ile to jest zmienna
globalna.

W obu powyższych przypadkach &nazwisko jest czym innym. W pierwszym jest
wskaźnikiem na _wskaźnik_, a w drugim - wskaźnikiem na _tablicę_.

Na dodatek w przypadku argumentów funkcji napisanie char arg[WIELKOŚĆ],
tak jak i char arg[], oznacza naprawdę char *arg. Taka sobie mała
niekonsekwencja.

IMHO scanfowi lepiej konsekwentnie podawać argument typu char *, a nie
np. char (*)[WIELKOŚĆ], nawet jeśli oba miałby akurat w danej sytuacji
tę samą wartość - czyli w praktyce nie dodawać & przy zmiennych
łańcuchowych będących argumentami scanfa. Scanf nie rozróżnia typów tych
argumentów, więc i tak nie wyskoczy błąd, jeśli podamy argument typu
char (*)[WIELKOŚĆ] albo nawet char **, ale podawanie char * jest
bardziej logiczne, a nawet konieczne w przypadku kiedy to jest zmienna
wskaźnikowa, a nie bezpośrednio tablica znaków, albo kiedy jest to
argument funkcji - bo wtedy to są różne wskaźniki.

Tak więc:

[qrczak ~]$ awk '{ printf("%2d: %s\n", NR, $0) }' test.c
 1: f (char *s1, char s2[10], char **S1, char (*S2)[10])
 2: {
 3:   s1 = &s1;         /*    ŹLE:       (char *) = (char **) */
 4:   s2 = &s2;         /*    ŹLE:       (char *) = (char **) */
 5:   S1 = &s1;         /* DOBRZE:      (char **) = (char **) */
 6:   S2 = &s2;         /*    ŹLE: (char (*)[10]) = (char **) */
 7:   S2 = &s1;         /*    ŹLE: (char (*)[10]) = (char **) */
 8:   S1 = &s2;         /* DOBRZE:      (char **) = (char **) */
 9: }
10: char *s1, s2[10], **S1, (*S2)[10];
11: main ()
12: {
13:   s1 = &s1;         /*    ŹLE:       (char *) = (char **)      */
14:   s2 = &s2;         /*    ŹLE:       (char *) = (char (*)[10]) */
15:   S1 = &s1;         /* DOBRZE:      (char **) = (char **)      */
16:   S2 = &s2;         /* DOBRZE: (char (*)[10]) = (char (*)[10]) */
17:   S2 = &s1;         /*    ŹLE: (char (*)[10]) = (char **)      */
18:   S1 = &s2;         /*    ŹLE:      (char **) = (char (*)[10]) */
19: }
[qrczak ~]$ make test
cc     test.c   -o test
test.c: In function `f':
test.c:3: warning: assignment from incompatible pointer type
test.c:4: warning: assignment from incompatible pointer type
test.c:6: warning: assignment from incompatible pointer type
test.c:7: warning: assignment from incompatible pointer type
test.c: In function `main':
test.c:13: warning: assignment from incompatible pointer type
test.c:14: incompatible types in assignment
test.c:17: warning: assignment from incompatible pointer type
test.c:18: warning: assignment from incompatible pointer type
make: *** [test] Error 1
[qrczak ~]$

PS. Jestem taki mądry, bo teraz poeksperymentowałem :-)

PS/2. Nie opieram się na jakichś wyczytanych własnościach standardu,
tylko na zdrowym rozsądku popartym testami na linuksowym gcc.

-- 
                                 QRCZAK
    __("<              Marcin Kowalczyk
    \__/              qrczak@knm.org.pl
     ^^      http://qrczak.home.ml.org/
Re: fscanff i sekwencja formatujaca
#693
Author: Marek Kotowski
Date: Wed, 21 Jan 1998 09:14
39 lines
2074 bytes
Qrczak wrote:
> On Tue, 20 Jan 1998, Marek Kotowski wrote:
> 
> > Natomiast &nazwisko nie jest typu char**. W RATIONALE wyraznie
> > podkreslono, ze dla celow zachowania ogolnej spojnosci standardu
> > przyjeto, ze operator & powinien byc stosowalny takze do tablic.
> > Zwieksza sie jego abstrakcyjnosc (mozna go stosowac do kazdego
> > obiektu). Kompilator moze oczywiscie wysunac zastrzezenie, ale kod nie
> > jest niepoprawny (w istocie kompilator moze wypisywac rozne
> > ostrzezenia - jest to sprawa implementacji jezyka).
> 
> Krêcisz.

  Zatem jestem w znakomitym towarzystwie, tj. autorow standardu. :-)
Rozumiem, ze wedlug Pana i oni kreca.

> 
> Je¶li nazwisko jest typu char *, to &nazwisko _jest_ typu char **.

Nie pisalem, ze nazwisko jest typu *char. Zalozylem, chociazby
sadzac po nazwie, ze jest to tablica znakow:

char nazwisko[LENGTH];

  To jest tu istotne i o tym napisano w RATIONALE (tj. o uzywaniu
operatora & wobec tablicy). &nazwisko nie jest traktowane jako char**
(sam Pan o tym dalej napisal).
  W istocie dyskusji by nie bylo, gdyby w wyjsciowym postingu
podane byly definicje zmiennych. 

> PS/2. Nie opieram siê na jakich¶ wyczytanych w³asno¶ciach standardu,
> tylko na zdrowym rozs±dku popartym testami na linuksowym gcc.

  I tu sie roznimy. Zdrowy rozsadek mozna stosowac tam, gdzie
standard lub RATIONALE, ktore jest jego integralna czescia,
nie wypowiada sie dostatecznie jasno czy w ogole.


Marek Kotowski
Re: fscanff i sekwencja formatujaca
#695
Author: Mechanik
Date: Wed, 21 Jan 1998 19:48
26 lines
1653 bytes
Dnia Tue, 20 Jan 1998 19:39:21 +0100 Qrczak <qrczak@knm.org.pl> napisal tak:

>On Tue, 20 Jan 1998, Marek Kotowski wrote:

>Jeśli nazwisko jest typu char *, to &nazwisko _jest_ typu char **.
>Nazwisko jest wartością zmiennej, a &nazwisko jest adresem tej zmiennej
>(i jest stałą o ile to jest zmienna globalna).

>Jeśli natomiast nazwisko jest typu char[WIELKOŚĆ] (co jest kompatybilne
>z char *), to &nazwisko jest typu char (*)[WIELKOŚĆ], czyli jest
>wskaźnikiem na tablicę danej WIELKOŚCi. Wartości nazwisko i &nazwisko są
>takie same, ale są innego typu - nazwisko jest wskaźnikiem na znak, a
>&nazwisko jest wskaźnikiem na całą tablicę znaków. Adres tej tablicy nie
>jest trzymany w żadnej zmiennej - jest stały o ile to jest zmienna
>globalna.

Chce tylko zauwazyc ze jesli mamy:

char nazwisko[WIELKOSC];

to wyrazenie &nazwisko nie ma sensu, tak jak nie ma sensu wyrazenie &3.1415, bo nie
mozna brac adresu stalej. I wtedy kompilator daje ostrzezenie.

VANITAS VANITATUM ET OMNIA VANITAS

Mechanik
Re: fscanff i sekwencja formatujaca
#694
Author: Karpierz
Date: Wed, 21 Jan 1998 20:38
56 lines
2195 bytes
Marek Kotowski <mkot@imm.org.pl> napisal(a) 
[...]
> > Jeśli nazwisko jest typu char *, to &nazwisko _jest_ typu char **.
> 
> Nie pisalem, ze nazwisko jest typu *char. Zalozylem, chociazby
> sadzac po nazwie, ze jest to tablica znakow:
> 
> char nazwisko[LENGTH];
> 
>   To jest tu istotne i o tym napisano w RATIONALE (tj. o uzywaniu
> operatora & wobec tablicy). &nazwisko nie jest traktowane jako char**

Kazdy kij ma dwa konce:

zalozmy ze wg RATIONALE mamy:

1).

char nazwisko [LENGTH];

.... // dluuuugi fragment programu

scanf ("%s", &nazwisko);

i przyjdzie nam ochota lub  zostaniemy smuszeni zmienic to na 
dynamiczny przydzial:

2).

char * nazwisko = (char *) malloc (LENGTH);

.... // dluuuugi fragment programu

scanf ("%s", &nazwisko);

no i mamy wskaznik do wskaznika czyli char ** zamiast char *m
a dam sobie reke uciac :), ze scanf sie nie zbuntuje (ani kompilator)....
No i mamy piekny przyklad zawieszenia sie programu.
A co bedzie gdy takich scanfow czy tym podobnych bedzie duzo
i to rozsianych po calym programie ? - strach myslec..  
trzeba wszystkie sprawdzic...
To ja juz wole klasycznie choc moze mniej "jednolicie":

char nazwisko [LENGTH];

.... // dluuuuugi fragment programu

scanf ("%s", nazwisko);

bo widze od razu po %s ze chodzi o char * i nie musze sie martwic 
ze zmiana deklaracji zmiennej nazwisko cos popsuje.

-- 
Pozdrawiam                                         Adam Karpierz   
mailto:karpierz@intertele.pl
http://www.intertele.pl/users/karpierz 
Re: fscanff i sekwencja formatujaca
#696
Author: Marek Kotowski
Date: Thu, 22 Jan 1998 09:43
19 lines
1286 bytes
Mechanik wrote:
> 
> Chce tylko zauwazyc ze jesli mamy:
> 
> char nazwisko[WIELKOSC];
> 
> to wyrazenie &nazwisko nie ma sensu, tak jak nie ma sensu wyrazenie &3.1415, bo nie
> mozna brac adresu stalej. I wtedy kompilator daje ostrzezenie.

  To nie jest dobre porownanie. nazwisko jest adresem w pamieci,
niekoniecznie stalym, np. jesli tablica jest zmienna lokalna.
3.14 jest stala, a nie zmienna i sama w sobie nie zajmuje miejsca
w pamieci.
  Wyrazenie &nazwisko ma sens adresu tablicy (pisano o tym juz
w tym watku). Mozna dyskutowac, na ile bywa przydatne praktycznie.
Autorzy standardu uznali, ze jest sensowne go dopuscic. 


   Marek Kotowski
Re: fscanff i sekwencja formatujaca
#697
Author: Qrczak
Date: Thu, 22 Jan 1998 17:44
38 lines
2567 bytes
On Thu, 22 Jan 1998, Marek Kotowski wrote:

> > to wyrazenie &nazwisko nie ma sensu, tak jak nie ma sensu wyrazenie &3.1415, bo nie
> > mozna brac adresu stalej. I wtedy kompilator daje ostrzezenie.
> 
> To nie jest dobre porownanie. nazwisko jest adresem w pamieci,
> niekoniecznie stalym, np. jesli tablica jest zmienna lokalna. 3.14
> jest stala, a nie zmienna i sama w sobie nie zajmuje miejsca w
> pamieci.

Nie takie złe było to porównanie. Adres nie jest co prawda stały, ale
chodzi o to, że on nie jest pamiętany w żadnym miejscu pamięci! Więc
branie adresu tego adresu jest bez sensu.

C to obchodzi w ten sposób, że niby nazwisko jest wskaźnikiem na znak,
jak każda tablica, ale może być traktowane również jako tablica jako
taka, bez żadnego wskaźnika. Wtedy już to może mieć adres, taki sam jak
wskaźnik na zerowy element.

> Wyrazenie &nazwisko ma sens adresu tablicy (pisano o tym juz w tym
> watku). Mozna dyskutowac, na ile bywa przydatne praktycznie. Autorzy
> standardu uznali, ze jest sensowne go dopuscic.

Ja bym się na nich nie obraził, gdyby nie można było dopuścić. Jest to o
tyle niekonsekwentne, że argument funkcji typu char[WIELKOŚĆ] jest mimo
wszystko wskaźnikiem, który tym razem ma swój adres, i &tablica ma inne
znaczenie w zależności od tego, czy ta tablica jest zmienną, czy _tak
samo opisanym_ argumentem funkcji. Na dodatek, jak mówiłem i jak to
dobrze powiedział Adam Karpierz, jeśli to nie jest tablica, tylko
wskaźnik, to w większości sytuacji zachowuje się tak samo, z wyjatkiem
tego nieszczęsnego brania adresu. Można się bez konstrukcji typu
&tablica obyć.

-- 
                                 QRCZAK
    __("<              Marcin Kowalczyk
    \__/              qrczak@knm.org.pl
     ^^      http://qrczak.home.ml.org/
Re: fscanff i sekwencja formatujaca
#714
Author: Mechanik
Date: Thu, 22 Jan 1998 20:50
55 lines
2476 bytes
Dnia Thu, 22 Jan 1998 10:43:08 +0100 Marek Kotowski <mkot@imm.org.pl> napisal tak:

>Mechanik wrote:
>> 
>> Chce tylko zauwazyc ze jesli mamy:
>> 
>> char nazwisko[WIELKOSC];
>> 
>> to wyrazenie &nazwisko nie ma sensu, tak jak nie ma sensu wyrazenie &3.1415, bo nie
>> mozna brac adresu stalej. I wtedy kompilator daje ostrzezenie.

>  To nie jest dobre porownanie. nazwisko jest adresem w pamieci,
>niekoniecznie stalym, np. jesli tablica jest zmienna lokalna.
>3.14 jest stala, a nie zmienna i sama w sobie nie zajmuje miejsca
>w pamieci.

To nie tak! Jesli mamy tablice char nazwisko[WIELKOSC] to sam identyfikator
tablicy czyli nazwisko jest adresem pierwszego elementu tablicy:

nazwisko == &nazwisko[0]

Dla przykladu jesli tablica nazwisko[WIELKOSC] znajduje sie pod adresem 12345
to wartoscia wyrazenia nazwisko jest adres 12345. Nie jest to zmienna i sam w sobie
nie zajmuje miejsca w pamieci.

Jesli proponujesz brac adres &nazwisko, to proponujesz brac adres &&nazwisko[0], co
jest bez sensu. Moj kompilator daje w takim wypadku stosowne ostrzezenie:

'&' on function/array, ignored

czyli po prostu ignoruje takie cudo.

> Wyrazenie &nazwisko ma sens adresu tablicy (pisano o tym juz
>w tym watku). Mozna dyskutowac, na ile bywa przydatne praktycznie.
>Autorzy standardu uznali, ze jest sensowne go dopuscic. 

Wyrazenie &nazwisko ma sens rowny wyrazeniu nazwisko, bo po prostu & jest tu
ignorowane, i nie jest adresem tablicy tylko adresem pierwszego alementu tablicy.

Tak samo jak masz

 int fun(void);

to fun jest adresem funkcji oraz &fun jest adresem
funkcji i jest to to samo.

nazwisko == &nazwisko == &nazwisko[0]
fun = &fun

Jest to nielogiczne i wola o pomste do nieba, ale tak wlasnie jest.


VANITAS VANITATUM ET OMNIA VANITAS

Mechanik
Re: fscanff i sekwencja formatujaca
#715
Author: Marek Kotowski
Date: Fri, 23 Jan 1998 11:53
32 lines
1620 bytes
Mechanik wrote:
> 
> Jesli proponujesz brac adres &nazwisko, to proponujesz brac adres &&nazwisko[0], co
> jest bez sensu. Moj kompilator daje w takim wypadku stosowne ostrzezenie:

  Rece opadaja. :-)
  Nie proponuje brac &nazwisko. Mowie tylko, ze jest to zapis 
uprawniony i tak postanowiono w standardzie. Wyrazenie
&nazwisko nie jest adresem &&nazwisko[0]. Gdyby tak bylo,
to Panski kompilator by "takiego cuda" nie zignorowal. :-)

> 
> '&' on function/array, ignored
> 
> czyli po prostu ignoruje takie cudo.

Co nie zmienia faktu, ze akceptuje takie wyrazenie jako
uprawnione, tak jak chcieli autorzy standardu.

> nazwisko == &nazwisko == &nazwisko[0]
> fun = &fun
> 
> Jest to nielogiczne i wola o pomste do nieba, ale tak wlasnie jest.
> 

  Jest to logiczne i wynika z regul domyslnosci w C.
Jak Pan chce, niech Pan wola niebiosa, ale watpie, by
chcialy sie mscic. :-)

  Pozdrawiam

  Marek Kotowski
Re: fscanff i sekwencja formatujaca
#698
Author: Marek Kotowski
Date: Fri, 23 Jan 1998 12:22
35 lines
2274 bytes
Qrczak wrote:
> 
> 
> Nie takie z³e by³o to porównanie. Adres nie jest co prawda sta³y, ale
> chodzi o to, ¿e on nie jest pamiêtany w ¿adnym miejscu pamiêci! Wiêc
> branie adresu tego adresu jest bez sensu.

Nie rozumiem tej uwagi. A jaki adres jest pamietany w jakims
miejscu pamieci? Jest tak: kompilator analizuje wyrazenie.
Napotyka w nim "nazwisko" lub "&nazwisko", zamienia je
na konkretny adres i uzywa go przy szacowaniu wyrazenia.
Liczby 3.14 nie zamienia na zaden adres, bo to nie jest
zmienna, ktora by miala adres, tak jak ma go tablica.

> 
> Ja bym siê na nich nie obrazi³, gdyby nie mo¿na by³o dopu¶ciæ. Jest to o
> tyle niekonsekwentne, ¿e argument funkcji typu char[WIELKO¦Æ] jest mimo
> wszystko wska¼nikiem, który tym razem ma swój adres, i &tablica ma inne
> znaczenie w zale¿no¶ci od tego, czy ta tablica jest zmienn±, czy _tak
> samo opisanym_ argumentem funkcji. Na dodatek, jak mówi³em i jak to
> dobrze powiedzia³ Adam Karpierz, je¶li to nie jest tablica, tylko
> wska¼nik, to w wiêkszo¶ci sytuacji zachowuje siê tak samo, z wyjatkiem
> tego nieszczêsnego brania adresu. Mo¿na siê bez konstrukcji typu
> &tablica obyæ.
> 

Oczywiscie. Tyle, ze autorzy standardu musieli rozwazyc, czy
dopuscic wyrazenie &nazwisko czy nie. Uznano, ze ze wzgledu na
spojnosc jezyka (operator & powinien byc stosowalny do
wszystkich obiektow) nalezy dopuscic takie wyrazenia. Gdyby
zabronili takich konstrukcji, standard bylby niespojny,
przynajmniej pod tym wzgledem.


  Marek Kotowski
Re: fscanff i sekwencja formatujaca
#699
Author: Karpierz
Date: Fri, 23 Jan 1998 16:29
64 lines
3312 bytes
Marek Kotowski <mkot@imm.org.pl> napisal
> Qrczak wrote:
> > 
> > 
> > Nie takie złe było to porównanie. Adres nie jest co prawda stały, ale
> > chodzi o to, że on nie jest pamiętany w żadnym miejscu pamięci! Więc
> > branie adresu tego adresu jest bez sensu.
> 
> Nie rozumiem tej uwagi. A jaki adres jest pamietany w jakims
> miejscu pamieci? 

taki nie:

char nazwisko [ILOSC];

a taki jest:

char * nazwisko = (char *) malloc (ILOSC);

nie rozumiem niezrozumienia uwagi... ?

>Jest tak: kompilator analizuje wyrazenie.
> Napotyka w nim "nazwisko" lub "&nazwisko", zamienia je
> na konkretny adres i uzywa go przy szacowaniu wyrazenia.

No i powstaje galimatias.
W standardzie jest jasno napisane, ze nazwa tablicy jest traktowana 
jako adres jej pierwszego elementu (podobnie jak nazwa funkcji jest 
traktowana jako adres funkcji /mozna spokojnie napisac:
 (funkcja) (argumenty); , czasami sie to swiadomie nawet stosuje/.
I czy teraz nie jest tak przy powyzszym zalozeniu, ze przy intertpetacji 
&tablica jest stosowana _najpierw_ ta zasada, co powoduje ze jest 
pobierany adres czegos co faktycznie nie ma adresu ? 
I stad te warningi ...
Jest to po prostu sztuczne i bierze sie z faktu, ze chce sie na sile 
naprawic zaszlosc, /czyli traktowanie nazwy tablicy jak pointera do niej 
mimo, ze faktycznie sa to dwa rozne typy obiektow i wewnetrznie przez 
kompilator tez sa traktowane odmiennie. Dobrze ze chociaz struktury 
sie temu oparly /.
To ze jezyk sie tak a nie inaczej rozwijal i ze teraz sa z tym klopoty 
mozna zrozumiec i zaakceptowac, natomiast nie rozumiem, ze probujesz
tlumaczyc, ze wlasnie standard w tym miejscu ma racje ?

Standard != nietykalny...

> Oczywiscie. Tyle, ze autorzy standardu musieli rozwazyc, czy
> dopuscic wyrazenie &nazwisko czy nie. Uznano, ze ze wzgledu na
> spojnosc jezyka (operator & powinien byc stosowalny do
> wszystkich obiektow) nalezy dopuscic takie wyrazenia. 

Powyzsze byloby logiczne gdyby zlikwidowac zasade ze:
Nazwa tablicy jest traktowana jako adres jej pierwszego elementu.

> Gdyby zabronili takich konstrukcji, standard bylby niespojny,
> przynajmniej pod tym wzgledem.

W/g mnie byl miejscami dziwny, ale spojny, natomiast teraz stal sie 
niespojny czyli o wiele bardziej niebezpieczny , co staralem sie 
udowodnic w poprzednim moim liscie.

-- 
Pozdrawiam                                         Adam Karpierz   
mailto:karpierz@intertele.pl
http://www.intertele.pl/users/karpierz 
Re: fscanff i sekwencja formatujaca
#716
Author: Mechanik
Date: Fri, 23 Jan 1998 19:58
31 lines
1642 bytes
Dnia Fri, 23 Jan 1998 12:53:36 +0100 Marek Kotowski <mkot@imm.org.pl> napisal tak:

>> Jesli proponujesz brac adres &nazwisko, to proponujesz brac adres &&nazwisko[0], co
>> jest bez sensu. Moj kompilator daje w takim wypadku stosowne ostrzezenie:

>  Rece opadaja. :-)
>  Nie proponuje brac &nazwisko. Mowie tylko, ze jest to zapis 
> uprawniony i tak postanowiono w standardzie.

Sorry, uzylem "proponujesz" w mniej doslownym sensie.

> Wyrazenie
>&nazwisko nie jest adresem &&nazwisko[0]. Gdyby tak bylo,
>to Panski kompilator by "takiego cuda" nie zignorowal. :-)

Wg matematyki jest. Wiem, C to nie matematyka - w matematyce nie ma wyjatkow :-)

>Jak Pan chce, niech Pan wola niebiosa, ale watpie, by
>chcialy sie mscic. :-)

Pan Bog nie rychliwy, ale sprawiedliwy.

>  Pozdrawiam
>  Marek Kotowski

I ja pozdrawiam i zycze milego weekendu.


VANITAS VANITATUM ET OMNIA VANITAS

Mechanik
Re: fscanff i sekwencja formatujaca
#707
Author: Michal Kaczmarczyk
Date: Sat, 24 Jan 1998 12:49
14 lines
1516 bytes
On Fri, 23 Jan 1998, Marek Kotowski wrote:

> Oczywiscie. Tyle, ze autorzy standardu musieli rozwazyc, czy
> dopuscic wyrazenie &nazwisko czy nie. Uznano, ze ze wzgledu na
> spojnosc jezyka (operator & powinien byc stosowalny do
> wszystkich obiektow) nalezy dopuscic takie wyrazenia. Gdyby
> zabronili takich konstrukcji, standard bylby niespojny,
> przynajmniej pod tym wzgledem.

To raczej w tym momencie standard jest mało spójny, bo czasami "&" cos
oznacza (wzięcie adresu) a czasem nic (jak w cytowanym przypadku)... 

_______________________________________________________________________________
Michał Kaczmarczyk  mailto:mik@iname.com http://student.uci.agh.edu.pl/~kaczmar
Re: fscanff i sekwencja formatujaca
#700
Author: Marek Kotowski
Date: Sat, 24 Jan 1998 14:38
64 lines
3195 bytes
Karpierz wrote:
> > Nie rozumiem tej uwagi. A jaki adres jest pamietany w jakims
> > miejscu pamieci?
> 
> taki nie:
> 
> char nazwisko [ILOSC];
> 
> a taki jest:
> 
> char * nazwisko = (char *) malloc (ILOSC);
> 
> nie rozumiem niezrozumienia uwagi... ?
> 

Niech Pan  sie nie  dziwi. Nie wszyscy sa tacy lotni jak
Pan. :-)

BTW -  nie musi Pan stosowac rzutu przy wywolaniu malloc.
Jest to zbedne, a nawet niewskazane.

> W standardzie jest jasno napisane, ze nazwa tablicy jest traktowana
> jako adres jej pierwszego elementu (podobnie jak nazwa funkcji jest
> traktowana jako adres funkcji /mozna spokojnie napisac:
>  (funkcja) (argumenty); , czasami sie to swiadomie nawet stosuje/.
> I czy teraz nie jest tak przy powyzszym zalozeniu, ze przy intertpetacji
> &tablica jest stosowana _najpierw_ ta zasada, co powoduje ze jest
> pobierany adres czegos co faktycznie nie ma adresu ?

Moim zdaniem nie jest tak. Uzywajac slowa _najpierw_ zaklada
Pan czy  sugeruje  implicite  okreslony  sposob  dzialania
kompilatora przy analizie kodu. Oczywiscie argument bylby sluszny,
gdyby samo branie adresu tablicy np. w wywolaniu funkcji
bylo punktem  sekwencji. Nie  jest. Kompilator  analizuje
cale wyrazenie &Tablica i zamienia je na adres.

> I stad te warningi ...
> Jest to po prostu sztuczne i bierze sie z faktu, ze chce sie na sile
> naprawic zaszlosc, /czyli traktowanie nazwy tablicy jak pointera do niej
> mimo, ze faktycznie sa to dwa rozne typy obiektow i wewnetrznie przez
> kompilator tez sa traktowane odmiennie. Dobrze ze chociaz struktury
> sie temu oparly /.

Struktura jest  innym bytem  niz tablica.  IMO  jest  ona
blizsza zmiennej  integralnej niz tablicy, tyle, ze mozna
miec dostep  do jej wnetrza przez nazwy. W strukturze nie
ma - powiedzmy tak - wielokrotnosci wystapien, ktora jest
w tablicy.  Ale w  tej sprawie  ma Pan  najwyrazniej inne
zdanie. Odnotowuje roznice.

> 
> W/g mnie byl miejscami dziwny, ale spojny, natomiast teraz stal sie
> niespojny czyli o wiele bardziej niebezpieczny , co staralem sie
> udowodnic w poprzednim moim liscie.

Moim zdaniem przyjete zalozenie o stosowalnosci operatora
& wobec  tablic jest  konieczne dla  spojnosci jezyka. Tu
zgadzam sie  z autorami  standardu.  Panskim  zdaniem  to
zalozenie  jest   szkodliwe.  Odnotujmy   te  roznice   i
zamknijmy dyskusje.

  Pozdrawiam

  Marek Kotowski
Re: fscanff i sekwencja formatujaca
#708
Author: Marek Kotowski
Date: Sat, 24 Jan 1998 15:04
22 lines
1675 bytes
Michal Kaczmarczyk wrote:
> 
> To raczej w tym momencie standard jest ma³o spójny, bo czasami "&" cos
> oznacza (wziêcie adresu) a czasem nic (jak w cytowanym przypadku)...

  Najpierw Ritchie wymyslil C, a 16 lat potem wprowadzono
standard.
  Oczywiscie, jest to pewna niekonsekwencja. Ale moze Pan
znalezc takich niekonsekwencji w C wiecej. Zaleznie od
kontekstu * znaczy branie zawartosci adresu lub mnozenie
dwoch argumentow. Przecinek w jednym kontekscie jest punktem
sekwencji, w innym nie. while jest raz samodzielna petla,
a kiedy indziej koncem petli do-while. Operator &, o ktorym
tyle bylo mowy, raz oznacza branie adresu, a kiedy indziej
jest operatorem bitowym.  
  Moze Pan to wszystko wyciagnac przeciwko C. Rzecz w tym, 
ze takie bylo zalozenie. Ritchie chcial uzyskac jezyk maly
i zwarty i szereg spraw uzaleznil od kontekstu.

  Pozdrawiam

  Marek Kotowski
Re: fscanff i sekwencja formatujaca
#701
Author: Qrczak
Date: Sat, 24 Jan 1998 17:56
38 lines
2855 bytes
On Sat, 24 Jan 1998, Marek Kotowski wrote:

> Struktura jest innym bytem niz tablica. IMO jest ona blizsza zmiennej
> integralnej niz tablicy, tyle, ze mozna miec dostep do jej wnetrza
> przez nazwy. W strukturze nie ma - powiedzmy tak - wielokrotnosci
> wystapien, ktora jest w tablicy. Ale w tej sprawie ma Pan najwyrazniej
> inne zdanie. Odnotowuje roznice.

Dla mnie takie rozróżnienie jest sztuczne. Jest ono faktem w C, ale to
wynika tylko z założeń C, a nie z naturalnego porządku rzeczy. W innych
językach nie ma żadnego powodu, żeby struktura była bardziej "zwarta"
niż tablica.

IMHO po prostu twórcom C nie chciało się robić osobnych konstrukcji do
tablic zmiennej długości. W ogóle nie chciało im się robić tablic, więc
zaemulowali je na wskaźnikach, wsadzając bezpośrednio w pojęcie tablicy
tak mało, jak to było możliwe (nawet operator [] nie działa na tablicy,
tylko na wskaźniku). Udało im się to zrobić w taki sposób, że mimo to
tablicowe konstrukcje wyglądają w miarę naturalnie, ale pewne skutki
uboczne też są (chociażby to, że w odróżnieniu od Pascala tablice w C
muszą być indeksowane liczbami całkowitymi, i to poczynając od zera).

IMHO to wcale nie jest najbardziej naturalne podejście. Może prostsze w
implementacji - tylko tyle.

Przed chwilą sprawdziłem, że przy deklaracji char s[10] jest
sizeof (s) == 10, więc nazwa tablicy nie jest tak do końca wskaźnikiem
na jej zerowy element. Trochę to się robi niekonsekwentne, bo jeśli
uznamy, że s jest tablicą, a nie wskaźnikiem, to musimy nieco inaczej
niż do tego przywykłem zdefiniować działanie operatorów
* (jednoargumentowego), + i -. Na przykład nie jest prawdą, że
sizeof(x) == sizeof(&*x), o ile nawet prawa strona ma sens.

-- 
                                 QRCZAK
    __("<              Marcin Kowalczyk
    \__/              qrczak@knm.org.pl
     ^^      http://qrczak.home.ml.org/
Re: fscanff i sekwencja formatujaca
#706
Author: Karpierz
Date: Sat, 24 Jan 1998 22:52
80 lines
2951 bytes
Marek Kotowski <mkot@imm.org.pl> napisal
> Karpierz wrote:
> > > Nie rozumiem tej uwagi. A jaki adres jest pamietany w jakims
> > > miejscu pamieci?
> > 
> > taki nie:
> > 
> > char nazwisko [ILOSC];
> > 
> > a taki jest:
> > 
> > char * nazwisko = (char *) malloc (ILOSC);
> > 
> > nie rozumiem niezrozumienia uwagi... ?
> > 
> 
> Niech Pan  sie nie  dziwi. Nie wszyscy sa tacy lotni jak
> Pan. :-)

Widze ze zaczynasz (Pan) coraz bardziej "merytoryczna" dyskusje...
To miala byc zlosliwosc lepiej wiedzacego ??? smutne...

> BTW -  nie musi Pan stosowac rzutu przy wywolaniu malloc.
> Jest to zbedne, a nawet niewskazane.

Oooo :) czepiamy sie !
Tak :) ? A to mnie ubawiles (Pan) :).
Wszedzie w ksiazce K&C jest stosowane takie rzutowanie i tez 
bylem przekonany ze wlasnie tak jest bardziej prawidlowo, a tu
masz.. taka wolta.. nawet niewskazane...
Prosze o uzasadnienie.

Osobiscie wszystkim zalecam wlasnie stosowanie rzutowania.
Dlaczego ?

Podam tylko jeden prosty przyklad, na tyle malo teoretyczny 
co bardzo zyciowy:

#include <alloc.h>

int main ()
{
char * x = malloc (123);
...
}

Pod C sie kompiluje ? rzeczywiscie... No to piszemy "krocej"...
Po co sie meczyc... Po kilku latach stwierdzamy ze mamy
juz kilka MB kodu w C... 
No tak, ale te obiekty i to C++. Wypada sprobowac.
Nie powinno byc klopotu, przeciez pisalismy "przenosnie",
Wszyscy mowia ze poza nielicznymi wyjatkami C jest
wlasciwie podzbiorem C++ no wiec...
Probujemy kompilowac pod C++ i... 
mamy tyle "nielicznych" wyjatkow ile wywolan funkcji
malloc (czy innych brakow rzutowan prawej strony wyrazenia)...
w postaci bledow typu:

cannot convert void * to char * !

lub tym podobnych.

A przeciez moglismy stosowac te "zbedne" i "niewskazane" 
rzutowania:

#include <alloc.h>

int main ()
{
char * x = (char *) malloc (123);
...
}

No coz... przeciez szczesliwi czasu nie licza...

-- 
Pozdrawiam                                         Adam Karpierz   
mailto:karpierz@intertele.pl
http://www.intertele.pl/users/karpierz 
 
Re: fscanff i sekwencja formatujaca
#709
Author: Michal Kaczmarczyk
Date: Mon, 26 Jan 1998 03:35
59 lines
3612 bytes
On Sat, 24 Jan 1998, Marek Kotowski wrote:

> Michal Kaczmarczyk wrote:
> > 
> > To raczej w tym momencie standard jest mało spójny, bo czasami "&" cos
> > oznacza (wzięcie adresu) a czasem nic (jak w cytowanym przypadku)...
> 
>   Najpierw Ritchie wymyslil C, a 16 lat potem wprowadzono
> standard.
>   Oczywiscie, jest to pewna niekonsekwencja. Ale moze Pan
> znalezc takich niekonsekwencji w C wiecej. Zaleznie od
> kontekstu * znaczy branie zawartosci adresu lub mnozenie
> dwoch argumentow. Przecinek w jednym kontekscie jest punktem
> sekwencji, w innym nie. while jest raz samodzielna petla,
> a kiedy indziej koncem petli do-while. Operator &, o ktorym
> tyle bylo mowy, raz oznacza branie adresu, a kiedy indziej
> jest operatorem bitowym.  

...a kiedy indziej oznacza "no operation"... :-) 

Nie przekonuje mnie to. We wszystkich innych sytuacjach sprawa się
rozstrzyga po uwzględnieniu lokalnego kontekstu. A żeby sprawdzić czy
jednoargumentowy "&" ma zadziałać czy nie, to trzeba sprawdzić typ
argumentu stojącego po nim. A typ ten może być zdefiniowany kilka tysięcy
linii wczesniej, albo np. w pliku nagłówkowym... Poza tym konstrukcja ta
może prowadzić do nieporozumień (patrz przykład na końcu postu).

>   Moze Pan to wszystko wyciagnac przeciwko C. Rzecz w tym, 
> ze takie bylo zalozenie. Ritchie chcial uzyskac jezyk maly
> i zwarty i szereg spraw uzaleznil od kontekstu.

1. Udało mu się uzyskać język mały i zwarty co do kodu zródłowego, a nie
kompilatora. Ale i tak bije go na głowę kod maszynowy (pod obydwoma
względami)...

2. <P COMMENT="fikcja próbująca wyjaśnić zaistniałą sytuację">
 Richtie tego myku z "&" nie wymyslił. Pojawiło się to z początku w
niektórych implementacjach C, które były zrobione przez gości niezbyt
rozumiejących intencję autora. A potem przyszedł Standard (Panowie! czapki
z głów!), który stwierdził: "...ponieważ w wielu implementacjach języka C
taka konstrukcja jest dopuszczona, więc - żeby zachować z nimi zgodnosć
(jakże szczytny cel!) - damy taką możliwosć w standardzie..." </P>

3. Kiepskie założenie (co do "&"). Oto do czego ono prowadzi: 

#include<stdlib.h>
#include<stdio.h>
main(){
 char *a = (char *)malloc(100);
 int b;
 scanf("%d %10s", &b, &a);
 printf("%d %s\n", &b, &a);
}

Jeśli ktoś dalej nie wie na czym ów myk polega radzę ten program
skompilować, uruchomić i sprawdzić, czy działa zgodnie z "założeniami". 

______________________________________________________________________________
Michał Kaczmarczyk  mailto:mik@iname.com http://student.uci.agh.edu.pl/~kaczmar
Re: fscanff i sekwencja formatujaca
#712
Author: Michal Kaczmarczyk
Date: Mon, 26 Jan 1998 03:48
59 lines
3568 bytes
On Sat, 24 Jan 1998, Marek Kotowski wrote:

> Michal Kaczmarczyk wrote:
> > 
> > To raczej w tym momencie standard jest mało spójny, bo czasami "&" cos
> > oznacza (wzięcie adresu) a czasem nic (jak w cytowanym przypadku)...
> 
>   Najpierw Ritchie wymyslil C, a 16 lat potem wprowadzono
> standard.
>   Oczywiscie, jest to pewna niekonsekwencja. Ale moze Pan
> znalezc takich niekonsekwencji w C wiecej. Zaleznie od
> kontekstu * znaczy branie zawartosci adresu lub mnozenie
> dwoch argumentow. Przecinek w jednym kontekscie jest punktem
> sekwencji, w innym nie. while jest raz samodzielna petla,
> a kiedy indziej koncem petli do-while. Operator &, o ktorym
> tyle bylo mowy, raz oznacza branie adresu, a kiedy indziej
> jest operatorem bitowym.  

...a kiedy indziej oznacza "no operation"... :-) 

Nie przekonuje mnie to. We wszystkich innych sytuacjach sprawa się
rozstrzyga po uwzględnieniu lokalnego kontekstu. A żeby sprawdzić czy
jednoargumentowy "&" ma zadziałać czy nie, to trzeba sprawdzić typ
argumentu stojącego po nim. A typ ten może być zdefiniowany kilka tysięcy
linii wczesniej, albo np. w pliku nagłówkowym... Poza tym konstrukcja ta
może prowadzić do nieporozumień (patrz przykład na końcu postu).

>   Moze Pan to wszystko wyciagnac przeciwko C. Rzecz w tym, 
> ze takie bylo zalozenie. Ritchie chcial uzyskac jezyk maly
> i zwarty i szereg spraw uzaleznil od kontekstu.

1. Udało mu się uzyskać język mały i zwarty co do kodu zródłowego, a nie
kompilatora. Ale i tak bije go na głowę kod maszynowy (pod obydwoma
względami)...

2. <P COMMENT="fikcja próbująca wyjaśnić zaistniałą sytuację">
 Richtie tego myku z "&" nie wymyslił. Pojawiło się to z początku w
niektórych implementacjach C, które były zrobione przez gości niezbyt
rozumiejących intencję autora. A potem przyszedł Standard (Panowie! czapki
z głów!), który stwierdził: "...ponieważ w wielu implementacjach języka C
taka konstrukcja jest dopuszczona, więc - żeby zachować z nimi zgodnosć
(jakże szczytny cel!) - damy taką możliwosć w standardzie..." </P>

3. Kiepskie założenie (co do "&"). Oto do czego ono prowadzi: 

#include<stdlib.h>
#include<stdio.h>
main(){
 char *a = (char *)malloc(100);
 int b;
 scanf("%d %10s", &b, &a);
 printf("%d %s\n", &b, &a);
}

Jeśli ktoś dalej nie wie na czym ów myk polega radzę ten program
skompilować, uruchomić i sprawdzić, czy działa zgodnie z "założeniami". 

_______________________________________________________________________________
Michał Kaczmarczyk  mailto:mik@iname.com http://student.uci.agh.edu.pl/~kaczmar
Re: fscanff i sekwencja formatujaca
#713
Author: Michal Kaczmarczyk
Date: Mon, 26 Jan 1998 03:55
59 lines
3615 bytes
On Sat, 24 Jan 1998, Marek Kotowski wrote:

> Michal Kaczmarczyk wrote:
> > 
> > To raczej w tym momencie standard jest mało spójny, bo czasami "&" cos
> > oznacza (wzięcie adresu) a czasem nic (jak w cytowanym przypadku)...
> 
>   Najpierw Ritchie wymyslil C, a 16 lat potem wprowadzono
> standard.
>   Oczywiscie, jest to pewna niekonsekwencja. Ale moze Pan
> znalezc takich niekonsekwencji w C wiecej. Zaleznie od
> kontekstu * znaczy branie zawartosci adresu lub mnozenie
> dwoch argumentow. Przecinek w jednym kontekscie jest punktem
> sekwencji, w innym nie. while jest raz samodzielna petla,
> a kiedy indziej koncem petli do-while. Operator &, o ktorym
> tyle bylo mowy, raz oznacza branie adresu, a kiedy indziej
> jest operatorem bitowym.  

...a kiedy indziej oznacza "no operation"... :-) 

Nie przekonuje mnie to. We wszystkich innych sytuacjach sprawa się
rozstrzyga po uwzględnieniu lokalnego kontekstu. A żeby sprawdzić czy
jednoargumentowy "&" ma zadziałać czy nie, to trzeba sprawdzić typ
argumentu stojącego po nim. A typ ten może być zdefiniowany kilka tysięcy
linii wczesniej, albo np. w pliku nagłówkowym... Poza tym konstrukcja ta
może prowadzić do nieporozumień (patrz przykład na końcu postu).

>   Moze Pan to wszystko wyciagnac przeciwko C. Rzecz w tym, 
> ze takie bylo zalozenie. Ritchie chcial uzyskac jezyk maly
> i zwarty i szereg spraw uzaleznil od kontekstu.

1. Udało mu się uzyskać język mały i zwarty co do kodu zródłowego, a nie
kompilatora. Ale i tak bije go na głowę kod maszynowy (pod obydwoma
względami)...

2. <P COMMENT="fikcja próbująca wyjaśnić zaistniałą sytuację">
 Richtie tego myku z "&" nie wymyslił. Pojawiło się to z początku w
niektórych implementacjach C, które były zrobione przez gości niezbyt
rozumiejących intencję autora. A potem przyszedł Standard (Panowie! czapki
z głów!), który stwierdził: "...ponieważ w wielu implementacjach języka C
taka konstrukcja jest dopuszczona, więc - żeby zachować z nimi zgodnosć
(jakże szczytny cel!) - damy taką możliwosć w standardzie..." </P>

3. Kiepskie założenie (co do "&"). Oto do czego ono prowadzi: 

#include<stdlib.h>
#include<stdio.h>
main(){	
 char *a = (char *)malloc(100);
 int b;
 scanf("%d %10s", &b, &a);
 printf("%d %s\n", &b, &a);
}

Jeśli ktoś dalej nie wie na czym ów myk polega radzę ten program
skompilować, uruchomić i sprawdzić, czy działa zgodnie z "założeniami". 

_______________________________________________________________________________
Michał Kaczmarczyk  mailto:mik@iname.com http://student.uci.agh.edu.pl/~kaczmar
Re: fscanff i sekwencja formatujaca
#702
Author: Marek Kotowski
Date: Mon, 26 Jan 1998 09:21
22 lines
1723 bytes
Qrczak wrote:
> implementacji - tylko tyle.
> 
> Przed chwil± sprawdzi³em, ¿e przy deklaracji char s[10] jest
> sizeof (s) == 10, wiêc nazwa tablicy nie jest tak do koñca wska¼nikiem
> na jej zerowy element. Trochê to siê robi niekonsekwentne, bo je¶li

To jest jeden z dwoch przypadkow, gdy nazwa tablicy nie
jest zamieniana na adres. Drugim jest wyrazenie &Tablica[0].
Nie dam glowy, ze nie ma trzeciego, ale nie przypominam
sobie. :-)
  Ze jest pewna niekonsekwencja - zgoda. Mysle, ze
pewne niekonsekwencje w C wynikaja z jego dwoistego
charakteru: z jednej strony jest to jezyk wysokiego
poziomu - z drugiej zas jezyk o pewnych cechach
asemblera (nazywa sie C czasami "lepszym asemblerem").
Tak go sobie wymyslil Ritchie. W koncu, czy trzeba
z C korzystac, skoro jest taki niekonsekwentny? :-)

  Pozdrawiam

  Marek Kotowski
Re: fscanff i sekwencja formatujaca
#703
Author: Qrczak
Date: Mon, 26 Jan 1998 11:10
17 lines
1636 bytes
On Mon, 26 Jan 1998, Marek Kotowski wrote:

> To jest jeden z dwoch przypadkow, gdy nazwa tablicy nie
> jest zamieniana na adres. Drugim jest wyrazenie &Tablica[0].
> Nie dam glowy, ze nie ma trzeciego, ale nie przypominam
> sobie. :-)

IMHO &Tablica[0] nie jest żadnym przypadkiem szczególnym:
&Tablica[0] == &(Tablica[0]) == &(*(Tablica+0)) == &*Tablica == Tablica
niezależnie od tego, czy Tablica jest tablicą, czy wskaźnikiem
(mam nadzieję, że dobrze pamiętam priorytety [] i &).

-- 
                                 QRCZAK
    __("<              Marcin Kowalczyk
    \__/              qrczak@knm.org.pl
     ^^      http://qrczak.home.ml.org/
Re: fscanff i sekwencja formatujaca
#704
Author: Marek Kotowski
Date: Mon, 26 Jan 1998 11:42
21 lines
1701 bytes
Qrczak wrote:
> 
> IMHO &Tablica[0] nie jest ¿adnym przypadkiem szczególnym:

  Moim jest.

> &Tablica[0] == &(Tablica[0]) == &(*(Tablica+0)) == &*Tablica == Tablica
> niezale¿nie od tego, czy Tablica jest tablic±, czy wska¼nikiem
> (mam nadziejê, ¿e dobrze pamiêtam priorytety [] i &).
> 

W tym przypadku proces jest nieco bardziej zlozony, niz w przypadkach,
gdzie jest sama nazwa tablicy, np. w wywolaniu funkcji. Kompilator nie
rozroznia sytuacji z indeksem 0 jako specjalnej, ale analizuje tu
sytuacje, gdzie jest w ogole jakis indeks (moze to byc przeciez
inna liczba niz 0), i dodajac go do adresu poczatku tablicy (z
ewentualnym uwzglednieniem rozmiaru obiektu) tworzy adres wynikowy.

  Pozdrawiam

  Marek Kotowski
Re: fscanff i sekwencja formatujaca
#705
Author: Qrczak
Date: Mon, 26 Jan 1998 13:46
37 lines
2646 bytes
On Mon, 26 Jan 1998, Marek Kotowski wrote:

> > IMHO &Tablica[0] nie jest żadnym przypadkiem szczególnym:
> 
>   Moim jest.

Jestem uparty :-)

> W tym przypadku proces jest nieco bardziej zlozony, niz w przypadkach,
> gdzie jest sama nazwa tablicy, np. w wywolaniu funkcji. Kompilator nie
> rozroznia sytuacji z indeksem 0 jako specjalnej, ale analizuje tu
> sytuacje, gdzie jest w ogole jakis indeks (moze to byc przeciez
> inna liczba niz 0), i dodajac go do adresu poczatku tablicy (z
> ewentualnym uwzglednieniem rozmiaru obiektu) tworzy adres wynikowy.

Zero nie ma znaczenia, z inna liczbą byłoby to samo.

&Tablica[7] == &(Tablica[7]) == &(*(Tablica+7)) = Tablica+7

A bez ostatniego "uproszczenia" (kompilator nie musi w końcu rozwiązywać
równań ani upraszczać czegoś na zewnątrz, tylko bierze po kolei
operatory, tzn. mimo że ogólnie &*(...) == (...), to nie można napisać
&(&(*(*Tablica))):

Mamy wyrażenie &(*(Tablica+7)). Tablica+7 to wskaźnik na siódmy element
tablicy. *(Tablica+7) to referencja do siódmego elementu tablicy (C tak
naprawdę ma referencje, tylko nie we wszystkich miejscach i nazywa
referencję lvalue; lewy argument operatora przypisania i=7 nie jest
wyrażeniem typu int, tylko referencją na int, czyli intem, który ma
adres). &(referencja) tworzy z powrotem wskaźnik. Tak więc zmienna
Tablica może być traktowana jako zwykły wskaźnik.

-- 
                                 QRCZAK
    __("<              Marcin Kowalczyk
    \__/              qrczak@knm.org.pl
     ^^      http://qrczak.home.ml.org/
Re: fscanff i sekwencja formatujaca
#710
Author: Radoslaw Gancarz
Date: Mon, 26 Jan 1998 18:47
55 lines
2954 bytes
Michal Kaczmarczyk <mik@iname.com> wrote:
> On Sat, 24 Jan 1998, Marek Kotowski wrote:
[ciach]
> 3. Kiepskie założenie (co do "&"). Oto do czego ono prowadzi: 

> #include<stdlib.h>
> #include<stdio.h>
> main(){
>  char *a = (char *)malloc(100);
>  int b;
>  scanf("%d %10s", &b, &a);
>  printf("%d %s\n", &b, &a);
> }

> Jeśli ktoś dalej nie wie na czym ów myk polega radzę ten program
> skompilować, uruchomić i sprawdzić, czy działa zgodnie z "założeniami". 

Oczywiscie ze chodzi zgodnie z zalozeniami (byc moze uzywam innych 
zalozen) :-)

HP-UX:
Skompilowal sie bez bledow i zrobil to co bylo w programie:
- pobral dane
- wyswietlil adres pierwszej danej (jako int) i zawartosc drugiej 

Linux 2.0.33 gcc 2.7.2:
$gcc -Wall test.c -o test
test.c:3: warning: return-type defaults to `int'
test.c: In function `main':
test.c:6: warning: char format, pointer arg (arg 3)
test.c:7: warning: int format, pointer arg (arg 2)
test.c:7: warning: char format, pointer arg (arg 3)
test.c:8: warning: control reaches end of non-void function

Jak widac kompilatorowi kod sie podoba umiarkowanie (bez -Wall nie wyswietla
tych ostrzezen).

Bylbym bardzo wdzieczny gdybys raczyl wyjasnic co tu jest nie tak ??? :->
W ten sposob mozesz co najwyzej udowodnic ze jezeli 
sizeof(int) != sizeof (char *) to printf moze nie dzialac prawidlowo
bo czyta smieci z listy argumentow (tak jest bodajze w BC) ...
Typy int i int * nie sa zgodne i jesli probujesz wypisac jeden zamiast
drugiego to efekty moga byc dziwne i/lub zaskakujace.
 
Moze linia z printf powinna wygladac:

  printf("%d %s\n",b,&a);
 
BTW. Sprobuj sobie: printf("%ld %s\n",&b,&a); albo printf("%lf %s\n",&b,&a);
     IMHO poziom poprawnosci tych konstrukcji jest zblizony.

-- 
1+-------------------------------------------------------------------------+1
2| Radoslaw Gancarz                           feanor@zeus.polsl.gliwice.pl |2
3+--------Zeby zadac pytanie, trzeba znac chociaz czesc odpowiedzi.--------+3
Re: fscanff i sekwencja formatujaca
#711
Author: Michal Kaczmarczyk
Date: Mon, 26 Jan 1998 21:29
38 lines
2420 bytes
On 26 Jan 1998, Radoslaw Gancarz wrote:

> Michal Kaczmarczyk <mik@iname.com> wrote:
> > On Sat, 24 Jan 1998, Marek Kotowski wrote:
> [ciach]
> > 3. Kiepskie założenie (co do "&"). Oto do czego ono prowadzi: 
> 
> > #include<stdlib.h>
> > #include<stdio.h>
> > main(){
> >  char *a = (char *)malloc(100);
> >  int b;
> >  scanf("%d %10s", &b, &a);
> >  printf("%d %s\n", &b, &a);

Sorry, moja pomyłka. Miało być: printf("%d %s\n", b, &a);
(swoja droga może też być nawet samo a, ale chodziło mi o wykazanie, że
"&" przed stringiem w scanf/printf jest bez sensu)

> > }
> 
> > Jeśli ktoś dalej nie wie na czym ów myk polega radzę ten program
> > skompilować, uruchomić i sprawdzić, czy działa zgodnie z "założeniami". 
> 
> Oczywiscie ze chodzi zgodnie z zalozeniami (byc moze uzywam innych 
> zalozen) :-)
> 
> HP-UX:
> Skompilowal sie bez bledow i zrobil to co bylo w programie:
> - pobral dane
> - wyswietlil adres pierwszej danej (jako int) i zawartosc drugiej 

Czy na pewno wyswietlił zawartosć drugiej? Proponuję wpisać dłuższy
string i sprawdzić, czy się pierwsza nie zmieniła (co będzie widać po
poprawce w programie).

_______________________________________________________________________________
Michał Kaczmarczyk  mailto:mik@iname.com http://student.uci.agh.edu.pl/~kaczmar
Re: fscanff i sekwencja formatujaca
#717
Author: Maciej MOCHOL
Date: Wed, 28 Jan 1998 12:20
23 lines
1327 bytes
On Fri, 23 Jan 1998, Marek Kotowski wrote:

> &nazwisko nie jest adresem &&nazwisko[0]. Gdyby tak bylo,

No wlasnie, tez to odkrylem. Bylem w szoku jak pluskwa ktorej 
szukalem trzy godziny spowodowana byla roznica pomiedzy char **a a
char *a[]...

> 
>   Pozdrawiam
> 
>   Marek Kotowski
> 
> 
pozdrawiam
c.

-------------------------------------.
Codematic                            |            
 code@beta.cku.pwr.wroc.pl           |
 mmochol@elka.pw.edu.pl              |
http://home.elka.pw.edu.pl/~mmochol  |
-------------------------------------'
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads