C data types, tar knäcken på mig

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
ekman
Inlägg: 280
Blev medlem: 13 januari 2009, 14:04:35

C data types, tar knäcken på mig

Inlägg 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;
}
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
adent
Inlägg: 4103
Blev medlem: 27 november 2008, 22:56:23
Ort: Utanför Jönköping
Kontakt:

Re: C data types, tar knäcken på mig

Inlägg 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
Användarvisningsbild
bit96
Inlägg: 2492
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: C data types, tar knäcken på mig

Inlägg av bit96 »

Kan det ha att göra med little och big endian ?
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: C data types, tar knäcken på mig

Inlägg av sodjan »

> Men det resulterade i att jag fick ett helt annat resultat...

Och de resultaten är alltså hemliga eftersom du inte visar dom?
ekman
Inlägg: 280
Blev medlem: 13 januari 2009, 14:04:35

Re: C data types, tar knäcken på mig

Inlägg 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.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45291
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: C data types, tar knäcken på mig

Inlägg 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.
ekman
Inlägg: 280
Blev medlem: 13 januari 2009, 14:04:35

Re: C data types, tar knäcken på mig

Inlägg 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?
Användarvisningsbild
bit96
Inlägg: 2492
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: C data types, tar knäcken på mig

Inlägg 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);
Användarvisningsbild
Icecap
Inlägg: 26147
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: C data types, tar knäcken på mig

Inlägg 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.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45291
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: C data types, tar knäcken på mig

Inlägg 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.
gkar
Inlägg: 1453
Blev medlem: 31 oktober 2011, 15:28:29
Ort: Linköping

Re: C data types, tar knäcken på mig

Inlägg 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!
Användarvisningsbild
bit96
Inlägg: 2492
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: C data types, tar knäcken på mig

Inlägg 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... :humm:
Användarvisningsbild
adent
Inlägg: 4103
Blev medlem: 27 november 2008, 22:56:23
Ort: Utanför Jönköping
Kontakt:

Re: C data types, tar knäcken på mig

Inlägg 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
ekman
Inlägg: 280
Blev medlem: 13 januari 2009, 14:04:35

Re: C data types, tar knäcken på mig

Inlägg 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! :tumupp:

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 :D
ekman
Inlägg: 280
Blev medlem: 13 januari 2009, 14:04:35

Re: C data types, tar knäcken på mig

Inlägg av ekman »

@bit96

Ditt svar fungerade också! med, printf("Relative LBA address 0x%08X\n", *((unsigned long*)CharLBA));

:bravo:
Skriv svar