Perkenalan

Perkenalan

Kami telah mencapai titik penting dalam serangkaian artikel kami tentang pengembangan C. Itu juga, bukan kebetulan, bagian C yang memberikan banyak sakit kepala bagi pemula. Di sinilah kita masuk, dan tujuan artikel ini (salah satunya, bagaimanapun), adalah untuk membantah mitos tentang pointer dan tentang C sebagai bahasa yang keras/mustahil untuk dipelajari dan dibaca. Meskipun demikian, kami merekomendasikan peningkatan perhatian dan sedikit kesabaran dan Anda akan melihat bahwa pointer tidak seberkas pikiran seperti yang dikatakan legenda.

Definisi dan peringatan

Tampaknya masuk akal dan sehat bahwa kita harus mulai dengan peringatan, dan kami dengan sungguh -sungguh menyarankan Anda mengingatnya: sementara pointer menjadikan hidup Anda sebagai pengembang C lebih mudah, mereka juga Bisa memperkenalkan bug yang sulit ditemukan dan kode yang tidak dapat dipahami. Anda akan melihat, jika Anda terus membaca, apa yang sedang kita bicarakan dan keseriusan bug tersebut, tetapi intinya, seperti yang dikatakan sebelumnya, berhati -hatilah.

Definisi sederhana dari pointer adalah "variabel yang nilainya adalah alamat variabel lain". Anda mungkin tahu bahwa sistem operasi berurusan dengan alamat saat menyimpan nilai, sama seperti Anda akan memberi label pada gudang sehingga Anda memiliki cara mudah untuk menemukannya saat dibutuhkan. Di sisi lain, array dapat didefinisikan sebagai kumpulan item yang diidentifikasi oleh indeks. Anda akan melihat nanti mengapa pointer dan array biasanya disajikan bersama, dan bagaimana menjadi efisien dalam C menggunakannya. Jika Anda memiliki latar belakang dalam bahasa tingkat tinggi lainnya, Anda terbiasa dengan tipe data string. Dalam C, array adalah setara dengan variabel yang diketik string, dan dikatakan bahwa pendekatan ini lebih efisien.



Pointer

Anda telah melihat definisi pointer, sekarang mari kita mulai dengan beberapa penjelasan mendalam dan, tentu saja, contoh. Pertanyaan pertama yang mungkin Anda tanyakan pada diri sendiri adalah “mengapa saya harus menggunakan pointer?". Meskipun saya mungkin terbakar karena perbandingan ini, saya akan mengambil peluang saya: apakah Anda menggunakan symlink di sistem Linux Anda? Bahkan jika Anda belum membuat sendiri, sistem Anda Ufses mereka dan itu membuat pekerjaan lebih efisien. Saya telah mendengar beberapa cerita horor tentang pengembang C senior yang bersumpah mereka tidak pernah menggunakan petunjuk karena mereka "rumit", tetapi itu hanya berarti pengembang tidak kompeten, tidak lebih. Plus, ada situasi di mana Anda harus menggunakan pointer, jadi mereka tidak boleh diperlakukan sebagai opsional, karena tidak. Seperti sebelumnya, saya percaya pada belajar dengan contoh, jadi begini:

int x, y, z; x = 1; y = 2; int *ptoi; /* ptoi adalah, dan singkatan dari, pointer ke integer*/ ptOi = & x; / * PTOI menunjuk ke x */ z = *ptoi; / * z sekarang 1, nilai X, ke arah poin PTOI */ ptOi = & y; / *ptoi sekarang menunjuk ke y */

Jika Anda menggaruk kepala dalam kebingungan, jangan lari: itu hanya menyakitkan pertama kali, Anda tahu. Ayo pergi baris demi baris dan lihat apa yang kami lakukan di sini. Kami pertama -tama menyatakan tiga bilangan bulat, itu masing -masing x, y dan z, dan memberikan nilai x dan y 1 dan 2. Ini adalah bagian yang sederhana. Elemen baru disertai dengan deklarasi variabel PTOI, yang merupakan a penunjuk ke bilangan bulat, sehingga poin menuju bilangan bulat. Ini dicapai dengan menggunakan tanda bintang sebelum nama variabel dan dikatakan sebagai operator pengalihan. Garis 'ptoi = & x;' berarti “PTOI sekarang menunjuk ke arah X, yang harus menjadi bilangan bulat, sesuai dengan deklarasi PTOI di atas”. Anda sekarang dapat bekerja dengan PTOI seperti yang Anda lakukan dengan X (yah, hampir). Mengetahui hal ini, baris berikutnya adalah setara dengan 'z = x;'. Selanjutnya kita Dereferensi ptoi, artinya kita mengatakan "berhenti menunjuk ke x dan mulai menunjuk ke y". Satu pengamatan penting diperlukan di sini: operator & hanya dapat digunakan pada objek residen memori, mereka menjadi variabel (kecuali register [1]) dan elemen array.

[1] Variabel tipe register adalah salah satu elemen C yang ada, tetapi mayoritas pemrogram menghindari mereka. Variabel dengan kata kunci ini terlampir menyarankan kepada kompiler yang akan sering digunakan dan harus disimpan dalam daftar prosesor untuk akses yang lebih cepat. Sebagian besar kompiler modern mengabaikan petunjuk ini dan memutuskan sendiri, jadi jika Anda tidak yakin perlu mendaftar, Anda tidak.

Kami mengatakan bahwa PTOI harus menunjuk ke bilangan bulat. Bagaimana kita harus melanjutkan jika kita menginginkan penunjuk generik, jadi kita tidak perlu khawatir tentang tipe data? Masukkan pointer untuk membatalkan. Ini semua yang akan kami katakan kepada Anda, dan tugas pertama adalah untuk mencari tahu apa kegunaan yang dapat dimiliki oleh pointer untuk void dan apa batasannya.



Array

Anda akan melihat dalam sub-bab ini mengapa kami bersikeras menyajikan pointer dan array dalam satu artikel, meskipun ada risiko berlebihan otak pembaca. Senang mengetahui bahwa, saat bekerja dengan array, Anda tidak perlu menggunakan pointer, tetapi senang melakukannya, karena operasi akan lebih cepat, dengan penurunan kode yang kurang dapat dipahami. Deklarasi Array memiliki hasil dari mendeklarasikan sejumlah elemen berturut -turut yang tersedia melalui indeks, seperti demikian:

int a [5]; int x; A [2] = 2; x = a [2];

A adalah array 5-elemen, dengan elemen ketiga menjadi 2 (penomoran indeks dimulai dengan nol!), dan x didefinisikan juga 2. Banyak bug dan kesalahan saat pertama kali berurusan dengan array adalah orang lupa masalah 0-indeks. Ketika kami mengatakan "elemen berturut -turut" yang kami maksudkan adalah dijamin bahwa elemen array memiliki lokasi berturut -turut dalam memori, bukan bahwa jika [2] adalah 2, maka [3] adalah 3. Ada struktur data di C yang disebut enum yang melakukan itu, tetapi kami belum akan menghadapinya dulu. Saya menemukan beberapa program lama yang saya tulis saat belajar C, dengan bantuan dari teman saya Google, yang membalikkan karakter dalam sebuah string. Ini dia:

#include #include int main () char stringy [30]; int i; Char C; printf ("Ketikkan string .\ n "); fgets (stringy, 30, stdin); printf (" \ n "); untuk(i = 0; i < strlen(stringy); i++) printf("%c", stringy[i]); printf("\n"); untuk(i = strlen (stringy); i> = 0; i--) printf ("%c", stringy [i]); printf ("\ n"); kembali 0;  

Ini adalah salah satu cara melakukan ini tanpa menggunakan pointer. Ini memiliki kekurangan dalam banyak hal, tetapi menggambarkan hubungan antara string dan array. Stringy adalah array 30 karakter yang akan digunakan untuk menahan input pengguna, saya akan menjadi indeks array dan c akan menjadi karakter individu yang akan dikerjakan. Jadi kami meminta string, kami menyimpannya ke array menggunakan fget, mencetak string asli dengan mulai dari stringy [0] dan berlangsung, menggunakan loop secara bertahap, sampai string berakhir. Operasi terbalik memberikan hasil yang diinginkan: kami kembali mendapatkan panjang string dengan strlen () dan memulai hitung mundur 'til nol lalu cetak karakter string demi karakter. Aspek penting lainnya adalah bahwa array karakter apa pun di C diakhiri dengan karakter nol, diwakili secara grafis oleh '\ 0'.

Bagaimana kita melakukan semua ini menggunakan pointer? Jangan tergoda untuk mengganti array dengan pointer ke char, itu tidak akan berhasil. Sebaliknya, gunakan alat yang tepat untuk pekerjaan itu. Untuk program interaktif seperti yang di atas, gunakan array karakter dengan panjang tetap, dikombinasikan dengan fungsi aman seperti fgets (), jadi Anda tidak akan digigit oleh luapan buffer. Untuk konstanta string, Anda dapat menggunakan

char * myname = "David";

Dan kemudian, menggunakan fungsi yang disediakan untuk Anda dalam string.h, memanipulasi data sesuai keinginan Anda. Ngomong -ngomong, fungsi apa yang akan Anda pilih untuk menambahkan nama myN ke string yang membahas pengguna? Misalnya, alih -alih "Harap masukkan nomor" Anda harus memiliki "David, silakan masukkan nomor".



Pointer dan Array

Anda dapat, dan didorong untuk, menggunakan array bersama dengan pointer, meskipun pada awalnya Anda mungkin terkejut karena sintaksis. Secara umum, Anda dapat melakukan apa saja yang terkait dengan array dengan pointer, dengan keuntungan kecepatan di sisi Anda. Anda mungkin berpikir bahwa dengan perangkat keras saat ini, menggunakan pointer dengan array hanya untuk mendapatkan kecepatan tidak sepadan. Namun, ketika program Anda tumbuh dalam ukuran dan kompleksitas, perbedaan tersebut akan mulai lebih jelas, dan jika Anda pernah berpikir untuk porting aplikasi Anda ke beberapa platform tertanam, Anda akan memberi selamat kepada diri sendiri. Sebenarnya, jika Anda mengerti apa yang dikatakan sampai saat ini, Anda tidak akan memiliki alasan untuk terkejut. Katakanlah kami memiliki berbagai bilangan bulat dan kami ingin menyatakan pointer ke salah satu elemen array. Kode akan terlihat seperti ini:

int myarray [10]; int *myptr; int x; myptr = & myarray [0]; x = *myptr;

Jadi, kami memiliki array bernama myarray, yang terdiri dari sepuluh bilangan bulat, pointer ke bilangan bulat, yang mendapatkan alamat elemen pertama array, dan x, yang mendapatkan nilai elemen pertama tersebut melalui Pointer. Sekarang Anda dapat melakukan segala macam trik bagus untuk bergerak melalui array, seperti

*(myptr + 1);

yang akan menunjuk ke arah elemen myarray berikutnya, yaitu myarray [1].

Satu hal penting untuk diketahui, dan pada saat yang sama yang menggambarkan hubungan antara pointer dan array, adalah bahwa nilai objek tipe array adalah alamat elemen 'pertama (nol), jadi jika myptr = & myarray [ 0], lalu myptr = myArray. Sebagai sedikit latihan, kami mengundang Anda untuk mempelajari hubungan ini sedikit dan membuat kode beberapa situasi di mana Anda pikir itu akan/bisa berguna. Inilah yang akan Anda temui sebagai aritmatika pointer.

Pertimbangan tentang string di C dan panggilan

Sebelum kami melihat bahwa Anda dapat melakukan keduanya

char *mystring; myString = "Ini adalah string."

atau Anda dapat melakukan hal yang sama dengan menggunakan

char mystring [] = "Ini adalah string.";

Dalam kasus kedua, seperti yang mungkin telah Anda simpulkan, myString adalah array yang cukup besar untuk menahan data yang dikaitkan dengan itu. Perbedaannya adalah bahwa dengan menggunakan array Anda dapat beroperasi pada karakter individu di dalam string, saat menggunakan pendekatan pointer Anda tidak bisa. Ini adalah masalah yang sangat penting untuk diingat bahwa akan menyelamatkan Anda dari kompiler yang memiliki pria besar yang datang ke rumah Anda dan melakukan hal -hal buruk kepada nenek Anda. Melangkah lebih jauh, masalah lain yang harus Anda ketahui adalah bahwa jika Anda lupa tentang pointer, panggilan di C dibuat dengan nilai. Jadi ketika suatu fungsi membutuhkan sesuatu dari suatu variabel, salinan lokal dibuat dan pekerjaan dilakukan untuk itu. Tetapi jika fungsi mengubah variabel, perubahan tidak tercermin, karena aslinya tetap utuh. Dengan menggunakan pointer, Anda dapat menggunakan panggilan dengan referensi, Seperti yang akan Anda lihat dalam contoh kami di bawah ini. Juga, panggilan berdasarkan nilai mungkin menjadi sumber daya yang intensif jika objek yang sedang dikerjakan besar. Secara teknis, ada juga panggilan oleh pointer, tapi mari kita tetap sederhana untuk saat ini.

Katakanlah kami ingin menulis fungsi yang mengambil bilangan bulat sebagai argumen dan menambahnya dengan beberapa nilai. Anda mungkin akan tergoda untuk menulis sesuatu seperti ini:

void incr (int a) a+= 20; 

Sekarang jika Anda mencoba ini, Anda akan melihat bahwa bilangan bulat tidak akan bertambah, karena hanya salinan lokal. Jika Anda akan menulis

void incr (int & a) a+= 20; 

Argumen integer Anda akan bertambah dengan dua puluh, itulah yang Anda inginkan. Jadi jika Anda masih memiliki beberapa keraguan tentang kegunaan pointer, inilah satu contoh sederhana namun signifikan.



Topik yang agak canggih

Kami berpikir untuk meletakkan topik-topik ini di bagian khusus karena mereka sedikit lebih sulit untuk dipahami bagi pemula, tetapi berguna, harus tahu bagian dari pemrograman C. Jadi…

Pointer ke pointer

Ya, pointer adalah variabel sama seperti yang lain, sehingga mereka dapat memiliki variabel lain yang menunjuk kepada mereka. Sementara pointer sederhana seperti yang terlihat di atas memiliki satu tingkat "menunjuk", pointer ke pointer memiliki dua, jadi variabel seperti itu menunjuk ke yang lain yang menunjuk ke yang lain. Anda pikir ini menjengkelkan? Anda dapat memiliki pointer ke pointer ke pointer ke pointer ke .. .ad infinitum, tetapi Anda sudah melintasi ambang kewarasan dan kegunaan jika Anda mendapatkan deklarasi seperti itu. Kami merekomendasikan penggunaan cDecl, yang merupakan program kecil yang biasanya tersedia di sebagian besar distro linux yang “menerjemahkan” antara C dan C ++ dan bahasa Inggris dan sebaliknya dan sebaliknya. Jadi, pointer ke pointer dapat dinyatakan sebagai

int ** ptrtoptr;

Sekarang, sesuai bagaimana petunjuk multi-level digunakan, ada situasi ketika Anda memiliki fungsi, seperti perbandingan di atas, dan Anda ingin mendapatkan pointer dari mereka sebagai nilai pengembalian. Anda juga mungkin menginginkan serangkaian string, yang merupakan fitur yang sangat berguna, seperti yang akan Anda lihat dalam kemauan.

Array multi-dimensi

Array yang telah Anda lihat sejauh ini tidak ada artinya, tetapi itu tidak berarti Anda terbatas pada itu. Misalnya, array bi-dimensi dapat dibayangkan dalam pikiran Anda sebagai array array. Saran saya adalah menggunakan array multi-dimensi jika Anda merasa perlu, tetapi jika Anda baik dengan yang sederhana dan bagus, tidak ada yang tidak ada, gunakan itu sehingga hidup Anda sebagai pembuat kode akan lebih sederhana. Untuk mendeklarasikan array bi-dimensi (kami menggunakan dua dimensi di sini, tetapi Anda tidak terbatas pada angka itu), Anda akan melakukannya

 int Bidimarray [4] [2];

yang akan memiliki efek menyatakan array integer 4-by-2. Untuk mengakses elemen kedua secara vertikal (pikirkan teka -teki silang jika itu membantu!) dan yang pertama secara horizontal, Anda dapat melakukannya

Bidimarray [2] [1];

Ingatlah bahwa dimensi ini hanya untuk mata kita: kompiler mengalokasikan memori dan bekerja dengan array dengan cara yang sama, jadi jika Anda tidak melihat utilitas ini, jangan gunakan itu. Ergo, array kami di atas dapat dinyatakan sebagai

int Bidimarray [8]; / * 4 kali 2, seperti yang dikatakan */


Argumen baris perintah

Dalam angsuran kami sebelumnya dari seri ini, kami berbicara tentang Main dan bagaimana hal itu dapat digunakan dengan atau tanpa argumen. Ketika program Anda membutuhkannya dan Anda memiliki argumen, mereka adalah char argc dan char *argv []. Sekarang Anda tahu apa itu array dan pointer, hal -hal mulai masuk akal. Namun, kami berpikir untuk mendapatkan sedikit detail di sini. char *argv [] dapat ditulis sebagai char ** argv juga. Sebagai beberapa makanan untuk dipikirkan, mengapa menurut Anda itu mungkin? Harap diingat bahwa Argv adalah singkatan dari "Argumen Vektor" dan merupakan serangkaian string. Selalu Anda dapat mengandalkan fakta bahwa Argv [0] adalah nama program itu sendiri, sedangkan Argv [1] adalah argumen pertama dan sebagainya. Jadi program singkat untuk melihat nama 'dan argumennya akan terlihat seperti ini:

#include #include int main (int argc, char ** argv)  ketika(argc--) printf ("%s \ n", *argv ++); kembali 0; 

Kesimpulan

Kami memilih bagian -bagian yang tampak paling penting untuk memahami pointer dan array, dan sengaja meninggalkan beberapa subjek seperti pointer untuk fungsi. Meskipun demikian, jika Anda bekerja dengan informasi yang disajikan di sini dan menyelesaikan latihan, Anda akan memiliki awal yang cukup baik pada bagian C yang dianggap sebagai sumber utama kode yang rumit dan tidak dapat dipahami.

Berikut adalah referensi yang sangat baik tentang pointer C ++. Meskipun bukan C, bahasa tersebut terkait, jadi artikel ini akan membantu Anda lebih memahami petunjuk.

Inilah yang dapat Anda harapkan selanjutnya:

  • SAYA. C Perkembangan di Linux - Pendahuluan
  • Ii. Perbandingan antara C dan bahasa pemrograman lainnya
  • AKU AKU AKU. Jenis, Operator, Variabel
  • Iv. Alur kontrol
  • V. Fungsi
  • Vi. Pointer dan Array
  • Vii. Struktur
  • Viii. I/O Dasar
  • Ix. Gaya pengkodean dan rekomendasi
  • X. Membangun program
  • Xi. Kemasan untuk Debian dan Fedora
  • Xii. Mendapatkan paket di repositori resmi Debian

Tutorial Linux Terkait:

  • Pengantar Otomatisasi Linux, Alat dan Teknik
  • Hal -hal yang harus diinstal pada ubuntu 20.04
  • Menguasai loop skrip bash
  • Loop bersarang dalam skrip bash
  • Mint 20: Lebih baik dari Ubuntu dan Microsoft Windows?
  • Manipulasi data besar untuk kesenangan dan keuntungan bagian 1
  • Hal -hal yang harus dilakukan setelah menginstal ubuntu 20.04 FOSSA FOSSA Linux
  • Tutorial debugging GDB untuk pemula
  • Pencatatan dan audit lanjutan di Linux
  • Seberapa sering Anda harus me -reboot server linux Anda?