Avatar billede hclarsen Nybegynder
24. august 2009 - 20:38 Der er 12 kommentarer og
1 løsning

Characters og tilsvarende integer

Hej

Jeg har leget lidt med

printf("%c", 97);

Dette giver mig et 'a'. I min C-bog har jeg en oversigt, hvor der er en søjle kaldet "DEC" og en søjle med det tilsvarende character.

"DEC" løber fra 0..255, hvorfor jeg har forstået det således: En byte (forudsat denne er 8 bit) kan antage 256 mulige værdier, i.e. 0..255.

Mine spørgsmål er:


#1: Hvordan ved printf, at 97 svarer til 'a' og vice versa?
#2: Hvad kaldes tallet "97" i denne sammenhæng?
#3: Er det korrekt at sige, at byten har værdien "97"?
#4: Kaldes tegnene i søjlen for ASCII-værdier? Hvis nej, hvad kaldes de så for?

Tak på forhånd.
Avatar billede dennismp Nybegynder
24. august 2009 - 21:24 #1
#1
Fordi man har defineret en standard, hvor det er vedtaget at 97 er a. Der findes andre standarder, hvor dette ikke er tilfældet. Standarden hedder ASCII i dette tilfælde.

#2
ASCII værdien

#3
Det kan du sagents sige. I princippet kan du også bruge en integer til at gemme ascii værdier i. Men det er jo klart overkill, når vi kun bruger værdierne 0..255 :)

#4
Du har karakterne og ASCII værdien der repræsenterer dem (i denne contekst).
Avatar billede hclarsen Nybegynder
24. august 2009 - 22:05 #2
Ok, tak. Jeg stiller nogle opfølgende spørgsmål, og svarene kan du ligge i et "Svar", så du kan få point :-)


#5: Er de 256 karakterer de mulige tegn, der forefindes på en computer? I.e., samtlige tegn overhovedet er blandt de 256?

Tak, du er god.
Avatar billede hclarsen Nybegynder
24. august 2009 - 22:05 #3
Hov, jeg mente "lægge", ikke "ligge".
Avatar billede hclarsen Nybegynder
24. august 2009 - 22:23 #4
Iøvrigt:

#6: Jeg har defineret en integer i. Hvis jeg sætter i=35000, så klager min compiler ikke. Hvorfor?

Jeg bruger MS Visual C++.
Avatar billede arne_v Ekspert
25. august 2009 - 03:22 #5
ASCII har kun tegn 0-127
ISO-8859-1 og de andre har kun tegn 0-255
Unicode har ca. 100000 tegn 0-100000

ASCII, ISO-8859-1 og de andre gemmer et tegn i en enkelt byte

Unicode gemmer tegn ifoelge en encoding

den mest brugte encoding er UTF-8, med den vil et tegn blive gemt som 1-3 tegn (eller er det 1-4 ?)

den naestmeste brugte encoding er UTF-16, hvor et tegn gemmes som 2 byte (bortset fra visse special tilfaelde hvor det er 4)

i C/C++ bruger man typerne:
  char = 1 byte : ASCII, ISO-8859-1 og Unicode i UTF-8
  wchar_t = 2 byte : Unicode i UTF-16
Avatar billede hclarsen Nybegynder
25. august 2009 - 08:58 #6
Så svarene til spørgsmål 1-4 er korrekte?
Avatar billede hclarsen Nybegynder
25. august 2009 - 09:11 #7
Ok, så de 0..255 tegn er ISO-8859-1. Men hedder de tilsvarende integers stadig ASCII-værdier for alle tegnene?
Avatar billede hclarsen Nybegynder
25. august 2009 - 09:33 #8
Er en ASCII-fil en fil indeholdende de 0..127 tegn, eller må 128-255 også være med?
Avatar billede dennismp Nybegynder
25. august 2009 - 10:21 #9
Helt god er jeg ikke :) Arne har ret.

#5: Er de 256 karakterer de mulige tegn, der forefindes på en computer? I.e., samtlige tegn overhovedet er blandt de 256?

Nej, der findes langt flere. Husk på, at der findes jo mange varianter af fx e: é, è, ë, ê. Og der er jo tonsvis af tegn. Og vi har jo også kinesisk, arabisk, russisk etc.

Her kommer en lang smøre, som er hvad jeg *tror* verdenen ser ud. Så husk på din dansklære og hvad han fortalte om kildekritik :)

Dengang hvor ASCII/ISO-8859-1/osv blev brugt, var i den tid hvor computerens resourcer var noget mere begrænset end i dag. Dengang brugte man bare et tegnsæt (fx 8859-1 i danmark) og da alle gøre det, var det ikke et problem. Og ISO-8859-1 kan jo netop repræsenteres i en byte, som du selv er inde på. Nemt.

Begrænsningerne blev mere og mere tydeligt efterhånden som computerne kom i netværk, herunder især internettet. Pludselig kunne man blive præsenteret for tekster skrevet på sprog der indeholder tegn, der ikke fandtes i ISO-8859-1. (Da ISO-8859-1s "byte" var brugt op, kunne man ikke bare definere flere karakter).. Så der er mange forskellige alternativer til ISO-8859-1. Fx er russere ikke så interesseret i æøå, så de har deres egen med de tegn de bruger.

Hvis du har set en tekst/webside hvor æøå ser underligt ud, er det ofte fordi at man ikke er enig om hvilken standard der bruges. Fx, afsenderen har sendt teksten i en standard, hvor læseren tror det er en anden. I de fleste browsere kan du i "View" menuen finde en "Encoding" hvor du selv kan tvinge din browser til at bruge en bestemt encoding.

Det kunne jo så være smart, nu hvor computerens resourcer ikke er nær så begrænset som i "gamle dage", at lave en standard der indeholder "alle" (næsten alle) tegn der findes: Unicode.

Som arne er inde på, så er 1 byte ikke altid et tegn når vi snakker unicode. Da vi jo gerne vil have mange flere tegn end 256 tegn, bliver vi nød til at bruge mere end en byte pr tegn. Vi kunne jo bare sige, at nu fylder alle tegn 2 bytes (eller 3.. eller 4). Men det vil jo betyde at hvis du læser en ISO-8859-1 fil som unicode, vil alt være volapyk. Og samme tekst vil fylde dobbelt så meget.

Det ville jo være smartere at genbruge ISO-8859-1 (så har vi jo allerede en hel del af de tegn der bruges i eksisterende tekster, hvilket gør det nemmere for folk at "opgrader" til Unicode hvis der bruges UTF-8) og så udvide denne til at kunne indeholde "alt det andet". Og det gør unicode.

UTF-8, UTF-16 .. osv, er forskellige måder at repræsentere unicode karakterne.

#6: Jeg har defineret en integer i. Hvis jeg sætter i=35000, så klager min compiler ikke. Hvorfor?

Der er ikke noget underligt i at have 35000 som heltal. Så den del er gyldig.

Compileren ser argumenterne til printf() som gyldige (første argument er en string, næste en integer). Den ved ikke noget om, hvad indeholdet af string'en er, eller at typen af argumentet efter format-string, skal passe sammen med %c. Argumenterne er gyldige (set fra compileren). At det så semantisk ikke giver mening, er et andet problem. c er jo ret relativt lavniveaussprog, så det er dit ansvar at bruge printf() korrekt, så det giver mening.

Håber du kan bruge det.
Avatar billede hclarsen Nybegynder
25. august 2009 - 10:40 #10
Det hjalp meget. Det eneste jeg er i tvivl om er det sidste spørgsmål:

#7: Altså 0..127 er så ASCII-tegnene, og 128-255 er udvidelsen - samlet kaldes det for ISO-8859. For intervallet 128-255, hedder de tilsvarende integers stadig ASCII-værdier eller er det "ISO-8859"-værdier? Eller noget helt tredje?

#8: Angående det med i = 35000: Jeg tænker på, at integers løber fra -32000 til 32000 (cirka), så hvordan kan 35000 være gyldig?
Avatar billede dennismp Nybegynder
25. august 2009 - 11:02 #11
#7
Jeg tror at de fleste kalder det for ASCII tegn (selvom det er forkert). Men ellers er det vel bare (ISO-8859..)-tegn.

#8
Så vidt jeg husker, så definere C kun hvad en integer minimum skal være, ikke hvad den maks må være. Så en int kan på en platform indeholde flere værdier end en int på en anden platform.

Men en 32bit heltal kan indeholde værdier: -2.147.483.648 til 2.147.483.647.

En 16bit heltal ligger derimod i intervallet −32.768 - 32.767

I stdlib.h er der defineret typer som int16_t, int32_t, uint16_t olign. Samt INT16_MIN, INT32_MIN, INT16_MAX .. som indeholder minimum og maximum værdier du kan gemme i de forskellige typer.

Jeg vil tro at din integer er større end du tror :)
Avatar billede hclarsen Nybegynder
25. august 2009 - 11:08 #12
Aha, ok. Tak.

Jeg tænkte, at arne burde lægge et svar også. Så deler jeg pointene.
Avatar billede arne_v Ekspert
26. august 2009 - 00:21 #13
Hvis vi ser bort fra EBCDIC (gammel IBM tegnsaet til mainframe), saa bruger man samme betydning af tegn 0-127 (ASCII, ISO-8859-x, Unicode etc.).

Tegnene 128-255 findes ikke i ASCII men findes i ISO-8859-x og Unicode. Det er imidlertid vaerd at bemaerke at de har forskellig betydning i ISO-8859-1 (vesteuropaeisk) og ISO-8859-2 (oesteuropaeisk) og de andre.

ISO-8859-1 specielt i dens Windows faetter kaldet CodePage 1252 er stadig ret udbredte omend trenden absolut gaar mod Unicode med UTF-8 som encoding.

Hvis du vil se hvor stor din int er saa udskriv:

sizeof(int)

Hvis vi antager 8 bit bytes (hvilket ikke er givet i C standarden men som de facto er universel idag) og 2's complement for negative tal (ditto), saa vil range af int vaere -2^(8*n-1) ... 2^n(8*n-1)-1

Og jeg skal ikke have point her.

Dennis har svaret paa spoergsmaalene - jeg har bare suppleret.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester