"We are back" « oc.at

[c] Speicherort Variable-Name

lama007 01.03.2009 - 20:29 1437 13
Posts

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Hi, kann mir jemand kurz erklären, wo und wie die Namen von Variablen gespeichert werden?

Code:
#include <stdio.h> 
#include <stdlib.h>   

int main( void ) { 	
  char letter = 'a'; 	
  int dez = (int) letter; 	
  int i; 	
  int bit[8]; 	 	

  for ( i = 7; i >= 0; i-- ) { 		
    bit[i] = dez % 2; 		
    dez /= 2; 	
  } 	 	

  printf( "\n\"a\" wurde als " ); 	
  for ( i = 0; i < 8; i++ ) { 		
    printf( "%d", bit[i] ); 	
  } 	
  printf( " im Byte mit der Adresse %p gespeichert.\n", &letter ); 	
  printf( "Wo wird der Name der Variable \"letter\" gespeichert?\n\n" );  	

  return 0; 
}

COLOSSUS

Administrator
GNUltra
Avatar
Registered: Dec 2000
Location: ~
Posts: 12213
Nirgendwo (zumindest so lange man nicht mit Debug-Flags kompiliert). Variablennamen werden in Speicheradressen uebersetzt.

Burschi1620

24/7 Santa Claus
Avatar
Registered: Apr 2004
Location: Drüber da Donau
Posts: 6792
Fragä: Warum convertierst du den letter in int um bevor du ihn in dez speicherst? Meines Wissens nach werden chars ohnehin als int gespeichert.

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Ok, hier kürzer und sparsamer:

Code:
#include <stdio.h> 
#include <stdlib.h>   

int main( void ) { 	
  char letter = 'a'; 	
  char dez = letter; 	
  short i; 	
  char bit[8]; 	 	

  for ( i = 7; i >= 0; i-- ) { 		
    bit[i] = dez % 2; 		
    dez /= 2; 	
  } 	 	

  printf( "\n\"a\" wurde als " ); 	
  for ( i = 0; i < 8; i++ ) { 		
    printf( "%d", bit[i] ); 	
  } 	
  printf( " im Byte mit der Adresse %p gespeichert.\n", &letter ); 	
  printf( "Wo wird der Name der Variable \"letter\" gespeichert?\n\n" );  	

 return 0; 
}

Datentypen braucht es nur für die Speicherreservierung?

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11346
Zitat von lama007
Datentypen braucht es nur für die Speicherreservierung?

Einerseits für die Speicherreservierung, andererseits muss der Compiler den zu den Datentypen passenden Code erzeugen - es ist ein ja Unterschied, ob du zwei ints oder zwei chars addierst.

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Noch sparsamer:

Code:
#include <stdio.h> 
#include <stdlib.h>   

int main( void ) { 	
  char letter = 'a'; 	
  char dez = letter; 	
  struct bb {    		
    unsigned bit_0:1;    		
    unsigned bit_1:1;    		
    unsigned bit_2:1;    		
    unsigned bit_3:1; 		
    unsigned bit_4:1;    		
    unsigned bit_5:1;    		
    unsigned bit_6:1;    		
    unsigned bit_7:1;   	
  } Byte;
 	
  Byte.bit_7 = dez % 2; dez /= 2; 	
  Byte.bit_6 = dez % 2; dez /= 2; 	
  Byte.bit_5 = dez % 2; dez /= 2; 	
  Byte.bit_4 = dez % 2; dez /= 2; 	
  Byte.bit_3 = dez % 2; dez /= 2; 	
  Byte.bit_2 = dez % 2; dez /= 2; 	
  Byte.bit_1 = dez % 2; dez /= 2; 	
  Byte.bit_0 = dez % 2; dez /= 2; 	 	

  printf( "\n\"a\" wurde als " ); 	
  printf( "%d", Byte.bit_0 ); 	
  printf( "%d", Byte.bit_1 ); 	
  printf( "%d", Byte.bit_2 ); 	
  printf( "%d", Byte.bit_3 ); 	
  printf( "%d", Byte.bit_4 ); 	
  printf( "%d", Byte.bit_5 ); 	
  printf( "%d", Byte.bit_6 ); 	
  printf( "%d", Byte.bit_7 ); 	
  printf( " im Byte mit der Adresse %p gespeichert.\n", &letter ); 	
  printf( "Wo wird der Name der Variable \"letter\" gespeichert?\n\n" );  	

  return 0; 
}
Wobei "printf( "%lu\n", sizeof( struct bb ) );" gibt mir 4 zurück, ich hätte mir aber 1 erwartet.

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Zitat von that
Einerseits für die Speicherreservierung, andererseits muss der Compiler den zu den Datentypen passenden Code erzeugen - es ist ein ja Unterschied, ob du zwei ints oder zwei chars addierst.

Mir ist dazu Ganzzahldatentypen vs. Gleitpunktdatentypen eingefallen.
Beim Unterschied zwischen ints und chars denke ich an die verschiedenen Limits der beiden Datentypen.
Aber beim Rechnen mit ints und chars habe ich nichts bemerkt:

Code:
#include <stdio.h> 
#include <stdlib.h>  

int main( void ) { 
	 	
  char b = 50, c = 51; 	
  int x = 53, y = 54;  	
  int z = b + c; 	
  char a = x + y;  	

  printf( "%d\n", z ); 	
  printf( "%d\n", a ); 	
  printf( "%d\n", b + x ); 	
  printf( "%d\n", a + y ); 	
  printf( "%c\n", z ); 	 	

 return 0;  
}

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Zitat von lama007
Mir ist dazu Ganzzahldatentypen vs. Gleitpunktdatentypen eingefallen.
Beim Unterschied zwischen ints und chars denke ich an die verschiedenen Limits der beiden Datentypen.
Aber beim Rechnen mit ints und chars habe ich nichts bemerkt:

Code:
#include <stdio.h> 
#include <stdlib.h>  

int main( void ) { 
	 	
  char b = 50, c = 51; 	
  int x = 53, y = 54;  	
  int z = b + c; 	
  char a = x + y;  	

  printf( "%d\n", z ); 	
  printf( "%d\n", a ); 	
  printf( "%d\n", b + x ); 	
  printf( "%d\n", a + y ); 	
  printf( "%c\n", z ); 	 	

 return 0;  
}
Der Unterschied ist nicht unbedingt für das Programm problematisch, der compiler muss einfach nur anderen Binärcode erzeugen - Du kannst ja mal das Programm disassemblen um zu schauen was da erzeugt wird.

Zu deinem anderen Codestück - Das dürfte daran liegen dass der compiler nicht unbedingt den minimal benötigten speicherbereich zuweisen muss, der kann auch abstand zwischen den bits lassen, bzw. das feld nicht vollmachen - probier mal
Code:
       -fpack-struct[=n]
	   Without a value specified, pack all structure members together
	   without holes.  When a value is specified (which must be a small
	   power of two), pack structure members according to this value, rep-
	   resenting the maximum alignment (that is, objects with default
	   alignment requirements larger than this will be output potentially
	   unaligned at the next fitting location.

	   Warning: the -fpack-struct switch causes GCC to generate code that
	   is not binary compatible with code generated without that switch.
	   Additionally, it makes the code suboptimal.	Use it to conform to a
	   non-default application binary interface.
Ich würd halt auch das warning beherzigen, verwendet hab ich sowas bis jetzt nicht ;)

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11346
Generell sind auf 32-Bit-Maschinen Datentypen mit weniger als 32 Bits nur dann sinnvoll, wenn sie in großen Mengen (sprich: Arrays) auftreten.

Also ein short oder ein char als z.B. Schleifenvariable oder Funktionsparameter bringt überhaupt keine Vorteile.

Vermutlich auch aus diesem Grund füllt der Compiler das Bitfeld einfach auf 32 Bits auf.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Naja, bitte vergiss nicht dass man aber auch für kleinere Systeme schreiben kann (und ein GUI-Freies Programm lässt sich zumindest weitestgehend sogar Plattformunabhängig schreiben), die eben keine 32/64 Bit Register haben (Und sind die ersten 8 Register im x86-32/64 nicht sowieso 16 Bit? Da war doch was). Es soll auch Systeme geben die im Handheld Format sind, etc.

Ich find schon dass man sein Programm sinnvoll schreiben soll - wenn man nur ein short braucht, deklariert man die Variable auch so, wenns ein char braucht, dann wirds ein char, und wenns ein long long sein muss, dann natürlich auch. Der Compiler bläst die zu kleinen Typen schon auf die richtige Größe auf.

DirtyHarry

aka robobimbo
Avatar
Registered: Apr 2001
Location: outer space
Posts: 464
bei wechselnden plattformen würd ich sowieso mit eigenen datentypen die man per typedef einmal festlegt (zb. uint16) und man somit mit einer änderung am quellcode sicherstellen kann, dass man mit der richtigen wortbreite arbeitet

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11346
Zitat von DirtyHarry
bei wechselnden plattformen würd ich sowieso mit eigenen datentypen die man per typedef einmal festlegt (zb. uint16) und man somit mit einer änderung am quellcode sicherstellen kann, dass man mit der richtigen wortbreite arbeitet

Seit C99 sind die sogar in der Sprache eingebaut - #include <stdint.h> und es gibt unt16_t und viele andere.

DirtyHarry

aka robobimbo
Avatar
Registered: Apr 2001
Location: outer space
Posts: 464
jau, meinte das auch eher im kontext von embedded systems, wo man ja durchwegs mal die ints unterschiedlich gross sind, und der c compiler alles andere aus standardkonform ist :)

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Zitat von DirtyHarry
bei wechselnden plattformen würd ich sowieso mit eigenen datentypen die man per typedef einmal festlegt (zb. uint16) und man somit mit einer änderung am quellcode sicherstellen kann, dass man mit der richtigen wortbreite arbeitet
Das seh ich anders - zumindest nicht nur.

Es hat schon nen Grund warum 'int' plattformabhängig definiert ist. Klar irgendwo - z.B. für Datenfelder - brauch ich vielleicht einen uint16 typ, aber nur selbstgestrickte Datentypen ist der falsche Weg - damit bist du erst recht wieder plattformabhängig (nämlich von der Plattform auf der du testest/entwickelst)
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz