lama007
OC Addicted
|
Hi, kann mir jemand kurz erklären, wo und wie die Namen von Variablen gespeichert werden? #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
AdministratorGNUltra
|
Nirgendwo (zumindest so lange man nicht mit Debug-Flags kompiliert). Variablennamen werden in Speicheradressen uebersetzt.
|
Burschi1620
24/7 Santa Claus
|
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
|
Ok, hier kürzer und sparsamer: #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
|
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
|
Noch sparsamer: #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
|
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: #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
Legendundead
|
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:
#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 -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
|
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
Legendundead
|
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
|
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
|
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
|
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
Legendundead
|
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)
|