birlik ve yapı hafıza paylaşımı
Bir birlik içindeki iki yapıyı içeren bir sorunun cevabını bulmaya çalışıyordum.
Soruyu çevrimiçi hata ayıklayıcıya yazdım, bulduğum cevabı ve gerçek cevap birbirlerine el vermiyor. Biri açıklama ile cevapta bana yardım edebilir mi?
#include <stdio.h>
int main()
{
union{
struct{
char c[2];
char ch[2];
}s;
struct {
short int i;
short int j;
}st;
}u={12,1,15,1};
printf("%d%d",u.st.i,u.st.j);
}
cevap 268ve271
Yanıtlar
Ondalık sayılar bu tür testler için pek iyi değildir. Ayrıca tüm uyarıları da etkinleştirmelisiniz. Eğer bunu yaparsan alacaksın
<source>:25:8: warning: missing braces around initializer [-Wmissing-braces]
Öyleyse programınızı biraz yeniden yazalım:
int main()
{
union
{
struct
{
char c[2];
char ch[2];
}s;
struct
{
short int i;
short int j;
}st;
}u={.s = {{0x12,0x01},{0x15,0x01}}}; //better to show compiler what you want to initialize
printf("%04hx %04hx",u.st.i,u.st.j);
}
Ve sonuç:
0112 0115
ilklendirmede kullandığımız sayıları açıkça gösteriyor. Rakamlar bize, bu sistemin en az anlamlı baytın ilk yerleştirildiği küçük endian sistemini kullandığını gösteriyor.
Derleyicinin gerekli herhangi bir dolguyu eklemekte özgür olduğunu bilmelisiniz. Bundan kaçınmak için derleyici uzantıları - yapı paketi kullanmanız gerekir.
- Onaltılık değiştirerek bu daha mantıklı başlayın:
{0xC,0x1,0xF,0x1}. Bu, ondalık tabana / ondalık tabandan dönüştürme konusunda endişelenmeden, bellekte depolandıkları haliyle baytları görüntülememizi sağlar. - A'yı başlatırken
union, ilk üye başlatılır, bu durumdastruct s. - Yazmak daha temiz olurdu
{ {{0xC,0x1}, {0xF,0x1}} }ama ne yazık ki C, iç yapıların / dizilerin küme parantezlerinin çıkarılmasına izin vererek, sırf yapabildiğimiz için ilklendirme listelerimize dikkatsizce yazılmış saçmalıklar koymamızı sağlar. - Bir
charbayt dizisinin bellek sırası, herhangi bir sistemde her zaman yukarıdan aşağıya doğrudur: ilk bayt en az önemli adrestedir. Yani:0xC 0x1 0xF 0x1. - Açıkça söylemek gerekirse, derleyici yanlış hizalamayı telafi etmek için struct / union üyeleri arasında herhangi bir yere struct padding baytları eklemekte özgürdür. Bu özel durumda olmaz, ancak örneğin kullanırsak olur
char c[3]. - Şort kullanarak bu hafıza alanına "pun" yazdığınızda, kısa 1 bayttan büyük olduğu ve bir tamsayı türü olduğu için, bunlar kalıcılığa göre okunur.
- Küçük bir endian CPU'da, bu nedenle, her bir kısay, 0xC'nin en az anlamlı bayt olduğunu varsayarsınız ve böylece ilk kısa,
010Conaltılık olarak sona erer .
Kodunuzu hex'e çevirirsek, daha net olmalıdır:
#include <stdio.h>
int main()
{
union{
struct{
char c[2];
char ch[2];
}s;
struct {
short int i;
short int j;
}st;
}u={ {{0xC,0x1}, {0xF,0x1}} };
printf("%.4X\n%.4X",u.st.i,u.st.j);
}
Küçük endian işlemcide çıktı:
010C
010F
10Ch = 268d ve benzeri.