Modul 4: Pointer dan Struct - Algoritma-dan-Pemrograman-ITS/DasarPemrograman GitHub Wiki

Daftar Isi


Pointer

Alamat Memori

Operator Address-Of (&)

Setiap variabel, fungsi, struct, ataupun objek lain yang dibuat dalam program mempunyai lokasi masing-masing pada memori. Alokasi setiap variabel disimpan dalam alamat memori tertentu.

Misalnya:
Terdapat variabel bernama var. Untuk mengetahui alamat memori dari variabel, digunakan operator address-of (&) di depan nama variabelnya.

int var = 5;
printf("%d\n", var);
printf("%p\n", &var);

Output:

5
0x7fffdeb3ed84

Output bisa berbeda-beda di tiap eksekusi.
0x7fffdeb3ed84 merupakan alamat memori dari variabel var.


Pengenalan Pointer

Pointer adalah variabel spesial yang menampung alamat memori, bukan nilai seperti variabel biasa.

Deklarasi Variabel Pointer

Deklarasi variabel pointer menggunakan operator * di antara tipe data dan nama variabelnya.

int *ptr;

atau

int* ptr;

Kedua cara deklarasi di atas merupakan sintaks yang valid.

Inisialisasi Variabel Pointer

Variabel ptr di atas adalah variabel pointer yang bertipe int. Variabel pointer menampung alamat memori. Inisialisasi variabel pointer harus berupa alamat memori, bisa dari variabel lain atau alokasi secara dinamis.

int var = 55;
int *ptr = &var; // Inisialisasi menggunakan alamat dari var

Inisialisasi yang tidak sesuai akan menghasilkan error atau undefined behaviour.

// ERROR
int *ptr  = 5;
// UNDEFINED BEHAVIOUR
int *ptr2 = 0x7fffdeb3ed84;

Assignment Variabel Pointer

Cara melakukan assignment pada variabel pointer tidak sama dengan inisialisasinya.

int var, *ptr;
var = 55;
ptr = &var; // Assignment pada variabel pointer menggunakan alamat dari var

Assignment tidak perlu menggunakan simbol * di depan nama variabelnya. Berbeda pada saat deklarasi yang mana kita perlu memberitahu compiler bahwa variabel tersebut adalah variabel pointer.

Operator Dereference (*)

Operator dereference menggunakan simbol yang sama dengan simbol operator perkalian, yakni * (simbol asterisk). Namun, fungsinya sangat berbeda. Operator dereference digunakan untuk mengakses nilai yang ditunjuk (pointed) dari sebuah variabel pointer.

Untuk mengakses nilai dari sebuah variabel pointer, digunakan operator dereference di depan nama variabel pointer.

int var  = 55;
int *ptr = &var;

printf("%d\n", *ptr);
*ptr = 20;

printf("%d\n", *ptr);
printf("%d\n", var);

Output

55
20
20

Apa output dari program di bawah ini?

#include <stdio.h>

int main(void)
{
    int x, y, z;
    int *ptr1, *ptr2;
    x = 5;
    y = 6;

    ptr1 = &x;
    ptr2 = &y;

    z = *ptr1 + *ptr2;
    printf("%d\n", z);
    
    return 0;
}

Double Pointer

Variabel pointer juga dapat menunjuk variabel pointer lainnya. Hal ini disebut dengan double pointer (pointer to pointer). Untuk mendeklarasikan variabel double pointer, digunakan dua simbol *. Kegunaan paling umum dari variabel double pointer adalah untuk membuat array dua dimensi secara dinamis.

int **dbPtr;

Variabel dbPtr di atas menyimpan alamat memori dari variabel pointer lainnya.

#include <stdio.h>

int main(void)
{
    int var = 23;
    int *ptr = &var;
    int **dbPtr = &ptr;

    printf("%d\n", **dbPtr);
    
    return 0;
}

Pointer dan Array

Kita sudah mengetahui bahwa array adalah kumpulan data yang disusun secara sekuensial. Karena disusun secara sekuensial, alamat-alamat memori tiap elemen array juga tersusun secara berurutan.

memory

Bagaimana jika kita ingin mengetahui alamat memori dari array?

#include <stdio.h>

int main()
{
    int arr[5] = {1, 2, 3, 4, 5};
    int i;
    for (i = 0; i < 5; ++i) {
        printf("&arr[%d] => %p\n", i, &arr[i]);
    }
    printf("Address of arr => %p\n", arr);
    return 0;
}

Output

&arr[0] => 0x7fffe85f0520
&arr[1] => 0x7fffe85f0524
&arr[2] => 0x7fffe85f0528
&arr[3] => 0x7fffe85f052c
&arr[4] => 0x7fffe85f0530
Address of arr => 0x7fffe85f0520

Dapat diperhatikan bahwa alamat dari &arr[0] sama dengan alamat dari arr. Dari hal ini dapat diketahui bahwa nama array menunjuk ke elemen pertama dari array tersebut. Karena &arr[0] = arr, maka dapat disimpulkan bahwa arr[0] = *arr, atau nilai dari elemen pertama dapat diakses dengan *arr atau *(arr + 0).

arr[0] = *(arr + 0)
arr[1] = *(arr + 1)
arr[2] = *(arr + 2)
.
.
dst

Kesimpulan: Nama array merujuk pada alamat memori dari elemen pertama pada array. Berbekal dari hal tersebut, maka kita dapat melakukan hal demikian.

#include <stdio.h>

int main()
{
    int arr[5] = {1, 2, 3, 4, 5}, i;
    int *ptr = arr;

    for (i = 0; i < 5; ++i) {
        printf("%d ", *(ptr+i));
    }
    return 0;
}

Output

1 2 3 4 5

Pointer dan Fungsi

Sebelumnya kita sudah mengetahui bahwa fungsi dapat menerima parameter sebagai input. Penggunaan-penggunaan parameter fungsi selama ini sebenarnya menggunakan konsep pass by value. Selain menggunakan cara itu, terdapat cara lain untuk passing argumen pada fungsi.

Pass by Value

Pass by Value berarti saat kita memasukkan (passing) argumen pada fungsi, nilai dari argumen tersebut akan disalin ke variabel yang berada pada parameter fungsi. Karena hanya nilainya saja yang diterima oleh fungsi, perubahan yang terjadi pada variabel parameter fungsi tidak akan berpengaruh terhadap variabel asalnya.

Contoh:

#include <stdio.h>

void change(int a, int b)
{
    a = a + 5;
    b = b + 5;
}

int main()
{
    int x = 10, y = 6;
    change(x, y);
    printf("%d %d\n", x, y);

    return 0;
}

Nilai pada variabel x dan y tidak berubah karena metode passing yang digunakan adalah Pass by Value.

Pass by Address/Reference

Berbeda dengan sebelumnya, sesuai namanya, metode Pass by Address berarti argumen yang dimasukkan (passing) ke parameter fungsi adalah alamat memori variabel. Segala perubahan yang terjadi pada variabel tersebut, juga mempengaruhi langsung ke variabel asalnya. Hal ini terjadi karena argumennya adalah langsung berupa alamat memorinya.

#include <stdio.h>

void change(int *a, int *b)
{
    *a = *a + 5;
    *b = *b + 5;
}

int main()
{
    int x = 10, y = 6;
    change(&x, &y);
    printf("%d %d\n", x, y);

    return 0;
}

Karena parameternya menerima alamat memori, maka variabel parameternya harus berupa pointer.

Passing array sebagai parameter fungsi juga dapat dilakukan dengan pointer. Segala perubahan pada array akan berpengaruh pada array asalnya.

#include <stdio.h>

void printArr(int *arr)
{
    // ...
    // ...
}

int main()
{
    int num[5] = {1, 2, 3, 4, 5}, i;
    printArr(num);
    // ...
    // ...
    return 0;
}

Struct

Pengenalan Struct

Dalam bahasa C, struct adalah salah satu tipe data turunan atau bisa disebut juga user defined data type yang dapat mengelompokkan beberapa variabel di bawah satu nama. Tidak seperti array yang hanya dapat menyimpan elemen dengan tipe data sama, struct dapat mengelompokkan elemen dengan tipe data yang berbeda-beda.

Contoh:

Perhatikan gambar di atas. Mahasiswa merupakan suatu entitas yang di dalamnya terdapat atribut-atribut berupa:

  • Nama
  • NRP
  • Umur
  • IPK
  • Semester
  • Status

Atribut-atribut inilah yang nantinya berperan sebagai member dari struct Mahasiswa.

Deklarasi Struct

Seperti variabel, struct harus dideklarasikan terlebih dahulu sebelum bisa digunakan. Pendeklarasian struct menggunakan sintaks sebagai berikut.

struct <nama_struct> {
    <tipe_data_member> <nama_member>;
    <tipe_data_member> <nama_member>;
    <tipe_data_member> <nama_member>;
    .
    .
    .
};

Berikut adalah contoh deklarasi struct berdasarkan kasus Mahasiswa di atas.

struct Mahasiswa {
    char nama[100];
    char nrp[20];
    int umur;
    double ipk;
    int semester;
    int status;
};

Variabel Struct

Setelah dideklarasikan, sebuah struct akan menjadi tipe data baru. Maka dalam kasus ini, struct Mahasiswa di sini menjadi tipe data baru dengan member-member berupa nama, nrp, umur, ipk, semester, dan status. Untuk membuat variabel dengan tipe data struct, dilakukan dengan sintaks berikut.

struct <nama_struct> <nama_variabel>;

Contoh:

struct Mahasiswa mhs1;
struct Mahasiswa mhs2;

Contoh di atas menunjukkan terdapat dua variabel mhs1 dan mhs2 bertipe struct Mahasiswa.

Akses Member Struct

Lalu bagaimana cara untuk mengakses member dari variabel struct yang telah dibuat? Untuk mengakses member-member dari struct, digunakan operator dot (.) setelah nama variabelnya.

<nama_variabel>.<member_struct>

Contoh:

mhs1.umur = 19;
mhs1.semester = 3;

mhs2.umur = 20;
mhs2.semester = 5;

Contoh program untuk mendemonstrasikan Struct:

#include <stdio.h>
#include <string.h>

struct Mahasiswa {
    char nama[100];
    char nrp[20];
    int umur;
    double ipk;
    int semester;
    int status;
};

int main(void)
{
    struct Mahasiswa mhs1;

    strcpy(mhs1.nama, "Ahmad");
    strcpy(mhs1.nrp, "05111940000012");
    mhs1.umur = 18;
    mhs1.ipk = 3.94;
    mhs1.semester = 3;
    mhs1.status = 1;

    printf("Nama\t: %s\n", mhs1.nama);
    printf("NRP\t: %s\n", mhs1.nrp);
    printf("Umur\t: %d\n", mhs1.umur);
    printf("IPK\t: %.2lf\n", mhs1.ipk);
    printf("Sem\t: %d\n", mhs1.semester);
    printf("Status\t: %s\n", (mhs1.status == 1 ? "Aktif" : "Tidak Aktif"));
    
    return 0;
}

Array of Struct

Kita juga dapat membuat array dengan tipe data struct. Caranya sama persis dengan deklarasi array pada umumnya.

#include <stdio.h>
struct Point {
    int x, y;
};

int main()
{
    struct Point arr[3];
    arr[0].x = 2, arr[0].y = 3;
    arr[1].x = 5, arr[1].y = 3;
    arr[2].x = 2, arr[2].y = 8;

    printf("%d %d\n", arr[0].x, arr[0].y);
    printf("%d %d\n", arr[1].x, arr[1].y);
    printf("%d %d\n", arr[2].x, arr[2].y);
    
    return 0;
}

Soal Latihan

Soal 1

Implementasikan fungsi bernama tambah berisi 3 parameter, di mana parameter pertama merupakan bilangan 1, parameter kedua merupakan bilangan 2, dan parameter terakhir adalah variabel tempat hasil output.

Contoh pemanggilan:

int a = 1;
int b = 2;
int c;
tambah(a, b, &c);
printf(ā€œ%dā€, c);

Output-nya:

3

Soal 2

Buatlah struct untuk menyimpan data nilai UN mahasiswa yang berisi nama, nilai Matematika, nilai IPA, nilai Bahasa Indonesia, dan nilai Bahasa Inggris. Setelah itu buat program yang dapat memasukkan list data nilai UN lalu menampilkan data sesuai nama.

Keterangan: urutan pemasukan nilai adalah Matematika, IPA, Bahasa Indonesia, Bahasa Inggris. Berikut merupakan contoh input dan output. 4 kelompok data di awal merupakan jumlah data nilai UN yang akan dimasukkan. Angka 3 di akhir merupakan jumlah nama yang akan dicari.

Sample Input

4
Hope
100
90
20
90
Ricky
80
70
80
90
Maden
100
100
100
100
Tenten
90
80
99
100
3
Maden
Dennis
Tenten

Sample Output

Nilai Maden 
Matematika : 100
IPA : 100
Bahasa Indonesia : 100
Bahasa Inggris : 100
Nilai Dennis tidak ditemukan
Nilai Tenten
Matematika : 90
IPA : 80
Bahasa Indonesia : 99
Bahasa Inggris : 100

Soal 3

Buatlah fungsi bernama reverse() untuk me-reverse array of integer menggunakan pointer. Fungsinya dapat digunakan seperti berikut.

int arr[5]
.
.
//input

reverse(arr, 5);
.
.
//print isi arr

Sample Input:

5
8 4 2 3 1

Sample Output:

1 3 2 4 8
āš ļø **GitHub.com Fallback** āš ļø