it-swarm-id.com

Bagaimana C Array Diwakili Dalam Memori?

Saya percaya saya mengerti bagaimana variabel normal dan pointer diwakili dalam memori jika Anda menggunakan C.

Misalnya, mudah untuk memahami bahwa pointer Ptr akan memiliki alamat, dan nilainya akan menjadi alamat yang berbeda, yang merupakan ruang di memori yang ditunjuknya. Kode berikut:

int main(){
    int x = 10;
    int *Ptr;
    Ptr = &x;
return 0;
}

Akan memiliki representasi berikut dalam memori:

+---------------------+-------------+---------+
| Variable Name       | Address     | Value   | 
+---------------------+-------------+---------+
| x                   | 3342        | 10      |
+---------------------+-------------+---------+
| Ptr                 | 5466        | 3342    |
+---------------------+-------------+---------+

Namun saya merasa sulit untuk memahami bagaimana array diwakili dalam memori. Misalnya kodenya:

int main(){
    int x[5];
        x[0]=12;
        x[1]=13;
        x[2]=14;

    printf("%p\n",(void*)x);
    printf("%p\n",(void*)&x);

return 0;
}

menampilkan alamat yang sama dua kali (demi kesederhanaan 10568). Artinya x == & x. Namun * x (atau x [0] dalam notasi array) sama dengan 12, * (x +1) (atau x [1] dalam notasi array) sama dengan 13 dan seterusnya. Bagaimana ini bisa diwakili? Salah satu caranya adalah ini:

+---------------------+-------------+----------+----------------------+
| Variable Name       | Address     | Value    | Value IF array       |
+---------------------+-------------+----------+----------------------+
| x                   | 10568       | 10568    | 12                   |
+---------------------+-------------+----------+----------------------+
|                     | 10572       |          | 13                   | 
+---------------------+-------------+----------+----------------------+
|                     | 10576       |          | 14                   | 
+---------------------+-------------+----------+----------------------+
|                     | 10580       |          | trash                | 
+---------------------+-------------+----------+----------------------+
|                     | 10584       |          | trash                | 
+---------------------+-------------+----------+----------------------+

Apakah ini dekat dengan apa yang terjadi, atau sama sekali tidak aktif?

25
Daniel Scocco

Array adalah blok objek yang berdekatan tanpa spasi di antaranya. Ini berarti bahwa x dalam contoh kedua Anda disajikan dalam memori sebagai:

+---------------------+-------------+---------+
| Variable Name       | Address     | Value   | 
+---------------------+-------------+---------+
| x                   | 10568       | 12      |
|                     |             +---------+
|                     |             | 13      |
|                     |             +---------+
|                     |             | 14      |
|                     |             +---------+
|                     |             | ??      |
|                     |             +---------+
|                     |             | ??      |
+---------------------+-------------+---------+

Yaitu, x adalah lima ints besar, dan memiliki satu alamat.

Bagian aneh tentang array bukan pada bagaimana mereka disimpan - melainkan bagaimana mereka dievaluasi dalam ekspresi. Jika Anda menggunakan nama array di suatu tempat yang bukan subjek dari operator & atau sizeof unary, itu mengevaluasi ke alamat anggota pertama.

Artinya, jika Anda hanya menulis x, Anda akan mendapatkan nilai 10568 dengan mengetik int *.

Jika, di sisi lain Anda menulis &x, maka aturan khusus tidak berlaku - sehingga operator & bekerja seperti biasanya, yang artinya ia mengambil alamat array. Dalam contoh ini, ini akan menjadi nilai 10568 dengan tipe int (*)[5].

Alasan bahwa x == &x adalah bahwa alamat anggota pertama array harus sama dengan alamat array itu sendiri, karena sebuah array dimulai dengan anggota pertamanya.

32
caf

Diagram Anda benar. Keanehan di sekitar &x tidak ada hubungannya dengan bagaimana array diwakili dalam memori. Ini ada hubungannya dengan peluruhan pointer-> pointer. x dengan sendirinya dalam konteks nilai meluruh menjadi pointer ke elemen pertamanya; yaitu, ini setara dengan &x[0]. &x adalah pointer ke array, dan fakta bahwa keduanya sama secara numerik hanya mengatakan bahwa alamat array secara numerik sama dengan alamat elemen pertama.

22
Raymond Chen

Ya, Anda sudah mendapatkannya. Array C menemukan nilai yang diindeks x[y] dengan menghitung x + (y * sizeof(type)). x adalah alamat awal dari array. y * sizeof(type) adalah offset dari itu. x[0] menghasilkan alamat yang sama dengan x.

Array multidimensi juga dilakukan, sehingga int x[y][z] akan menggunakan memori sizeof(int) * y * z.

Karena ini, Anda dapat melakukan beberapa trik pointer C bodoh. Ini juga berarti mendapatkan ukuran array hampir mustahil.

2
Schwern

Bagian Array dan Pointer di C FAQ memiliki beberapa informasi bermanfaat.

0
Sinan Ünür

Daniel,

ini tidak sulit. Anda memiliki ide dasar dan tidak ada banyak perbedaan dalam representasi memori array. jika Anda mendeklarasikan sebuah array, katakan

     void main(){
         int arr[5]={0,1,2,3,4};


     }

anda telah menginisialisasi (mendefinisikan) array. Jadi lima elemen akan disimpan di lima lokasi yang berdekatan dalam memori. Anda dapat mengamati ini dengan merujuk alamat memori masing-masing elemen. Tidak seperti tipe data primitif lainnya dalam C, pengidentifikasi array (di sini, arr ) itu sendiri merupakan penunjuknya. Idenya tampak kabur jika Anda seorang pemula tetapi Anda akan merasa nyaman saat melanjutkan. 

      printf("%d",arr);

baris ini akan menunjukkan alamat memori elemen pertama, arr [0]. Ini mirip dengan merujuk alamat elemen pertama.

      printf("%d",&arr[0]);

sekarang, Anda dapat melihat lokasi memori semua elemen. Sepotong kode berikut akan melakukan pekerjaan.

    int i;
    for(i=0;i<5;i++){
       printf("location of %d is %d\n",arr[i],&arr[i]);
    } 

anda akan melihat setiap kenaikan alamat dengan kesenjangan empat (jika bilangan bulat Anda adalah 32 bit). Jadi, Anda dapat dengan mudah memahami bagaimana array disimpan dalam memori.

anda juga dapat mencoba hal yang sama menggunakan metode yang berbeda.

    int i;
    for(i=0;i<5;i++){
       printf("location of %d is %d\n",*(a+i),a+i);
    }

anda akan mendapatkan serangkaian jawaban yang sama di kedua kasus dan mencoba untuk mendapatkan kesetaraan. 

coba eksperimen yang sama menggunakan tipe data berbeda (tipe char, float, dan struct). Anda akan melihat perbedaan antara elemen-elemen yang berdekatan bervariasi berdasarkan ukuran elemen tunggal.

0
Tharindu Rusira

Array C hanyalah blok memori yang memiliki nilai sekuensial dengan ukuran yang sama. Ketika Anda memanggil malloc (), itu hanya memberi Anda blok memori. foo[5] sama dengan *(foo + 5).

Contoh - foo.c:

#include <stdio.h>

int main(void)
{
    int foo[5];
    printf("&foo[0]: %tx\n", &foo[0]);
    printf("foo: %tx\n\n", foo);
    printf("&foo[3]: %tx\n", &foo[3]);
    printf("foo: %tx\n", foo + 3);
}

Keluaran:

$ ./foo
&foo[0]: 5fbff5a4
foo: 5fbff5a4

&foo[3]: 5fbff5b0
foo: 5fbff5b0
0
ObscureRobot

Array dalam C adalah blok memori berurutan dengan blok masing-masing anggota dengan ukuran yang sama. Inilah sebabnya mengapa pointer berfungsi, Anda mencari offset berdasarkan alamat anggota pertama.

0
alex