kolos programowanie, I semestr, Programowanie


Więc jak obiecałem omawiam kolokwium. Zestaw 1. Łopatologicznie jak tylko miałem cierpliwość
W pierwszej kolejności patrzymy na funkcję main. Nie trzeba od razu przyglądać się deklaracjom zmiennych, więc przechodzimy do pierwszego printf-a

printf("Zestaw 1:\n%3d.%04d.%3d.\n",A(2-1,3+1,4*2)*2,2+A(3-1,4+1,1+2)/2,2*A(2+2,2-3,4-3)%2);

Analizujemy pokolei pierwszy argument, czyli to co w "". Najpierw jest zwykły tekst "Zestaw 1:", więc wypisujemy go, kratka na literę. Dalej mamy "\n" co jest znakiem przejścia do nowej lini (do początku). Potem znak specjalny % oznaczjący, że będziemy wypisywać jakąś zmienną. Po % jest 3, co oznacza, że zajmie ona PRZYNAJMNIEJ 3 znaki. Jeśli będzie to np liczba 2, która jest 1 znakiem, to z lewej pozostałe 2 znaki bedą puste, tzn spacje, czyli wypisze " 3". Następnie mamy d oznaczające typ danych jaki wypisujemy, d akurat to liczba całkowita typu int. Na typie kończy się zapis opisujący w jaki sposób zmienna ma być wypisana. Sprawdzamy więc co to za zmienna. Patrzymy na drugi argument printf-a czyli

A(2-1,3+1,4*2)*2

Analizujemy co to za wyrażenie. Ponieważ mamy jakiś symbol A i po nim bezpośrednio ( (ew moga być spacje) to mamy do czynienia z funkcją, albo taką powiedzmy pseudo-funkcją z #define. Szukamy wyżej w kodzie co to jest A. Znajdujemy

#define A(x,y,z) y*(i+(3*x+z))+1

więc ta druga opcja. Warto zapamiętać, że instrukcje preprocesora, czyli te zaczynające się od # w tym #define operują na samym tekście kodu jak edytor tekstowy, nie analizując go prawie, a kompilacja jest dopiero potem. #define robi coś takiego, że w miejsce

A(2-1,3+1,4*2)

wkleja

y*(i+(3*x+z))+1

a w miejsce x, y i z zgodnie z oznaczeniem "A(x,y,z)" wkleja kolejne wyrażenia między przecinkami, czyli za x 2-1 za y 3+1 za z 4*2. Ostatecznie więc zrobi taka podmianę:

3+1*(i+(3*2-1+4*2))+1

i że mieliśmy "A(2-1,3+1,4*2)*2", a to co wyżej zastąpiło A(2-1,3+1,4*2) to na końcu jest jeszcze *2. Ostatecznie:

3+1*(i+(3*2-1+4*2))+1*2

Takie przekształcenia trzeba robić albo w pamięci, albo zapisywać sobie w brudnopisie... Obliczamy sobie to wyrażenie, priorytety działań są tu normalne jak w matmie. "i" jest zmienną, szukamy wyżej jej wartości, w pierwszej linijce maina widzimy i=3 więc podstawiamy 3... Wychodzi 21 i to wypisujemy, pamiętając że miały być min. 3 znaki, a więc będzie " 21". Analizujemy w ten sposób dalej:

"Zestaw 1:\n%3d.%04d.%3d.\n"

Mamy kropkę, wypisujemy ją i jest następny opis zmiennej jaką printf ma wstawić - %04d - nowość w stosunku do wcześniejszego to tylko 0 oznaczające, że jeśli liczba będzie mniej niż 4 cyfrowa to wcześniej nie będzie spacji a 0, np dla 3 to będzie 0003. Znak % w ostatnim wyrażeniu to operator reszty z dzielenia, priorytet ma taki sam jak zwykłe dzielenie. 14%4 to np 2.

wsk=&arr[i/2]

Tu liczą się priorytety. Największy ma [] więc arr[i/2] (i/2 to 3/2, dzielimy liczby całkowite więc w wyniku też będziemy mieli całkowitą, zaokręglenie jest w dół, otrzymujemy 1) jest odwołaniem do drugiego (bo indexy tablic liczymy od 0) elementu tablicy arr zadeklarowanej wcześniej. & powoduje pobranie adresu pamięci, gdzie jest przechowywana ta zmienna (ten 2 el. tablicy). Czyli mamy wskaźnik. I na końcu ten wskaźnik, adres pamięci, przypisujemy do zmiennej wsk. Zadeklarowana jest wyżej jako float *wsk, czyli właśnie wskaźnik do zmiennej typu float (liczby rzeczywistej). Warto sobie gdzieś na boku zapisać co zawiera wsk, czyli na co wskazuje.

Potem kolejny printf:

printf("%9s:%4.1f,%-12.3e\n","ptr=arr",*wsk+j,*(wsk+j));

9 oznacza jak wcześniej, że co najmniej 9 znaków, a jak nie to uzupełnienie spacjami z lewej, %s oznacza, że będziemy wstawiać zmienną tekstową(tablicę znaków). Ten tekst to "ptr=arr", wypisujemy, oczywiście bez "", pamiętając że miało być min 9 znaków, a to co dane to 7, więc z początku będą 2 spacje. : jest normalnym znakiem, wypisujemy. %4.1f oznacza - co najmniej 4 znaki, inaczej spacje, .1 oznacza, że wypisuje zawsze 1 cyfrę po przecinku(dokładniej kropce), f określa typ jako liczbę rzeczywistą. Patrzy co mamy dane jako tą zmienną: jest "*wsk+j". * ma wyższy priorytet od +. Ze wskaźnika robi nam zmienną na którą było wskazanie, więc mamy jak pamiętamy 2 el. tablicy arr równy 6.14542678. Dodajemy do niego wartość j równą 4 i jest 10.14542678 wypisujemy to zgodnie z założeniami i mamy "10.1". Następnie przecinek przepisujemy. Dalej mamy symbole formatowania %-12.3e . - oznacza, że jeśli będzie mniej znaków niż tych 12 to uzupełniające spacje (ew 0 gdyby było 0 po - i przed 12) będą nie po lewo, a po prawo reszty. e oznacza liczbę rzeczywistą w notacji wykładniczej w zapisie 0.0000e+000 , gdzie przed kropką jest zawsze 1 cyfra, po - co najmniej 1, max tyle ile w formatowaniu określa prezycja, czyli u nas to .3 oznacza, że będą 3 cyfry po kropce (jeślo nie ma wcale tego .precyzja to domyślna precyzja jest 6 liczb po kropce, dla %f również). Zamiast + może być - zależnie od znaku wykładnika, a na wykładnik są zawsze(w naszych zastosowaniach) 3 cyfry. A jako ta liczba rzeczywista w notacji wykładniczej ma być zmienna dana jako *(wsk+j) . Ponieważ mamy nawiasy to najpierw dodajemy. Kiedy dodajemy do wskaźnika, to do adresu pamięci dodajemy wartość razy liczba bajtów jaką ma rozmiar zmiennej, jakiej typu jest wskaźnik. A prościej to przesuwamy wskaźnik o j elementów w tablicy na którą wskazywał. * ze wskaźnika rwyciąga nam ten element. Jako że j jest 4, a byliśmy już na 2 el. tablicy to mamy 6 el. równy 2879.4 . Zgodnie z wszystkimi ustaleniami będzie zapisany jako "2.879e+003 "

Polecam poczytać dokumentację, o tym jak zapisuje się formatowanie zmiennych w printf-ie
http://msdn.microsoft.com/en-us/library/56e442dc(VS.80).aspx

Wymagania są pojeb***, ale co zrobić, zaliczyć jakoś trzeba, a z 2 kolosów wystarczy zdobyć 15 na 50pkt więc może warto się chociaż trochę przygotować i cokolwiek sensownego napisać...

Omawiam dalej kolosa, mam nadzieję, że się przyda!


Jesteśmy w linii:

fun1(tab);


Jak widać jest to wywołanie funkcji fun1 o argumencie tab. Na początku maina w linii

char c; int high, i=3, j=4, in, low, tab[]={2,3,1,4,6};


jest definicja. Czyli mamy tablicę elementów typu int(liczb całkowitych). Jeśli jest
samo [] bez numeru elementów w środku to liczba elementów jest automatycznie ustalana na
podstawie podanych danych inicjujących - mamy tam 5 liczb, rozmiar tablicy=5. Samo tab, jak podane w argumencie fun1, jest wskaźnikiem do pierwszego elementu tablicy. I rzeczywiście jak można sprawdzić w
deklaracji zapowiadającej nad mainem

void fun1(int*);


albo w samej definicji niżej

void fun1(int *tab)


jako argument jest potrzebny wskaźnik na typ int. Dobra, przechodzimy do wnętrza tej funkcji.
Wewnątrz niej argument funkcji, czyli int *tab jest już jak zwykła zmienna lokalna, zupełnie
niezależna od tej w mainie (w fun1 nie "widać" zmiennych lokalnych maina i na odwrót). Ta
zmienna będąca argumentem ma jednak początkową wartość taką, jaką podaliśmy wywołując
funkcję, czyli jest wskaźnikiem na 1 element tab main-ie. I ważne, że to na co wskazuje tab w
fun1 możemy sobie dowolnie zmieniać i to nie będzie wpływać na tablicę w mainie, ALE jeśli
wskazuje na tamtą tablicę i będziemy modyfikowali dane pod tym adresem pamięci (poprzez *
czyli odwołanie do danych na które pokazuje wskaźnik) to możemy zmienić zawartość tablicy w
main().
Analizujemy kod fun1. Najpierw są deklaracje zmiennych, będą potrzebne dopiero później. Mamy wyrażenie:

i=(j=++tab[1])-1;


Zgodnie z priorytetami operatorów najpierw będzie obliczone tab[1]. Jest to odwołanie do
adresu pamięci który wskazuje wskaźnik tab plus 1 element typu int (bo typ tab to int*), czyli +4bajty. ALE to nas mało interesuje, bo wiemy że to wskaźnik na tablicę z maina, czyli to jest odwołanie do 2 el. tej tablicy (bo tablice indeksowane od 0...). Czyli mamy zmienną typu int - liczbę o wartości 3. Następnie pierwszeństwo ma ++ (w wersji preinkrementacji, bo przed wyrażeniem), które dodaje 1 do zmiennej (czyli już ten 2 el. tablicy tab w mainie ma wartość nie 3, a 4). To 4 przypisywane jest zmiennej lokalnej fun1 - j (ale nie tej wewnątrz maina! To inne zmienne choć sie tak samo nazywają, mają inne zakresy). Całe wyrażenie:

(j=++tab[1])


ma więc wartość 4. Następnie wyższy priorytet od = ma - ,więc od tej wartości 4 odejmujemy 1,
mamy 3 i przypisujemy to zmiennej i (znowu lokalnej fun1).

Dalej...

++tab[--j];


Najwyższy priorytet ma tu operator []. Ale że --j jest jego niejakim argumentem, to musi to
być najpierw obliczone. --j odejmuje od zmiennej j 1 czyli ma ona teraz wartość 3 (warto
sobie zapisywać, bo można się pogubić w tych wartościach...). Ponieważ -- jest w wersji
predekrementacyjnej (przed wyrażeniem) to wartość używana w reszcie obliczeń, czyli tu dla
[], jest już tą zmniejszoną. W wersji postdekrementacyjnej (to samo dla inkrementacji)
wartość używana do obliczeń nie jest jeszcze zmieniona, dopiero potem do zmiennej jest
dodawane/odejmowane 1.
Czyli w tym przypadku mamy tab[3] co sprawia, że w to miejsce wskakuje 4 element tablicy. Na
koniec wykonuje się ++, które zwiększa ten element o 1 (działamy przez wskaźniki więc ta
wartość będzie zmieniona "zdalnie" w tablicy wewnątrz maina).

Kolejna linia

tab[i++-1]=--j;


I tu znowu priorytety operatorów i działanie post/pre inkrementacji/dekrementacji, o czym już
pisałem. j jest zmniejszane o 1, ma wartość już 2. Przypisywane jest to elementowi tablicy,
jaki określa [i++-1] . W tym wyrażeniu, z uwagi na wersję postikrementacji, używana jest
jeszcze niezwiększona wartość i, czyli jest [3-1] ,zatem 3 element tablicy, jemu przypisujemy
to 2 jak ustaliliśmy. Po tym dopiero i ma zwiększaną wartość, od teraz równą 4.

printf(ciag,i+++1,j++,*(tab+1),*tab,--tab[2]);


w miejsce "ciag" wskakuje tekst jaki jest mu przypisany, czyli jakby

printf("Fun1:%-4d,%2d,%-3d.%05d:%-3d",i+++1,j++,*(tab+1),*tab,--tab[2]);


Tu zdaje się już nic nowego nie ma, wszystko omawiałem. Trzeba uważać na to formatowanie
danych i priorytety (w kolejności [] * ++/-- + a najważniejsze to nawiasy). "i+++1" to mniej
czytelne i++ + 1.

Kończy się funkcja, wracamy do maina i jesteśmy w linijce

fun2(wsk-1);


Działania fun1 zmieniły tablicę tab w mainie tak, że ma ona teraz wartości 2,4,1,5,6. Reszta
zmiennych w mainie ma takie wartości jak przed wejściem do fun1, a zmienne lokalne z fun1
przepadają.
Wywołujemy fun2, potrzebuje ona wskaźnika na float i to jej dajemy przez wsk-1. wsk wskazywał na 2 element tablicy arr. Odejmując od wskaźnika 1 powodujemy że będzie to wskazanie na element 1. (wartość zmiennej wsk maina oczywiście nie jest zmieniana, natomiast ta pomniejszona jest przypisywana argumentowi fun2, czyli zmiennej lokalnej float *wsk w fun2).
Wewnątrz fun2:

printf("\nFun2:\n");


To chyba banał...

for(j=1,i=5-j;j<4;j++,ciag[4]++)


j=1,i=5-j


To jest wykonywane tylko raz, na samym początku. Przecinek oddziela operacje, wykonywane są
one od lewej do prawej. Czyli najpierw przypisujemy j 1, potem i przypisujemy 5-j czyli 5-1
czyli 4.
Dalej w środku między ;; jest zawsze warunek kontynuowania pętli, u nas j<4 czyli będzie
wykonywany przebieg jeśli j będzie mniejsze niż 4. Warunek jest sprawdzany na początku
każdego przebiegu(ale już po tamtych przypisaniach co wyżej), więc pętla może sie nie wykonać
ani razu. Na koniec

j++,ciag[4]++


To operacje wykonywane po każdym przebiegu pętli. A ciałem pętli, czyli tym co się wykonuje w
każdym przebiegu jest

printf("%-9s%1u%1s;%3.0f,%.3e\n",ciag,--i+2,"]",*(wsk+1)*j,*wsk+j);


Tu nic nowego, może tylko typ "u" - jest to liczba całkowita bez znaku, czyli nieujemna. To lecimy po tej pętli... Najpierw j było 1, 1<4 więc wykonuje się pierwszy przebieg, wypisujemy co tam printf wyprodukuje. Wykonujemy "j++,ciag[4]++". j ma od teraz 2, ciag[4]++ dodaje 1 do 5 elementu tablicy ciąg. Ponieważ jest to znak, a znak wewnętrznie jest właściwie odpowiadającą mu liczbą, to zwiększamy tę liczbę o 1, a tym samym literę na następną w alfabecie (dokładnie na znak kolejny w tablicy ASCII). I następne okrążenie pętli... 2<4 więc się wykona. W następnym 3<4 wiec znowu się wykona. Aż w końcu 4<4 nie jest prawdą, pętla sie już nie wykona, przechodzimy za nią, a że to już koniec funkcji to wracamy do maina.

high=i=in=low=0;


operator przypisania jest łączny prawostronnie, co oznacza, że kolejność działań będzie taka
jak gdyby zapisać:

high=(i=(in=(low=0)));

A więc wszystkie 4 zmienne uzyskają wartość 0.

while((c=NEXT(i))!=EOS) if(c<'0')low++; else if(c>'9')high++; else ++in;


while jest pętlą, która sprawdza warunek wykonania na początku, więc może nie byc ani jednego przebiegu. Warunek to:

(c=NEXT(i))!=EOS


NEXT oraz EOS to konstrukcje preprocesora, a wiec w tekście po prostu podstawiamy sobie to, co oznaczają. Mamy:

(c=wejscie[i++])!='\0'


Najpierw jest robione to co w nawiasie, c przypisywany jest [i] el. tablicy wejscie czyli
i+1wszy, ale dlatego, że indeksujemy od 0 nie za sprawą ++. Dopiero potem i jest zwiększane o 1
przez ++. Mamy != - operator porównania, który zwraca prawdę (liczbę 1) jeśli po obu stronach
ma różne wartości. Inaczej zwraca fałsz(liczbę 0). Z lewej strony mamy to co c (ale już nie
to co wejscie[i++], bo i ma już zwiększoną wartość) a z prawej '\0' . ' ' tak technicznie
rzecz biorąc zamieniają podany znak w nich zawarty na odpowiadającą mu liczbę. \0 to znak
specjalny, któremu odpowiada właśnie liczba 0. Więc po prawej != mamy 0.
Jeśli cały ten złożony warunek będzie prawdą, to wykonywane jest ciało pętli czyli

if(c<'0')low++; else if(c>'9')high++; else ++in;


If-y sprawdzają warunki w nawiasach np. c<'0' to porównanie niby znaków, technicznie cyfr im
odpowiadających wg ASCII, a praktycznie wg kolejności w alfabecie (z tym że duże litery są
niżej od wszystkich małych, polskie litery gdzieś zupełnie dalej, nie mówiąc o innych
znakach (te standardowe np */- są zazwyczaj przed wszystkimi literami i cyframi), a cyfry są kolejno
od 0, ale niżej od wszystkich liter). Jeśli warunek jest prawdziwy wykonuje się to co za if-em pierwszym
i znowu wykonywane są operacje na warunku while, sprawdzana wartość logiczna... Jeśli warunek
ifa nie jest prawdą to przechodzi do else. Że w else jest znowu if to sprawdza jego wartość i
znowu wykonuje, albo idzie do ostatniego else. W ostatnim else nie ma już if-a, jeśli do tego momentu dojdzie to zawsze wykona się to ++in. I wtedy przechodzi do warunku while. Kiedy już warunek while nie będzie prawdą to kończy się pętla i przechodzi do kolejnej linijki.
Ale jak spojrzeć na warunek while, że z zerem jest porównywany element tablicy wejscie, a
jest ona długa i tych przebiegów będzie za dużo żeby pokolei je sprawdzać (bo w tej tablicy znak
0 jest po ostatniej kropce. Automatycznie jest dodawany przy inicjacji tablicy znaków jako
znak końca tekstu). Trzeba pomyśleć ogólnie co właściwie robi ta pętla - sprawdza każdy znak z "Grupy M4 - M6 pisza kolokwium 1 z PRM w dniu 12/04/2007." , do zmiennej low zlicza te niżej zera (to będą
spacje - / oraz .) do high wyżej od 9 czyli wszystkie litery, a do in pozostałe, czyli cyfry.

PRINT3(-2d,low,in,high);

To zagnieżdżany preprocesor. Przekształcenia będą takie:

PR(-2d,low), PRINT2(-2d,in,high);

potem:

printf(" "#val"=%"#format",",(low)), PR(-2d,in), PRINT1(-2d,high);

# to tak zwany operator łańcuchujący. Otacza on w "" to co za nim stoi, ale najpierw jeśli
trzeba tamten symbol podmienia. U nas val odpowiada low, a format to -2d. Będzie więc

printf(" ""low""=%""-2d"",",(low)), PR(-2d,in), PRINT1(-2d,high);

Podwójne " się niejako redukują, więc jest

printf(" low=%-2d,",(low)), PR(-2d,in), PRINT1(-2d,high);


i podstawiamy dalej

printf(" low=%-2d,",(low)), printf(" in=%-2d,",(in)), PR(-2d,high), NL;

printf(" low=%-2d,",(low)), printf(" in=%-2d,",(in)), printf(" high=%-2d,",(high)), printf("\n");


uff i na tym koniec przekształceń preprocesora. printf-y oddzielane przecinkami wykonują się pokolei od lewej do prawej, chyba nie ma tu niczego nadzwyczajnego.

i=low=in=high=0; j=FALSE;


Nic nowego, preprocesor i o przypisaniu to co było

while((c=NEXT(i))!=EOS && !j) if(c<'Z')low++; else if(c>'A')high++; else in++;


pętla bardzo podobna do poprzedniej. && ma tu ze wszystkiego najmniejszy priorytet. To koniunkcja. Operuje na wartościach logicznych (w praktyce na liczbach, 0 to fałsz, każda inna to prawda) i zwraca 1 dla prawdy 0 dla fałszu. Jak wiadomo prawda będzie tylko jak oba zdania koniunkcji będą prawdą. ! jest negacja logiczną, traktuje wartość j jako logiczną i zwraca 1 albo 0. Obliczane są wartości logiczne po obu stronach &&. po lewej tak samo jak we wcześniejszej pętli. !j jest zawsze prawdą, bo j jest zawsze 0, nie zmienia się w pętli.
Negacja 0 czyli logicznego fałszu to logiczna prawda czyli 1. Ostatecznie warunek pętli jest taki sam jak wcześniejszej bo liczy się tylko to co z lewej &&. Zliczamy do low znaki niealfanumeryczne, cyfry i duże litery oprócz Z. Do high duże litery oprócz A (ale tylko te niezliczane przez low, czyli w rezultacie Z-y) oraz małe litery. Do in reszta - czyli nic.

if(low>=EN || high>+EN || in>=EN) j=TRUE;


To połączenie tego o czym już mówiłem. Preprocesor, operatory i ich priorytety. || to logiczna alternatywa, najniższy tu priorytet oprócz przypisania, >= to porównanie, prawda zwracana jeśli to co z lewej jest większe lub równe temu z prawej, chyba logiczne nie jest operatorem, jest nim samo > , a + jest operatorem znaku, który stoi przed liczbą i robi on NIC. Jak w matmie możemy + przed liczbą napisać, nawet ujemną (+-liczba=-liczba) albo nie i nic to nie zmienia. Ale ogólnie warto zauważyć, że tą linię równie dobrze możemy wyrzucić, bo jedyną zmiane, jaką może wprowadzic to zmienić wartość j. A kawałek dalej mamy zawsze j=FALSE; Po drodze wartość j nie jest nigdzie używana.

Potem:

PRINT3(-3d,low,in,high);

i=low=in=high=0; j=FALSE;


analogicznie jak wcześniej

while((c=NEXT(i))!=EOS && !j)


warunek ten sam, ale tu j już będzie sie zmieniało w pętli i ma znaczenie.

if(c<'a') j=(++low==EN); else if(c>'z') j=(high++==EN); else j=(++in==EN);


Nowość to konstrukcje typu "j=(++low==EN)", "j=(high++==EN)" i "j=(++in==EN)". zmiennej j jest przypisywana wartość obliczona w nawiasie. A np. dla tego drugiego == porównuje high z EN(podstawione przez preprocesor, to jest 3). Zwraca 1 jeśli jest równe, 0 jeśli nie. po tym dopiero zwiększa high o 1. j jest przypisywana wartość logiczna, zawsze to będzie 0 lub 1.
Jak się chwilę zastanowić, to pętla jest przerywana albo jak sie skończy tekst, albo kiedy j będzie równe 1 (a to nastąpi u nas szybciej). j będzie równe 1 po tym gdy low osiągnie 3, czyli zliczone zostaną w sumie 3 litery duże\cyfry\znaki niealfanumeryczne, albo gdy high porównywane będzie równe 3, a będzie to w momencie zliczania już 4 znaku high(za sprawą postinkrementacji), czyli 4 znaku większego od 'z' - takich w ogóle tam nie mamy, lub gdy in osiągnie wartość 3, czyli przy zliczaniu 3 litery małej. Jak spojrzymy na tekst to widać że pierwszy będzie warunek z in. Zliczone będą tylko znaki "Grup" więc high osiągnie 0, low 1, a in właśnie 3.

PRINT3(-4d,low,in,high);

Zakładając dla pierwszego wiersza po fun2
że c na wejściu jest 1 elementem tablicy wejscie[] czyli w tym przypadku bedzie to litera G
to patrzymy jaki jest pierwszy warunek if(c<'0')low++ else if(c>'9')high++ else ++in
otwieramy teraz tablicę ASCII która mam nadzieje bedzie na wykładzie
http://www.programuj.com/ascii.php
i teraz cały trick polegający na tym że liczymy ile mamy znaków które leżą powyżej 0 w tym przypadku będą to od nr 0 - 47 w tablicy
przelatujemy przez tekst zliczamy wszystkie i to jest nasze low
następnie liczymy ile mamy znaków które leżą powyżej 9 czyli od 58-127 w ASCII
i to jest nasze high
reszta czyli nasze in to będą wszystkie cyferki występujące w tym tekscie
mamy low in high
teraz na chybił trafił wypisujemy te spacje przecinki (bo nie mamy czasu na dalszą analizę) załóżmy
" low=15, in=11, high=30,"

Następny wiersz lecimy analogicznie (przynajmniej tak mi sie wydaje 0x01 graphic
)
if(c<'Z')low++ else if(c>'A')high++ else in++
W tablicach ASCII nad Z leżą duże litery cyfry znaki niealfanumeryczne
zliczamy je z tekstu to jest nasze low
high to bedą wszystkie ktore leża pod A
in to w tym przypadku bedize 0 bo te dwa poprzednie przedzialy sie pokryja
i analogicznie
" low=32 , in=0 , high=24 ,"

Dlaczego spacja przed każdym bo w każdym printfie jest(" low.....") a dlaczego spacje na końcu? ponieważ w pierwszym wierszu jst -2d czyli conajmniej dwa znaki i dopisujemy spacje na prawo
w drugim wierszu natomiast jest już -3d i dlatego przecinek przesuwa nam sie w prawo bowiem jest to ta dodatkowa spacja

Trzeci wiersz to już calkowity spontan
Poprostu patrze na warunek dla c
I zlizcam wszystko z pierwszego wyrazu razem ze spacją czyli "Grupy " i porównuje to z wartością EN
1 dla prawdy 0 dla fałszu i chyba tyle
i tak wypisuje nie zapominając o brakujących spacjach w tym przypadku -4d

Nie mam zielonego pojecia czy ktoś to zrozumiał.
Ale życzę samych maxów

EDIT
Co do tego wypisywania juz na czysto
to mniej wiecej printf ma taka postac
printf(" #val=%#format", (val))
czyli w naszym przypadku val może byc low , in , high
a formatem jest pierwsza "współrzędna" z tego PRINT3(-2d,low,in,high) czyli -2d
po podstawieniu drukuje nam
printf(" low=%-2d, in=%-2d, high=%-2d) w miejsce %-2d wstawiamy to co policzyliśmy na szybko

tak samo dla następnych wierszy z tą różnicą że zmienia sie tylko %-2d na %-3d
a w ostatnim dochodzi porównanie tego co policzmy z wartością EN = 3 w tym przypadku

EDIT2
Nawet jeśli nie wiecie jak wypełnić 3 wiersz wystarczy że wpiszecie (chyba):
" low=0 , in=0 , high=0 ,"
Traficie 1/3 jak nie 2/3

if(low>=EN || high>EN || in>=EN) j=TRUE;
Ten cały warunek to zmyła. Równie dobrze można tą linię wyrzucić, bo kawałek dalej jest

j=FALSE;

a nigdzie po drodze wartość j nie jest używana.

Strona nr 8



Wyszukiwarka

Podobne podstrony:
Moja ściąga 2. kolos, Szkoła, Semestr 4, Podstawy automatyki
kolos 1. powtórzenie, Semestr 1, zoologia, materiały
kolos tworzywa, Semestr I, Materiałoznastwo, Sprawozdania, Cw.2(Tworzywa
En Prawa kolos, WSEI, semestr 1, Encyklopedia prawa
OU Access 2 kolos, WIT, Semestr II, OU 2
odp na pytania kolos eko, Semestr I
kolos II, Semestr III, Petrografia, Skały osadowe opracowania do kolokwium teoretycznego, petro kolo
sciaga 1 kolos, gik, semestr 4, satelitarna, Satka, Satelitarna
kolos I, Ogrodnictwo, Semestr III, Entomologia, Entomologia
łożyska sliz kolos, AGH, Semestr V, PKM [Łukasik], chomik all in one
3 kolos, AGH, Semestr II, Podstawy Nauk o materiałach[Kot,Dymek,Rakowski], PNOM, egzamin i inne
Analiza instrumentalna kolos II semestr
Sciaga Kolos I, gik, semestr 4, Wyższa, kolo1
3 kolos, Studia, semestr 4, Maszyny elektryczne, Maszyny elektryczne I
zagadnienia na kolos, STUDIA, SEMESTR IV, Badania struktury i własnosci materiałów, bsiwm
Kolos 1, ZiIP, semestr 1, materiałoznawstwo

więcej podobnych podstron