[c] Speicherort Variable-Name

Seite 1 von 1 - Forum: Coding Stuff auf overclockers.at

URL: https://www.overclockers.at/coding-stuff/c_speicherort_variable-name_205348/page_1 - zur Vollversion wechseln!


lama007 schrieb am 01.03.2009 um 20:29

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 schrieb am 01.03.2009 um 21:22

Nirgendwo (zumindest so lange man nicht mit Debug-Flags kompiliert). Variablennamen werden in Speicheradressen uebersetzt.


Burschi1620 schrieb am 01.03.2009 um 21:31

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 schrieb am 02.03.2009 um 08:20

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 schrieb am 02.03.2009 um 09:25

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 schrieb am 02.03.2009 um 10:01

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 schrieb am 02.03.2009 um 10:46

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 schrieb am 02.03.2009 um 11:57

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 schrieb am 02.03.2009 um 22:29

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 schrieb am 03.03.2009 um 09:57

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 schrieb am 04.03.2009 um 00:05

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 schrieb am 04.03.2009 um 00:24

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 schrieb am 04.03.2009 um 16:13

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 schrieb am 05.03.2009 um 02:12

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)




overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2026