Struct vs Union

Posting ini merupakan jawaban saya pada sebuah pertanyaan di milis linux-programming (Juli 2007). Saya posting di sini karena mungkin akan berguna bagi pemula dalam C.

Struct berguna untuk mengelompokkan data. Contoh: struktur mahasiswa mungkin memiliki NIM, nama, dst. Rasanya ini mudah dimengerti.

Union: untuk memberi beberapa nama untuk satu lokasi memori. Ini yang biasanya yang sulit dimengerti oleh yang baru belajar C. Saya berikan beberapa contoh:

#include <stdio.h>

union {
      int a;
      int b;
} a_dan_b;


int main() 
{
	a_dan_b.a = 5;
	printf("%d\n", a_dan_b.b);
	return 0;
}

Apa hasil keluaran program itu? Jawabnya adalah 5, karena a dan b menempati lokasi memori yang sama. Kita bisa menambahkan banyak variabel di union. Jika tipe variabel itu sama, maka nilainya akan sama. Kita bisa membuat union dari tipe yang berbeda juga, misalnya:

union {
   int a;
  char b;
  long c;
  double d;
} test;

Kompilator akan mengalokasikan memori sesuai dengan tipe yang paling besar (dalam contoh di atas adalah double, 8 byte). Jika kita akses:

test.a  = 5;

Lalu kita akses test.d, maka akan keluar angka yang aneh. Hal ini terjadi karena representasi double dan int tidak sama di memori.

Lalu apa kegunaan fitur semacam ini? biasanya union digabung dengan struct jika struktur digunakan untuk menyimpan lebih dari satu jenis data, dan pada satu saat kita hanya akan menggunakan satu jenis data.

Misalnya kita punya struktur bentuk, yang bisa menyimpan lingkaran atau bujursangkar. LIngkaran punya radius yang tipenya float sedangkan bujursangkar hanya integer (ini hanya contoh saja, sebenarnya agak mengada-ada supaya contohnya sederhana).Kita definisikan enumerasi seperti ini:

     typedef enum { lingkaran, bujursangkar} jenisbentuk;

Dan struktur bentuk adalah seperti ini:

typedef struct {
jenisbentuk jenis;
	    union {
	          float radius;
		  int sisi;
		} info;
} bentuk;

Kita bisa membuatnya tanpa union seperti ini:

typedef struct {
	jenisbentuk jenis;
      float radius;
      int sisi;
} bentuk;

Tapi ini akan memakan lebih banyak memori (12 byte, sedangkan versi union hanya butuh 8 byte). Kita bisa menaruh informasi sisi dan radius di memori yang sama karena kita tahu, bahwa pada satu saat, hanya sisi ATAU radius saja yang dipakai.

Contoh pemakaiannya:

bentuk b;
if (bentuk_baru == lingkaran) {
   b.jenis = lingkaran;
   b.info.radius = r;
} else if (bentuk_baru == bujursangkar) {
   b.jenis = bujursangkar;
   b.info.sisi = s;
} else {
 //bla bla, mungkin error
}

Untuk mengakses lagi, kita harus tahu apakah tadi kita menyimpan di sisi atau radius:

if (b.jenis==lingkaran) {
 printf("Radius = %f\n", b.info.radius);
}

Teknik semacam ini banyak digunakan di banyak API/system call UNIX (contoh: API untuk socket yang bisa menangani berbagai jenis socket, baik tcp/ip. unix socket, bluetooth, dll). Banyak juga dipakai di teknik kompilasi (misal satu node identifier bisa berupa integer, float, atau yang lain).

Leave a Reply

Your email address will not be published. Required fields are marked *