Sida 1 av 5
C data types, tar knäcken på mig
Postat: 16 december 2013, 21:01:30
av ekman
Jag följer en tutorial som handlar om FAT-filsystem. Och där tillhandahåller han som skrivit en image fil gjort från ett SD kort med några filer i. Test.img.
I hans exempel (som fungerar när jag compilerar) så har han deklarerat följande i en struct:
unsigned long start_sector;
När jag våghalsigt nog försökte skriva en egen, så tänkte jag "det borde ju lika gärna gå att använda Char och bestämma storleken själv?", så här:
unsigned char start_sector[4];
Men det resulterade i att jag fick ett helt annat resultat, trots att dom båda borde ta upp samma mängd bytes, 4?
när jag skriver ut sizeof av char variabeln, och long variabeln, så är dom lika stor, 4 bytes. Varför blir det fel?
Jag har skrivit ett litet program som öppnar image filen i binary, och försöker läsa in 4 bytes från en adress. Först en till Char variabel, sen en till Long variabel bara för att testa. Här är koden och filen och Tutorialen jag läser:
http://codeandlife.com/2012/04/02/simpl ... mment-8343
Kod: Markera allt
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE * in = fopen("test.img", "rb");
unsigned int i; //commenting this out and the program will crash when using CharLBA? wtf?
unsigned char CharLBA[4];
fseek(in, 0x1C6, SEEK_SET); // go to partition table LBA start adress
fread(CharLBA, 8, 1, in);
printf("Relative LBA address 0x%08X\n", CharLBA);
unsigned long LongLBA = 0;
fseek(in, 0x1C6, SEEK_SET); // go to partition table LBA start adress
fread(&LongLBA, 8, 1, in);
printf("Relative LBA address 0x%08X\n", LongLBA);
printf("%d\n", sizeof(CharLBA));
printf("%d\n", sizeof(LongLBA));
fclose(in);
return 0;
}
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:11:08
av adent
Nu är jag inte helt hundra, men siffran 8 i fread() antyder väl att du läser ett 64-bitars-tal, d.v.s. 8 bytes?
MVH: Mikael
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:14:40
av bit96
Kan det ha att göra med little och big endian ?
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:20:25
av sodjan
> Men det resulterade i att jag fick ett helt annat resultat...
Och de resultaten är alltså hemliga eftersom du inte visar dom?
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:25:10
av ekman
@adent
Ja det har du rätt.. Har testat med en 4 där, samma fel
@bit96
när jag tittar på filen i en HEX editor (HxD), så ligger bom bytes jag ska läsa av så här: 81 00 00 00
Svaret som sparas i variablerna ser ut så här:
Char variabeln: 0018FF54
Long variabeln: 00000081
0018FF54 är inte ens i närheten, och jag hittar dom inte ens i filen
vet inte vart dom kommer ifrån.
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:25:33
av TomasL
Det är nog snarare så att funktionen som använder "start_sector" förväntar sig en long, men eftersom du skickar en char till den, så funkar det inte.
Kan inte se någonstans i din inklippta kod var "start_sector" används.
Och nej en char[4] är inte samma sak som en long, dessutom beror längden på long på systemet du använder.
Definitionen på long är
A long integer can represent a whole integer number whose range is greater than or equal to that of a standard integer on the same machine.
A long integer commonly requires double the storage capacity of a standard integer, although this is not always the case.
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:38:15
av ekman
@TomasL
Koden jag klistrade in är ett test program jag skrev för att bara koncentrera mig på varför jag inte får samma svar.
Det är väl det jag inte förstår riktigt, varför Char[4] inte är samma sak som en long?
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:44:39
av bit96
Vad händer om du talar om för printf() att det är en 'unsigned long' du vill skriva ut?
Kod: Markera allt
printf("Relative LBA address 0x%08X\n", (unsigned long)CharLBA);
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:46:53
av Icecap
Varför inte göra en union?
Kod: Markera allt
union
{
unsigned long Long;
unsigned char Char[4];
} Start_Sector;
Då har du tillgång till båda delar.
Start_Sector.Long som unsigned long och
Start_Sector.Char[] som byte.
Att en unsigned long (ofta 32 bit) inte är lika med en unsigned char (8 bit) är väl ganska logisk eller hur?
Du glömmer kanske att kompilern inte fattar att du tänker använda din unsigned char som en unsigned long, du måste alltså cast'a den om du inte använder en union.
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:47:30
av TomasL
Därför att en char är 8 bitar, inget annat, det du angivit med char[4] är en array av char's dvs 4 stycken char, dvs 4 stycke 8-bitars variabler istället för en long.
Möjligtvis om du gör typedefar en egen typ, bestående av en union av en long och en char[4] kan du få det att fungera.
Icecap var samtidig, uppenbarligen.
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:51:19
av gkar
För att göra en enkel sak lite mer komlicerad.
De olika datatyperna i C varierar kraftigt mellan olika arktekturer. En char kan vara 8 eller 16 bitar, eller där imellan.
En long är längre än en int, och en int kan vara 16 eller någoting annat, vilket gör att en long kan vara 17bitar även om jag akdrig sett en sådan long.
Sedan spelar endian roll, big eller litle endian. Det finns andra obskyra endians också.
Vill du hårddra det kräver C inte heller att duräknar binärt, hårdvaran tillåts räkna i graycode.
Eftersom du inte skriver vilken maskin du kompilerar för antar vi Amiga och 68000.
En datatyp läggs normalt på en adress med natural alignment. Dvs en byte kan ligga på adress 0,1,2 eller 3 men en int32_t måste ligga på 0 eller 4. Eller i 68000 fall, även 2 och 6, eftersom den externt är 16 bitar. På 020 och uppåt får du dock straff eftersom du nu kräver dubbla bussaccesser)
Mer glögg!
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:52:23
av bit96
bit96 skrev:Vad händer om du talar om för printf() att det är en 'unsigned long' du vill skriva ut?
Kod: Markera allt
printf("Relative LBA address 0x%08X\n", (unsigned long)CharLBA);
Det gick nog för fort.
Om det skall vara meningsfullt måste du skriva:
Kod: Markera allt
printf("Relative LBA address 0x%08X\n", *((unsigned long*)CharLBA));
[/quote]
Tror jag, det börjar bli sent...

Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 21:55:00
av adent
AHA, rimligtvis skriver den här raden:
printf("Relative LBA address 0x%08X\n", CharLBA);
Ut adressen till CharLBA, inte innehållet
EDIT: Denna funkar:
printf("Relative LBA address 0x%08X\n", *(long *)&CharLBA[0])
Arrayer är mycket nära besläktade med pekare i C.
MVH: Mikael
Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 22:09:21
av ekman
@bit96
Testade, samma svar
@Icecap
Det är därför jag declarerar char[4], så att den ska kunna hålla 4 bytes, lika många som en long kan hålla.
@TomasL
Ja, precis. Men i Tutorial jag läser. Så har han använt sig av till ex. char[3], och lyckats lagra 3 bytes i den ändå
@gkar
Aa precis.. men med sizeof så skrev den ut att char och long variabeln var lika stora. Så borde lagrat lika stor mängd, och inte få så 'konstigt' svar.
@adent !!
TACK SÅ MYCKET!
Jag kan uppenbarligen inte så mycket inom C, men med ett * framför variabeln så hämtar den värdet, och inte adress (om jag inte har helt fel)
Så med detta fick jag rätt svar, printf("Relative LBA address 0x%08X\n", *CharLBA);
Vad sjuk glad jag blev. Hoppas det stämmer med *, och rätta mig om jag har fel.
Och tack alla som svarat

Re: C data types, tar knäcken på mig
Postat: 16 december 2013, 22:11:44
av ekman
@bit96
Ditt svar fungerade också! med, printf("Relative LBA address 0x%08X\n", *((unsigned long*)CharLBA));
