pitäisi kirjoittaa makro NOLLAA(taul, N), joka nollaa paranetrina saamansa taulukon, joka on kooltaan N. mutta miten? kiitos
makrolla taulukko tyhjäksi
jope
11905
0Äänestä
Muut lukivat myös
Odottaa vastausta
Näihin keskusteluihin ei ole vielä vastattu. Ole ensimmäinen.
Vastaukset 11
Vanhimmat
makro:
#define NOLLAA(taul, N) {int __i = 0; \
for (__i=0; __i < N; __i ) \
taul[__i] = 0; }
Toi merkki \ meinaa vaan että se kaikki tulee samalle riville, voit kirjoittaa ton homman pötköön yhdelle riville, mutta \ mahdollistaa selvemmän tulkinnan itselle.
Olen jättänyt sulkeet pois esim, (N) on vain N, koska virheen varaa ei tässä uskoakseni tule, kuten seuraava esimerkki valaisee.
#define fun(N) N*N
nyt jos kirjoitetaan fun(N 1) on tulos
N 1*N 1 = 2N 1, eikä mitä toivottiin eli
N^2 2N 1, mutta toivottu tulos saadaan aikaan suluilla
#define fun(N) (N)*(N)
nyt fun(N 1) antaa tulokseksi
(N 1)*(N 1) = N^2 N 1
miksi käytät tuota alaviivaa muuttujan edessä?
Ettei tule konfliktia jo kenties olemassa olevan int i, muutujan kanssa.
Jos sitä i:tä käytetään muuhun kuin taulukon läpikäymiseen, tai siis se pitää sisällää jotain muuta infoa jota tarvitaan vähän myöhemmin, niin makron muuttaisi sen arvoa, ja sitä paitsi julistaisi saman muuttujan toiseen kertaan.
eli konfliktin välttämiseksi on merkattu
__i,
tosin tietenkin voit käyttää ihan mitä tahansa tossa vaikka
int jotain;
kunhan se ei konfliktoi jo olemassa olevien muuttujien kanssa.
Tuo __i ei konfliktoi muiden kanssa, koska se on blokin (aaltosulkujen) sisällä.
Eli tavallinen i kelpaa myös :)
Lisäksi kaikki alaviivalla alkavat symbolit ovat C-standardin mukaan varattuja, joten niitä ei pidä käyttää muuttujien tms. nimenä.
Lähde tuohon väitteeseen, kiitos.
Teksti löytyy varmaankin jokaisesta C-kielen alkeita käsittelevästä kirjasta tai tekstistä, esim. täältä:
http://www.oakroadsystems.com/tech/c-predef.htm
Hmm.... "must never create (7.13/4.13) a non-static function or global variable that starts with the letters is, mem, str, to, or wcs followed by a lower-case letter".
Sivulle on viitattu mm. täällä:
http://www.lysator.liu.se/c/
Entäpäs jos makro olisi siis kirjoitettu kuten sanoit, eli näin
#define NOLLAA(taul, N) {int i = 0; \
for (i=0; i < N; i ) \
taul[i] = 0; }
Tässä tapauksessa jos kutsutkin makroa
NOLLAA(taul, i) eli sulla onkin muuttujassa i se taulun pituus, --> sinulla on ongelma.
Tehokkain tapa lienee:
#define NOLLAA(taul,N) memset((taul),0,(N))
Hmm..ei, paitsi ehkä char-taulukossa tuo voisi toimiakin. Tuon toimivuus olettaa myös sen, että taul on osoitin. memsetin kolmanneksi argumentiksi kun antaa N*sizeof(taulukon elementtien tyyppi), niin ollaan jo lähempänä.
Myös näin, kun taulun koko on kääntäjän tiedossa:
#define Nollaa(taul) memset(taul,0,sizeof(taul))
Float- ja double-tyyppisille tauluille memset-funktiota ei pidä käyttää. Se saattaa toimia tai sitten ei, koska standardi ei määrittele liukulukujen implementaatiota. Kokonaisluvuilla memset toimii käytännössä, vaikka standardi ei ota kantaa siihenkään.