The memory of your computer can be imagined as a succession of memory cells, each one of the minimal size that computers manage (one byte). Memori komputer Anda dapat dibayangkan sebagai suksesi sel memori, masing-masing ukuran minimal komputer yang mengelola (satu byte). These single-byte memory cells are numbered in a consecutive way, so as, within any block of memory, every cell has the same number as the previous one plus one. Single-byte ini sel-sel memori tersebut diberi nomor dalam cara berturut-turut, sehingga, dalam setiap blok memori, setiap sel memiliki jumlah yang sama seperti sebelumnya ditambah satu.
This way, each cell can be easily located in the memory because it has a unique address and all the memory cells follow a successive pattern. Dengan cara ini, setiap sel dapat dengan mudah yang terletak di memori karena memiliki alamat yang unik dan semua sel memori mengikuti pola yang berurutan. For example, if we are looking for cell 1776 we know that it is going to be right between cells 1775 and 1777, exactly one thousand cells after 776 and exactly one thousand cells before cell 2776. Sebagai contoh, jika kita mencari sel 1776 kita tahu bahwa itu akan tepat di antara sel-sel 1775 dan 1777, persis seribu sel setelah 776 dan tepat satu ribu sel sel sebelum 2776.
Reference operator (&) Operator referensi (&)
As soon as we declare a variable, the amount of memory needed is assigned for it at a specific location in memory (its memory address). Segera setelah kami menyatakan sebuah variabel, jumlah memori yang diperlukan sudah ditetapkan untuk itu di lokasi tertentu di memori (alamat memori nya). We generally do not actively decide the exact location of the variable within the panel of cells that we have imagined the memory to be - Fortunately, that is a task automatically performed by the operating system during runtime. Kami biasanya tidak aktif memutuskan lokasi yang tepat dari variabel dalam panel sel-sel yang telah kita bayangkan memori menjadi - Untungnya, itu adalah tugas dilakukan secara otomatis oleh sistem operasi pada saat runtime. However, in some cases we may be interested in knowing the address where our variable is being stored during runtime in order to operate with relative positions to it. Namun, dalam beberapa kasus kita mungkin tertarik untuk mengetahui alamat di mana variabel kita sedang disimpan selama runtime dalam rangka untuk beroperasi dengan posisi relatif untuk itu.The address that locates a variable within memory is what we call a reference to that variable. Alamat yang menempatkan variabel di dalam memori adalah apa yang kita sebut referensi ke variabel. This reference to a variable can be obtained by preceding the identifier of a variable with an ampersand sign ( & ), known as reference operator, and which can be literally translated as "address of". Ini referensi ke variabel dapat diperoleh dengan mendahului identifier dari sebuah variabel dengan tanda ampersand (&), yang dikenal sebagai referensi operator, dan yang dapat harfiah diterjemahkan sebagai "alamat". For example: Contoh:
|
This would assign to ted the address of variable andy , since when preceding the name of the variable andy with the reference operator ( & ) we are no longer talking about the content of the variable itself, but about its reference (ie, its address in memory). Hal ini akan menugaskan ke alamat ted variabel andy, sejak kapan nama sebelum variabel andy dengan operator referensi (&) kita tidak lagi bicara tentang isi dari variabel itu sendiri, tapi tentang referensi (yaitu, dengan alamat di memori).
From now on we are going to assume that andy is placed during runtime in the memory address 1776 . Dari sekarang kita akan berasumsi bahwa andy ditempatkan selama runtime di alamat memori 1776. This number ( 1776 ) is just an arbitrary assumption we are inventing right now in order to help clarify some concepts in this tutorial, but in reality, we cannot know before runtime the real value the address of a variable will have in memory. Nomor ini (1776) hanya sebuah asumsi yang sewenang-wenang menciptakan kita sekarang dalam rangka untuk membantu menjelaskan beberapa konsep dalam tutorial ini, tetapi dalam kenyataannya, kita tidak dapat mengetahui sebelum runtime nilai riil alamat dari suatu variabel akan memiliki di memori.
Consider the following code fragment: Perhatikan fragmen kode berikut:
| 1 1 2 2 3 3 | |
The values contained in each variable after the execution of this, are shown in the following diagram: Nilai-nilai yang terkandung dalam setiap variabel setelah eksekusi ini, akan ditampilkan dalam diagram berikut:
First, we have assigned the value 25 to andy (a variable whose address in memory we have assumed to be 1776). Pertama, kami telah diberi nilai 25 hingga andy (sebuah variabel yang alamatnya di memori kita diasumsikan 1776).
The second statement copied to fred the content of variable andy (which is 25). Pernyataan kedua disalin ke fred isi variabel andy (yang adalah 25). This is a standard assignment operation, as we have done so many times before. Ini adalah tugas standar operasi, seperti yang telah kita lakukan begitu banyak kali sebelumnya.
Finally, the third statement copies to ted not the value contained in andy but a reference to it (ie, its address, which we have assumed to be 1776 ). Akhirnya, pernyataan ketiga tidak ted tembusan kepada nilai yang terkandung dalam andy tetapi referensi untuk hal itu (yaitu, alamatnya, yang telah kita diasumsikan 1776). The reason is that in this third assignment operation we have preceded the identifier andy with the reference operator ( & ), so we were no longer referring to the value of andy but to its reference (its address in memory). Alasannya adalah bahwa dalam operasi tugas ketiga ini kita telah mendahului andy pengenal dengan operator referensi (&), jadi kami tidak lagi merujuk pada nilai andy tetapi acuannya (alamatnya di memori).
The variable that stores the reference to another variable (like ted in the previous example) is what we call a pointer . Variabel yang menyimpan referensi ke variabel lain (seperti ted pada contoh sebelumnya) adalah apa yang kita sebut pointer. Pointers are a very powerful feature of the C++ language that has many uses in advanced programming. Pointer adalah fitur yang sangat kuat dari C + + bahasa yang memiliki banyak digunakan dalam pemrograman tingkat lanjut. Farther ahead, we will see how this type of variable is used and declared. Lebih jauh ke depan, kita akan melihat bagaimana jenis variabel ini digunakan dan dinyatakan.
Dereference operator (*) Dereference operator (*)
We have just seen that a variable which stores a reference to another variable is called a pointer. Kita baru saja melihat bahwa sebuah variabel yang menyimpan referensi ke variabel lain disebut pointer. Pointers are said to "point to" the variable whose reference they store. Pointer berkata kepada "titik untuk" variabel yang referensi toko mereka.
Using a pointer we can directly access the value stored in the variable which it points to. Menggunakan pointer kita dapat langsung mengakses nilai yang tersimpan dalam variabel yang menunjuk ke. To do this, we simply have to precede the pointer's identifier with an asterisk (*), which acts as dereference operator and that can be literally translated to "value pointed by". Untuk melakukan ini, kita hanya perlu mendahului identifier pointer dengan tanda bintang (*), yang bertindak sebagai operator dan dereference yang dapat harfiah diterjemahkan ke "nilai ditunjukkan oleh".
Therefore, following with the values of the previous example, if we write: Oleh karena itu, berikut dengan nilai-nilai contoh sebelumnya, jika kita menulis:
|
(that we could read as: " beth equal to value pointed by ted ") beth would take the value 25 , since ted is 1776 , and the value pointed by 1776 is 25. (bahwa kami bisa dibaca sebagai: "beth sama dengan nilai yang ditunjukkan oleh ted") beth akan mengambil nilai 25, karena ted adalah 1776, dan nilai yang ditunjukkan oleh 1776 adalah 25.
You must clearly differentiate that the expression ted refers to the value 1776 , while *ted (with an asterisk * preceding the identifier) refers to the value stored at address 1776 , which in this case is 25 . Anda harus dengan jelas membedakan bahwa ungkapan ted mengacu pada nilai 1776, sementara * ted (dengan tanda bintang * sebelumnya pengenal) merujuk kepada nilai alamat yang tersimpan pada 1776, yang dalam kasus ini adalah 25. Notice the difference of including or not including the dereference operator (I have included an explanatory commentary of how each of these two expressions could be read): Perhatikan perbedaan termasuk atau tidak termasuk dereference operator (Saya telah menyertakan komentar penjelasan tentang bagaimana masing-masing dari kedua ekspresi bisa dibaca):
| 1 1 2 2 | |
Notice the difference between the reference and dereference operators: Perhatikan perbedaan antara dereference referensi dan operator:
- & is the reference operator and can be read as "address of" & Adalah operator dan referensi dapat dibaca sebagai "alamat"
- * is the dereference operator and can be read as "value pointed by" * Adalah operator dan dereference dapat dibaca sebagai "nilai ditunjukkan oleh"
Thus, they have complementary (or opposite) meanings. Dengan demikian, mereka saling melengkapi (atau sebaliknya) makna. A variable referenced with & can be dereferenced with * . Variabel direferensikan dengan & dapat dereferenced dengan *.
Earlier we performed the following two assignment operations: Sebelumnya kita melakukan dua tugas operasi berikut:
| 1 1 2 2 | |
Right after these two statements, all of the following expressions would give true as result: Tepat setelah dua pernyataan ini, semua istilah berikut akan memberikan hasil benar sebagai:
| 1 1 2 2 3 3 4 4 | |
The first expression is quite clear considering that the assignment operation performed on andy was andy=25 . Ekspresi pertama cukup jelas mengingat bahwa tugas operasi itu dilakukan pada andy andy = 25. The second one uses the reference operator ( & ), which returns the address of variable andy , which we assumed it to have a value of 1776 . Yang kedua menggunakan operator referensi (&), yang mengembalikan alamat dari variabel andy, yang kita asumsikan itu memiliki nilai 1776. The third one is somewhat obvious since the second expression was true and the assignment operation performed on ted was ted=&andy . Yang ketiga agak jelas karena ekspresi kedua benar dan penugasan operasi dilakukan pada ted adalah ted = & andy. The fourth expression uses the dereference operator ( * ) that, as we have just seen, can be read as "value pointed by", and the value pointed by ted is indeed 25 . Ekspresi keempat menggunakan operator dereference (*) itu, seperti yang telah kita lihat, dapat dibaca sebagai "nilai ditunjukkan oleh", dan nilai yang ditunjukkan oleh ted memang 25.
So, after all that, you may also infer that for as long as the address pointed by ted remains unchanged the following expression will also be true: Jadi, setelah semua itu, Anda juga menyimpulkan bahwa selama alamat ditunjukkan oleh ted tetap tidak berubah ekspresi berikut ini juga akan benar:
|
Declaring variables of pointer types Mendeklarasikan variabel tipe pointer
Due to the ability of a pointer to directly refer to the value that it points to, it becomes necessary to specify in its declaration which data type a pointer is going to point to. Karena kemampuan dari pointer ke langsung merujuk kepada nilai yang menunjuk pada, menjadi perlu menetapkan dalam deklarasi yang tipe data pointer akan menunjuk ke. It is not the same thing to point to a char as to point to an int or a float . Bukan hal yang sama untuk menunjuk pada sebuah char sebagai untuk menunjuk ke sebuah int atau float.The declaration of pointers follows this format: Deklarasi pointer mengikuti format ini:
type * name; type * nama;
where type is the data type of the value that the pointer is intended to point to. dimana jenis tipe data dari nilai yang dimaksudkan pointer untuk menunjuk ke. This type is not the type of the pointer itself! Tipe ini bukan tipe dari pointer itu sendiri! but the type of the data the pointer points to. tetapi tipe data pointer menunjuk ke. For example: Contoh:
| 1 1 2 2 3 3 | |
These are three declarations of pointers. Ini adalah tiga deklarasi pointer. Each one is intended to point to a different data type, but in fact all of them are pointers and all of them will occupy the same amount of space in memory (the size in memory of a pointer depends on the platform where the code is going to run). Masing-masing dimaksudkan untuk menunjukkan tipe data yang berbeda, tetapi kenyataannya semua itu adalah pointer dan mereka semua akan menempati jumlah ruang yang sama di memori (ukuran memori dari pointer tergantung pada platform dimana kode ini akan untuk menjalankan). Nevertheless, the data to which they point to do not occupy the same amount of space nor are of the same type: the first one points to an int , the second one to a char and the last one to a float . Namun demikian, data yang menunjukkan mereka tidak menempati jumlah ruang yang sama atau berasal dari tipe yang sama: yang pertama menunjuk ke suatu int, yang kedua ke char dan yang terakhir untuk pelampung. Therefore, although these three example variables are all of them pointers which occupy the same size in memory, they are said to have different types: int* , char* and float* respectively, depending on the type they point to. Oleh karena itu, walaupun ketiga variabel contoh mereka semua petunjuk yang menempati ukuran yang sama di memori, mereka dikatakan memiliki jenis yang berbeda: int *, char * dan float * masing-masing, tergantung pada jenis mereka menunjukkan.
I want to emphasize that the asterisk sign ( * ) that we use when declaring a pointer only means that it is a pointer (it is part of its type compound specifier), and should not be confused with the dereference operator that we have seen a bit earlier, but which is also written with an asterisk ( * ). Saya ingin menekankan bahwa tanda asterisk (*) yang kita gunakan ketika mendeklarasikan sebuah pointer hanya berarti bahwa itu adalah suatu penunjuk (ini adalah bagian dari senyawa jenis specifier), dan tidak boleh dereference bingung dengan operator yang kita telah melihat sedikit lebih dulu, tetapi yang juga ditulis dengan tanda bintang (*). They are simply two different things represented with the same sign. Mereka hanya dua hal yang berbeda diwakili dengan tanda yang sama.
Now have a look at this code: Sekarang kita lihat kode ini:
| 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 | | firstvalue is 10 firstvalue adalah 10 |
Notice that even though we have never directly set a value to either firstvalue or secondvalue , both end up with a value set indirectly through the use of mypointer . Perhatikan bahwa meskipun kami tidak pernah secara langsung mengatur nilai baik untuk firstvalue atau secondvalue, keduanya berakhir dengan nilai yang diatur secara tidak langsung melalui penggunaan mypointer. This is the procedure: Ini adalah prosedur:
First, we have assigned as value of mypointer a reference to firstvalue using the reference operator ( & ). Pertama, kami telah ditugaskan sebagai nilai mypointer referensi ke firstvalue menggunakan operator referensi (&). And then we have assigned the value 10 to the memory location pointed by mypointer , that because at this moment is pointing to the memory location of firstvalue , this in fact modifies the value of firstvalue . Dan kemudian kita tetapkan nilai 10 untuk menunjuk lokasi memori oleh mypointer, bahwa karena saat ini menunjuk ke lokasi memori firstvalue, ini sebenarnya memodifikasi nilai firstvalue.
In order to demonstrate that a pointer may take several different values during the same program I have repeated the process with secondvalue and that same pointer, mypointer . Dalam rangka untuk menunjukkan bahwa pointer dapat berlangsung beberapa nilai yang berbeda dalam program yang sama saya telah mengulangi proses yang sama secondvalue dan pointer, mypointer.
Here is an example a little bit more elaborated: Berikut adalah contoh sedikit lebih dijabarkan:
| 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 | | firstvalue is 10 firstvalue adalah 10 |
I have included as a comment on each line how the code can be read: ampersand ( & ) as "address of" and asterisk ( * ) as "value pointed by". Saya telah menyertakan sebagai komentar pada setiap baris kode bagaimana dapat dibaca: ampersand (&) sebagai "alamat" dan tanda bintang (*) sebagai "nilai ditunjukkan oleh".
Notice that there are expressions with pointers p1 and p2 , both with and without dereference operator ( * ). Perhatikan bahwa ada ekspresi dengan pointer p1 dan p2, baik dengan dan tanpa dereference operator (*). The meaning of an expression using the dereference operator ( * ) is very different from one that does not: When this operator precedes the pointer name, the expression refers to the value being pointed, while when a pointer name appears without this operator, it refers to the value of the pointer itself (ie the address of what the pointer is pointing to). Yang dimaksud dengan sebuah ekspresi yang menggunakan operator dereference (*) adalah sangat berbeda dari satu yang tidak: Ketika operator ini mendahului nama penunjuk, ekspresi mengacu pada nilai yang menunjuk, sementara ketika muncul nama pointer tanpa operator ini, itu mengacu dengan nilai pointer itu sendiri (yaitu alamat apa pointer menunjuk ke).
Another thing that may call your attention is the line: Hal lain yang boleh memanggil perhatian Anda adalah baris:
|
This declares the two pointers used in the previous example. Ini menyatakan dua pointer yang digunakan dalam contoh sebelumnya. But notice that there is an asterisk (*) for each pointer, in order for both to have type int* (pointer to int ). Tapi perhatikan bahwa ada tanda bintang (*) untuk setiap pointer, agar kedua untuk memiliki tipe int * (pointer ke int).
Otherwise, the type for the second variable declared in that line would have been int (and not int* ) because of precedence relationships. Jika tidak, jenis untuk kedua variabel dinyatakan dalam baris yang akan int (dan tidak int *) karena hubungan didahulukan. If we had written: Jika kita telah menulis:
|
p1 would indeed have int* type, but p2 would have type int (spaces do not matter at all for this purpose). p1 akan memang memiliki int * type, tapi p2 akan tipe int (spasi tidak masalah sama sekali untuk tujuan ini). This is due to operator precedence rules. Hal ini disebabkan oleh operator didahulukan aturan. But anyway, simply remembering that you have to put one asterisk per pointer is enough for most pointer users. Tapi bagaimanapun, hanya mengingat bahwa anda harus meletakkan satu bintang per pointer pointer cukup untuk sebagian besar pengguna.
Pointers and arrays Pointer dan array
The concept of array is very much bound to the one of pointer. Konsep array sangat terikat pada salah satu pointer. In fact, the identifier of an array is equivalent to the address of its first element, as a pointer is equivalent to the address of the first element that it points to, so in fact they are the same concept. Bahkan, pengenal sebuah array adalah setara dengan alamat dari elemen pertama, sebagai pointer setara dengan alamat dari elemen pertama yang poin, jadi pada kenyataannya mereka adalah konsep yang sama. For example, supposing these two declarations: Sebagai contoh, seandainya kedua pernyataan:| 1 1 2 2 | |
The following assignment operation would be valid: Operasi tugas berikut akan berlaku:
|
After that, p and numbers would be equivalent and would have the same properties. Setelah itu, p dan nomor akan sama dan akan memiliki sifat yang sama. The only difference is that we could change the value of pointer p by another one, whereas numbers will always point to the first of the 20 elements of type int with which it was defined. Satu-satunya perbedaan adalah bahwa kita bisa mengubah nilai pointer p dengan yang lain, sedangkan angka-angka akan selalu menunjuk kepada yang pertama dari 20 elemen tipe int dengan yang didefinisikan. Therefore, unlike p , which is an ordinary pointer, numbers is an array, and an array can be considered a constant pointer . Oleh karena itu, tidak seperti p, yang merupakan pointer biasa, angka adalah array, dan sebuah array dapat dianggap sebagai pointer konstan. Therefore, the following allocation would not be valid: Oleh karena itu, alokasi berikut tidak akan berlaku:
|
Because numbers is an array, so it operates as a constant pointer, and we cannot assign values to constants. Karena angka adalah sebuah array, sehingga beroperasi sebagai pointer konstan, dan kita tidak bisa memberikan nilai pada konstanta.
Due to the characteristics of variables, all expressions that include pointers in the following example are perfectly valid: Karena karakteristik variabel, semua ungkapan yang mencakup petunjuk dalam contoh berikut ini secara sempurna sah:
| 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 | | 10, 20, 30, 40, 50, 10, 20, 30, 40, 50, |
In the chapter about arrays we used brackets ( [] ) several times in order to specify the index of an element of the array to which we wanted to refer. Dalam bab mengenai array yang kita gunakan kurung ([]) beberapa kali dalam rangka untuk menentukan indeks dari sebuah elemen dari array yang ingin kita lihat. Well, these bracket sign operators [] are also a dereference operator known as offset operator . Nah, ini tanda braket operator [] juga merupakan operator dereference offset yang dikenal sebagai operator. They dereference the variable they follow just as * does, but they also add the number between brackets to the address being dereferenced. Mereka dereference variabel yang mereka ikuti hanya sebagai * tidak, tetapi mereka juga menambah jumlah antara kurung ke alamat yang dereferenced. For example: Contoh:
| 1 1 2 2 | |
These two expressions are equivalent and valid both if a is a pointer or if a is an array. Kedua ekspresi setara dan berlaku baik jika seorang adalah penunjuk atau jika adalah array.
Pointer initialization Pointer initialization
When declaring pointers we may want to explicitly specify which variable we want them to point to: Ketika mendeklarasikan pointer kita mungkin perlu secara eksplisit menentukan variabel kita ingin mereka agar menunjuk ke:| 1 1 2 2 | |
The behavior of this code is equivalent to: Perilaku kode ini setara dengan:
| 1 1 2 2 3 3 | |
When a pointer initialization takes place we are always assigning the reference value to where the pointer points ( tommy ), never the value being pointed ( *tommy ). Ketika terjadi inisialisasi pointer kita selalu menempatkan nilai referensi ke tempat pointer poin (tommy), tidak pernah nilai yang menunjuk (* tommy). You must consider that at the moment of declaring a pointer, the asterisk ( * ) indicates only that it is a pointer, it is not the dereference operator (although both use the same sign: *). Anda harus mempertimbangkan bahwa pada saat menyatakan pointer, tanda bintang (*) hanya menunjukkan bahwa itu adalah sebuah pointer, itu bukan dereference operator (walaupun keduanya menggunakan tanda yang sama: *). Remember, they are two different functions of one sign. Ingat, mereka adalah dua fungsi yang berbeda satu tanda. Thus, we must take care not to confuse the previous code with: Demikian, kita harus berhati-hati agar tidak membingungkan kode sebelumnya dengan:
| 1 1 2 2 3 3 | |
that is incorrect, and anyway would not have much sense in this case if you think about it. yang tidak benar, lagi pula tidak akan banyak artinya dalam hal ini jika Anda berpikir tentang hal ini.
As in the case of arrays, the compiler allows the special case that we want to initialize the content at which the pointer points with constants at the same moment the pointer is declared: Seperti dalam kasus array, kompilator memungkinkan kasus khusus yang kita ingin menginisialisasi konten di mana poin pointer dengan konstanta pada saat yang sama, pointer menyatakan:
|
In this case, memory space is reserved to contain "hello" and then a pointer to the first character of this memory block is assigned to terry . Dalam kasus ini, disediakan ruang memori berisi "halo" dan kemudian pointer ke karakter pertama blok memori ini ditugaskan untuk terry. If we imagine that "hello" is stored at the memory locations that start at addresses 1702, we can represent the previous declaration as: Jika kita membayangkan bahwa "halo" yang disimpan di lokasi memori alamat yang dimulai pada 1702, kita dapat mewakili deklarasi sebelumnya sebagai:
It is important to indicate that terry contains the value 1702, and not 'h' nor "hello" , although 1702 indeed is the address of both of these. Penting untuk menunjukkan bahwa terry berisi nilai 1702, dan bukan 'h' atau "halo", meskipun memang adalah 1702 alamat kedua.
The pointer terry points to a sequence of characters and can be read as if it was an array (remember that an array is just like a constant pointer). Terry pointer menunjuk ke sebuah rangkaian karakter dan dapat dibaca seolah-olah itu adalah sebuah array (ingat bahwa sebuah array adalah seperti pointer konstan). For example, we can access the fifth element of the array with any of these two expression: Sebagai contoh, kita dapat mengakses kelima elemen dari array dengan salah satu dari dua ekspresi:
| 1 1 2 2 | |
Both expressions have a value of 'o' (the fifth element of the array). Kedua ungkapan memiliki nilai 'o' (elemen kelima dari array).
Pointer arithmetics Pointer arithmetics
To conduct arithmetical operations on pointers is a little different than to conduct them on regular integer data types. Untuk melakukan operasi aritmatika pada pointer adalah sedikit berbeda daripada melakukan mereka pada tipe data integer biasa. To begin with, only addition and subtraction operations are allowed to be conducted with them, the others make no sense in the world of pointers. Untuk mulai dengan, hanya operasi penjumlahan dan pengurangan yang diperbolehkan untuk dilakukan dengan mereka, yang lain tidak masuk akal dalam dunia pointer. But both addition and subtraction have a different behavior with pointers according to the size of the data type to which they point. Tapi keduanya penjumlahan dan pengurangan perilaku yang berbeda dengan petunjuk sesuai dengan ukuran tipe data yang mereka titik.
When we saw the different fundamental data types, we saw that some occupy more or less space than others in the memory. Ketika kami melihat jenis data dasar yang berbeda, kami melihat bahwa beberapa menempati ruang yang lebih atau kurang daripada yang lain dalam memori. For example, let's assume that in a given compiler for a specific machine, char takes 1 byte, short takes 2 bytes and long takes 4. Sebagai contoh, mari kita asumsikan bahwa dalam suatu compiler untuk mesin tertentu, char mengambil 1 byte, pendek memerlukan 2 bytes dan panjang diperlukan 4.
Suppose that we define three pointers in this compiler: Misalkan kita mendefinisikan tiga pointer dalam kompiler ini:
| 1 1 2 2 3 3 | |
and that we know that they point to memory locations 1000 , 2000 and 3000 respectively. dan bahwa kita tahu bahwa mereka menunjuk ke lokasi memori 1000, 2000 dan 3000 masing-masing.
So if we write: Jadi jika kita menulis:
| 1 1 2 2 3 3 | |
mychar , as you may expect, would contain the value 1001 . mychar, seperti yang mungkin Anda harapkan, akan berisi nilai 1001. But not so obviously, myshort would contain the value 2002 , and mylong would contain 3004 , even though they have each been increased only once. Tapi tidak begitu jelas, myshort akan berisi nilai 2002, dan mylong akan berisi 3.004, meskipun mereka memiliki masing-masing telah meningkat hanya sekali. The reason is that when adding one to a pointer we are making it to point to the following element of the same type with which it has been defined, and therefore the size in bytes of the type pointed is added to the pointer. Alasannya adalah bahwa ketika menambahkan satu sampai pointer kita membuat agar menunjuk ke elemen berikut ini dari jenis yang sama dengan yang telah ditentukan, dan karenanya ukuran dalam bytes dari jenis ditambahkan menunjuk ke pointer.
This is applicable both when adding and subtracting any number to a pointer. Hal ini berlaku baik saat menambahkan dan mengurangkan setiap nomor ke pointer. It would happen exactly the same if we write: Hal itu akan terjadi persis sama jika kita menulis:
| 1 1 2 2 3 3 | |
Both the increase ( ++ ) and decrease ( -- ) operators have greater operator precedence than the dereference operator ( * ), but both have a special behavior when used as suffix (the expression is evaluated with the value it had before being increased). Kedua kenaikan (+ +) dan penurunan (-) operator memiliki operator lebih diutamakan daripada dereference operator (*), namun keduanya memiliki perilaku khusus apabila digunakan sebagai sufiks (ekspresi dievaluasi dengan nilai itu sebelum meningkat) . Therefore, the following expression may lead to confusion: Oleh karena itu, ekspresi berikut ini dapat mengakibatkan kebingungan:
|
Because ++ has greater precedence than * , this expression is equivalent to *(p++) . Karena + + memiliki lebih didahulukan daripada *, ungkapan ini setara dengan * (p + +). Therefore, what it does is to increase the value of p (so it now points to the next element), but because ++ is used as postfix the whole expression is evaluated as the value pointed by the original reference (the address the pointer pointed to before being increased). Oleh karena itu, apa yang dilakukannya adalah untuk meningkatkan nilai p (jadi sekarang menunjuk ke elemen berikutnya), tetapi karena + + yang digunakan sebagai ekspresi postfix seluruh dievaluasi sebagai nilai yang ditunjukkan oleh referensi asli (alamat yang menunjuk pointer untuk sebelum meningkat).
Notice the difference with: Perhatikan perbedaan dengan:
(*p)++ (* p) + +
Here, the expression would have been evaluated as the value pointed by p increased by one. Di sini, ekspresi akan dievaluasi sebagai nilai yang ditunjukkan oleh p bertambah satu. The value of p (the pointer itself) would not be modified (what is being modified is what it is being pointed to by this pointer). Nilai p (pointer itu sendiri) tidak akan diubah (apa yang diubah adalah apa yang sedang ditunjuk oleh pointer ini).
If we write: Jika kita menulis:
|
Because ++ has a higher precedence than * , both p and q are increased, but because both increase operators ( ++ ) are used as postfix and not prefix, the value assigned to *p is *q before both p and q are increased. Karena + + memiliki prioritas lebih tinggi dibandingkan *, baik p dan q meningkat, tetapi karena keduanya meningkatkan operator (+ +) digunakan sebagai postfix dan bukan awalan, nilai yang diberikan untuk * p * q sebelum kedua p dan q meningkat . And then both are increased. Dan kemudian keduanya meningkat. It would be roughly equivalent to: Ini akan menjadi kasar setara dengan:
| 1 1 2 2 3 3 | |
Like always, I recommend you to use parentheses () in order to avoid unexpected results and to give more legibility to the code. Seperti biasa, saya sarankan Anda untuk menggunakan tanda kurung () dalam rangka untuk menghindari hasil yang tidak diharapkan dan untuk memberi lebih banyak keterbacaan ke kode.
Pointers to pointers Pointer ke pointer
C++ allows the use of pointers that point to pointers, that these, in its turn, point to data (or even to other pointers). C + + memungkinkan penggunaan pointer yang mengarah ke pointer, bahwa ini, pada gilirannya, arahkan ke data (atau bahkan pointer lain). In order to do that, we only need to add an asterisk ( * ) for each level of reference in their declarations: Untuk melakukan itu, kita hanya perlu menambahkan tanda bintang (*) untuk tiap tingkat acuan dalam deklarasi:| 1 1 2 2 3 3 4 4 5 5 6 6 | |
This, supposing the randomly chosen memory locations for each variable of 7230 , 8092 and 10502 , could be represented as: Ini, seandainya yang dipilih secara acak lokasi memori untuk setiap variabel dari 7.230, 8092 dan 10.502, dapat digambarkan sebagai:
The value of each variable is written inside each cell; under the cells are their respective addresses in memory. Nilai setiap variabel yang tertulis di dalam setiap sel; di bawah sel masing-masing alamat di memori.
The new thing in this example is variable c , which can be used in three different levels of indirection, each one of them would correspond to a different value: Hal baru dalam contoh ini adalah variabel c, yang dapat digunakan dalam tiga tingkat yang berbeda tipuan, masing-masing dari mereka akan sesuai dengan nilai yang berbeda:
- c has type char** and a value of 8092 c memiliki tipe char ** dan nilai 8.092
- *c has type char* and a value of 7230 * c memiliki tipe char * dan nilai 7.230
- **c has type char and a value of 'z' ** c memiliki tipe char dan nilai 'z'
void pointers void pointer
The void type of pointer is a special type of pointer. Jenis kekosongan pointer tipe khusus pointer. In C++, void represents the absence of type, so void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereference properties). Dalam C + +, void mewakili ketiadaan jenis, jadi void pointer pointer yang mengarah ke sebuah nilai yang tidak memiliki tipe (dan dengan demikian juga yang belum ditentukan dan belum ditentukan dereference panjang properti).This allows void pointers to point to any data type, from an integer value or a float to a string of characters. Hal ini memungkinkan void pointer untuk menunjuk pada satu jenis data, dari nilai integer atau float ke string karakter. But in exchange they have a great limitation: the data pointed by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason we will always have to cast the address in the void pointer to some other pointer type that points to a concrete data type before dereferencing it. Tapi sebagai gantinya mereka sangat terbatas: data ditunjukkan oleh mereka tidak dapat secara langsung dereferenced (yang logis, karena kita tidak memiliki tipe dereference ke), dan karena alasan itu kita akan selalu harus membuang alamat dalam kekosongan pointer ke tipe pointer lain yang menunjuk ke suatu tipe data konkret sebelum dereferencing itu.
One of its uses may be to pass generic parameters to a function: Salah satu kegunaannya dapat melewati parameter generik ke fungsi:
| 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 | | y, 1603 y, 1603 |
sizeof is an operator integrated in the C++ language that returns the size in bytes of its parameter. sizeof adalah operator terintegrasi di C + + bahasa yang mengembalikan ukuran byte dari parameter. For non-dynamic data types this value is a constant. Non-tipe data dinamis nilai ini adalah sebuah konstanta. Therefore, for example, sizeof(char) is 1 , because char type is one byte long. Oleh karena itu, misalnya, sizeof (char) adalah 1, karena tipe char satu byte lama.
Null pointer Null pointer
A null pointer is a regular pointer of any pointer type which has a special value that indicates that it is not pointing to any valid reference or memory address. Sebuah pointer null pointer biasa dari setiap tipe pointer yang memiliki nilai khusus yang menunjukkan bahwa tidak menunjuk referensi yang valid atau alamat memori. This value is the result of type-casting the integer value zero to any pointer type. Nilai ini adalah hasil dari jenis-menebar nilai integer nol untuk semua tipe pointer.| 1 1 2 2 | |
Do not confuse null pointers with void pointers. Jangan bingung null pointer dengan void pointer. A null pointer is a value that any pointer may take to represent that it is pointing to "nowhere", while a void pointer is a special type of pointer that can point to somewhere without a specific type. Sebuah pointer nol adalah nilai bahwa setiap pointer mungkin diperlukan untuk menyatakan bahwa itu menunjuk ke "nowhere", sementara pointer void merupakan tipe khusus pointer yang dapat menunjuk ke suatu tempat tanpa jenis tertentu. One refers to the value stored in the pointer itself and the other to the type of data it points to. Satu mengacu pada nilai yang disimpan dalam pointer itu sendiri dan yang lain untuk jenis data yang menunjuk ke.
Pointers to functions Pointer ke fungsi
C++ allows operations with pointers to functions. C + + memperbolehkan operasi dengan pointer ke fungsi. The typical use of this is for passing a function as an argument to another function, since these cannot be passed dereferenced. Penggunaan yang khas ini untuk melewati sebuah fungsi sebagai argumen ke fungsi lain, karena ini tidak dapat melewati dereferenced. In order to declare a pointer to a function we have to declare it like the prototype of the function except that the name of the function is enclosed between parentheses () and an asterisk ( * ) is inserted before the name: Dalam rangka untuk mendeklarasikan pointer ke salah satu fungsi kita harus menyatakan hal itu seperti prototipe dari fungsi kecuali bahwa nama fungsi tertutup antara tanda kurung () dan tanda bintang (*) dimasukkan sebelum nama:| 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 | | 8 8 |
In the example, minus is a pointer to a function that has two parameters of type int . Dalam contoh, dikurangi adalah pointer ke fungsi yang memiliki dua parameter bertipe int. It is immediately assigned to point to the function subtraction , all in a single line: Hal ini segera ditugaskan untuk menunjuk ke fungsi pengurangan, semua dalam satu baris:
|
| Character Sequences Karakter Sequences | index indeks | Dynamic Memory Dynamic Memory |

Tidak ada komentar:
Posting Komentar