Hỏi về kiểu UNION

trong kiểu union thì nó sẽ lấy kích thước của biến lớn nhất làm bộ nhớ chung , vậy ở đây biến c[50] lớn nhất thì cũng chỉ có 50 byte , sao in ra sizeof của c nó cứ ra 52byte nhỉ ,thanks all

#include <stdio.h>
#include <string.h>
 
union Vietjack
{
   int i;
   float f;
   char  chuoi[50];
};
 
int main( )
{
   union Vietjack tenbien;        

   printf( "Kich co bo nho bi chiem giu boi tenbien la: %d\n", sizeof(tenbien));
   
   printf("\n===========================\n");
   printf("VietJack chuc cac ban hoc tot! \n");

   return 0;
}

có byte là có bao nhiêu byte? :V

1 Like

Hỏi thì hỏi cho rõ ràng ra bác: “vậy ở đây biến c[50] lớn nhất thì cũng chỉ có byte , sao in ra sizeof của c nó cứ ra nhỉ” đọc câu này ai biết là bác đang hỏi cái gì.

Nhưng câu “trong kiểu union thì nó sẽ lấy kích thước của biến lớn nhất làm bộ nhớ chung” là chưa hoàn toàn đúng. Phải là “kiểu union sẽ lấy kích thước tối thiểu bằng kích thước của phần tử lớn nhất” ==> điều đó có nghĩa là có trường hợp kích thước của nó sẽ lớn hơn phần tử lớn nhất.!!!

và trường hợp đó là khi nào??? là khi nó alignment ( cái này cũng tương tự như struct thôi, bác tự tiềm hiểu.)

code của bác sẽ ra 52 thay vì 50.

3 Likes

xin lỗi mn ,mình đã sửa lại đề , nãy ko biết sao viết thiếu

tại sao lại ra 52 nhỉ ,rõ ràng ở đây biến c lớn nhất có 50 byte ,
bạn cho mình 1 vidu về alignment đi

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

Mình nói là cái alignment của nó tương tự như struct chứ mình không hề nói nó lưu trữ dữ liệu nó giống struct.
Để giải thích rõ cái này phải vẽ hình ra cho bạn thấy thì mới rõ được, nhưng mình lười quá ( sorry bro ). bác chịu khó tưởng tượng 1 chút.
Trên 32bit system. Mỗi thanh ghi sẽ có 32bit tương ứng với 8 byte.
Khi bác khai báo :

union Vietjack
{
   int i;
   float f;
   char  chuoi[50];
};

Thì lúc này union cần hệ điều hành cấp cho nó 1 vùng nhớ đủ lớn để lưu trữ được dữ liệu tương ứng. Thì không cần phải là thiên tài cũng thấy 50byte là đủ.
Nhưng nếu cấp cho nó chỉ 50byte thì nó sẽ bị “lẽ”.
bác tưởng tượng nhá. 50byte chia đều cho các thanh ghi, mỗi thanh 8byte thì cần 6 thanh ghi công thêm 2byte của thanh ghi thứ 7 ( 8*6 + 2 = 50 ). Thì lúc này thanh ghi thứ 7 chỉ có 2byte muốn lưu kiểu int hay float ( 4byte ) thì nó cần dùng thêm 2byte của thanh ghi thứ 6 ==> cái chổ lẻ này sẽ làm cho máy tính rất khó trong tính toán và làm giảm hiệu năng. Nên trình biên dịch sẽ tự thêm 2byte vào cho thanh ghi thứ 7 đủ 4byte ==> vừa khít để lưu kiểu int, float trên cùng 1 thanh ghi. Do đó, kết quả sẽ là 50 + 2 = 52.

Bonus thêm:
Nếu cũng union như trên, bác đổi lại char chuoi[8]; thì size của union là 8. Nếu char chuoi[9]; thì… là 12. và char chuoi[10]; char chuoi[11]; char chuoi[12]; đều cho size là 12.!!!

1 Like

tại sao char chuoi[8] nó ko cấp phát thêm ,vd tôi tôi tạo ra biên char và xài hết 8 byte , vậy tôi muốn xài tiếp biến int i thì nó lại lấy bộ nhớ đã cấp phát cho biến char hả , vậy lại nhập nhằng rồi

Đọc kĩ hướng dẫn sử dụng trước khi dùng :slight_smile:

3 Likes

vd đoạn code trên ,tôi xài như sau :

Vietjack J;
J.chuoi="12345678";
J.i=15;

vậy bộ nhớ cấp phát giá trị cho biến i=15 là lấy từ chỗ biến chuoi hay phải cấp phát thêm ,xin Rogo10 chỉ giáo

ở chuoi[8] ,nếu theo union thì nó lấy 8byte là max, vậy khi tôi xài hết 8byte để câp phát cho biến int và float phía trên thì ko còn để cấp phát cho char , và theo như bạn nói nó ko cấp phát thêm nữa thì chỉ còn cách lấy bộ nhớ của int và float
Vậy tại sao ở chuoi[9] nó ko lấy lại bộ nhớ đã cấp phát cho int và float mà lại cấp phát thêm
mình chưa rõ chỗ đó ,mong bạn giải thích kỹ hơn ạ!

Cái đầu tiên bác nên tìm hiểu rõ như thế nào là union, như thế nào là struct. Bác đang lẫn lộn giữa hai thằng đó.
Sẽ chả có cái gì được lấy lại và cũng chả cấp phát thêm cái gì hết.

2 Likes

như mình tìm hiểu thì các biến trong union sẽ xài chung 1 bộ nhớ mà , vậy thì phải dùng lại bộ nhớ chứ ?

có lẽ đây là hiện tương padding

Thì đúng nó là padding.

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?