Keragaman Budaya Indonesia 5 Provinsi - Indonesia sangatlah kaya dengan keaneka ragaman istiadat pun budaya, tentu saja hal tersebut disebabkan oleh distrik Indonesia yang berbentuk kepulauan sehingga meningkatkan kekayaan dan keanekaragaman kebiasaan masing-masing pulau. Bahkan guna satu pulau ada bermacam-macam atau keanekaragaman kebiasaan pada masing-masing provinsi. Perbedaan kebiasaan dapat disaksikan dari adanya lokasi tinggal adat, pakaian adat, tarian tradisional, senjata tradisional, lagu daerah, suku wilayah dan sejumlah julukan pada 5 provinsi, bahkan sejumlah provinsi mempunyai lebih dari satu macam lokasi tinggal adat sebab pengaruh dari adanya suku yang beraneka aneka yang bermukim pada satu provinsi. Berikut ini kami tuliskan mengenai rumah tinggal adat, pakaian adat, tarian tradisional, senjata tradisional, lagu daerah, suku wilayah dan julukan pada 5 provinsi yang terdapat di Indonesia. 1. Provinsi Jawa Barat (JABAR) Ibukota ...
Pengenalan Tutorial
Mari kita mulai dengan pengenalan cepat di C. Tujuan kami adalah untuk menunjukkan unsur-unsur penting dari bahasa dalam program-program nyata, tetapi tanpa terhenti dalam rincian, peraturan, dan pengecualian. Pada titik ini, kita tidak mencoba untuk menjadi lengkap atau bahkan tepat (kecuali bahwa contoh adalah dimaksudkan untuk menjadi benar). Kami ingin mendapatkan Anda secepat mungkin ke titik di mana Anda dapat menulis program yang berguna, dan untuk itu kita harus berkonsentrasi pada dasar-dasar: variabel dan konstanta, aritmatika, aliran kontrol, fungsi, dan dasar-dasar input dan output. Kami sengaja meninggalkan keluar dari ini fitur bab C yang penting untuk menulis lebih besar program. Ini termasuk pointer, struktur, sebagian besar set kaya C dari operator, beberapa controlflow pernyataan, dan perpustakaan standar.
Pendekatan ini dan kekurangannya. Paling penting adalah bahwa cerita lengkap pada setiap tertentu fitur tidak ditemukan di sini, dan tutorial, dengan menjadi singkat, mungkin juga menyesatkan. Dan karena contoh tidak menggunakan kekuatan penuh dari C, mereka tidak ringkas dan elegan seperti mereka mungkin menjadi. Kami telah mencoba untuk meminimalkan efek ini, tetapi memperingatkan. Kelemahan lain adalah bahwa nanti bab tentu akan mengulang beberapa bab ini. Kami berharap bahwa pengulangan akan membantu Anda lebih dari itu mengganggu.
Dalam kasus apapun, programmer berpengalaman harus mampu ekstrapolasi dari materi dalam hal ini bab dengan kebutuhan program mereka sendiri. Pemula harus melengkapi dengan menulis kecil, program serupa dari mereka sendiri. Kedua kelompok dapat menggunakannya sebagai kerangka di mana untuk menggantung deskripsi yang lebih rinci yang dimulai pada Bab 2.
Memulai
Satu-satunya cara untuk belajar bahasa pemrograman baru adalah dengan menulisprogram di dalamnya. Pertama Program untuk menulis adalah sama untuk semua bahasa:
Cetak kata-kata
hello, world
Ini adalah rintangan besar, untuk melompati itu Anda harus mampu menciptakan teks program di suatu tempat, compile berhasil, beban itu, menjalankannya, dan mencari tahu di mana output pergi. Dengan rincian mekanik menguasai, segala sesuatu yang lain relatif mudah.
Dalam C, program untuk mencetak ``hello, world’’ is
#include
main()
{
printf("hello, world\n");
}
Hanya bagaimana untuk menjalankan program ini tergantung pada sistem yang Anda gunakan. Sebagai contoh spesifik, pada sistem operasi UNIX Anda harus membuat program dalam sebuah file yang namanya berakhiran ``.c’’, seperti hello.c, kemudian compile dengan perintahcc
hello.c
Jika Anda belum dirusak apa-apa, seperti menghilangkan karakter atau salah mengeja sesuatu, yang kompilasi akan melanjutkan diam-diam, dan membuat sebuah file eksekusi bernama a.out. Jika Anda menjalankan a.out dengan mengetikkan perintah
a.out
akan mencetak
hello, world
Pada sistem lain, aturan akan berbeda, periksa dengan ahli lokal. Sekarang, untuk beberapa penjelasan tentang program itu sendiri. Sebuah program C, apapun ukurannya, terdiri fungsi dan variabel. Sebuah fungsi berisi pernyataan yang menentukan komputasi operasi yang harus dilakukan, dan nilai-nilai variabel store digunakan selama perhitungan. Fungsi C seperti subrutin dan fungsi dalam Fortran atau prosedur dan fungsi Pascal. Kami contoh adalah fungsi bernama main. Normally you are at liberty to give functions whatever names you like, but ``main'' khusus - program anda mulai mengeksekusi pada awal utama. Ini berarti bahwa setiap program harus memiliki main di suatu tempat.
Main will usually call other functions to help perform its job, some that you wrote, and others from libraries that are provided for you. The first line of the program,
#include
mengatakan kepada kompiler untuk menyertakan informasi tentang standar perpustakaan input / output; baris muncul pada awal banyak file sumber C. Perpustakaan standar dijelaskan dalam Bab 7 dan Lampiran B.
Salah satu metode komunikasi data antara fungsi adalah untuk fungsi panggilan untuk memberikan daftar nilai, disebut argumen, dengan fungsi itu panggilan. Tanda kurung setelah nama fungsi mengelilingi daftar argumen. Dalam contoh ini, main didefinisikan sebagai fungsi yang mengharapkan tidak ada argumen, yang ditunjukkan dengan daftar kosong ( ).
#include
termasuk informasi tentang standar Library
Main() mendefinisikan sebuah fungsi yang di
Sebut “main” yang tidak menerima nilai
Nilai argumen
{ laporan main diapit oleh kurung
printf("hello, world\n"); main memanggil fungsi library printf
untuk mencetak urutan karakter
}\ n mewakili karakter baris baru
Program C pertama
Laporan dari fungsi diapit oleh kurung {}. Fungsi main hanya berisi satu pernyataan,
printf(”hello, world\n”);
Sebuah fungsi disebut dengan penamaan itu, diikuti dengan daftar kurung argumen, sehingga panggilan ini fungsi printf dengan argumen “hello, world\n”. Printf adalah fungsi library yang mencetak output, dalam hal ini string karakter antara tanda kutip.
Sebuah urutan karakter dalam tanda kutip ganda, seperti “hello, world\n”, disebut karakter string atau konstanta string. Untuk saat ini kita gunakan hanya karakter string akan sebagai argumen untuk printf dan fungsi lainnya.
Urutan \n dalam string adalah notasi C untuk karakter baris baru, yang bila dicetak kemajuan output ke margin kiri pada baris berikutnya. Jika Anda meninggalkan keluar in the string is C notation for the newline character, which when printed advances the output to the left margin on the next line. If you leave out the \n (percobaan berharga), Anda akan menemukan bahwa tidak ada garis muka setelah output dicetak. Anda harus menggunakan \n untuk memasukkan karakter baris baru di printf argumen, jika Anda mencoba sesuatu seperti,
printf(”hello, world”);
compiler C akan menghasilkan pesan kesalahan.
Printf tidak pernah memasok karakter baris baru secara otomatis, sehingga beberapa panggilan dapat digunakan untuk membangun sebuah jalur output secara bertahap. Program pertama kami bisa juga ditulis
#include
main()
{
printf("hello, ");
printf("world");
printf("\n");
}
untuk menghasilkan output yang identik.
Perhatikan bahwa \n hanya mewakili satu karakter. Sebuah urutan escape seperti \n menyediakan mekanisme umum dan extensible untuk mewakili sulit tipe atau karakter tak terlihat. Di antara lain bahwa C menyediakan adalah \t untuk tab, \b backspace untuk, \ "untuk kutipan ganda dan \ \ untuk backslash itu sendiri.
latihan 1-1 Jalankan ``hello, world'' Program pada sistem Anda. Percobaan dengan meninggalkan keluar bagian dari program, untuk melihat apa pesan kesalahan yang Anda dapatkan.
Latihan 1-2 Percobaan untuk mencari tahu apa yang terjadi ketika prints's argumen string mengandung \ c, di mana c adalah beberapa karakter tidak tercantum di atas.
Variabel dan Aritmatika Ekspresi
Program berikutnya menggunakan rumus oC = (5/9) (oF-32) untuk mencetak tabel berikut suhu Fahrenheit dan Celcius atau setara Celcius mereka:
1 -17
20 -6
40 4
60 15
80 26
100 37
120 48
140 60
160 71
180 82
200 93
220 104
240 115
260 126
280 137
300 148
Program itu sendiri masih terdiri dari definisi fungsi tunggal bernama main. Hal ini lebih lama daripada yang dicetak ``hello, world'', tapi tidak rumit. Hal ini memperkenalkan beberapa ide-ide baru, termasuk komentar, deklarasi, variabel, ekspresi aritmatika, loop, dan output diformat.
#include
/* mencetak tabel Fahrenheit-Celsius
for fahr = 0, 20, ..., 300 */
main()
{
int fahr, celsius;
int lower, upper, step;
lower = 0; /* batas bawah skala suhu */
upper = 300; /* batas atas */
step = 20; /* ukuran langkah */
fahr = lower;
while (fahr <= upper) {
celsius = 5 * (fahr-32) / 9;
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
}
Dua baris
/* mencetak tabel Fahrenheit-Celsius
for fahr = 0, 20, ..., 300 */
adalah komentar, yang dalam hal ini menjelaskan secara singkat apa program tidak. Setiap karakter antara / * dan * / diabaikan oleh compiler, mereka dapat digunakan secara bebas untuk membuat program lebih mudah untuk memahami. Komentar dapat muncul di mana saja di mana kosong, tab atau baris baru bisa.
Dalam C, semua variabel harus dideklarasikan sebelum mereka digunakan, biasanya pada awal fungsi sebelum pernyataan dieksekusi. Sebuah deklarasi mengumumkan sifat variabel, terdiri dari nama dan daftar variabel, seperti
int fahr, celsius;
int lower, upper, step;
Jenis yang int berarti bahwa variabel yang tercantum adalah bilangan bulat, sebaliknya dengan float, yang berarti floating point, yaitu, angka yang mungkin memiliki bagian pecahan. Kisaran kedua int dan float tergantung pada mesin yang Anda gunakan, 16-bit ints, yang terletak antara -32768 dan 32767, yang umum, seperti 32-bit ints. Sejumlah float biasanya kuantitas 32-bit, dengan setidaknya enam angka signifikan dan besarnya umumnya antara sekitar 10-38 dan 1038.
C menyediakan beberapa tipe data lain selain int and float, termasuk:
char
karakter - satu byte
short
integer pendek
long
Integer panjang
double
double-precision floating point
Ukuran benda-benda ini juga tergantung-mesin. Ada juga array, struktur dan serikat ini tipe dasar, pointer kepada mereka, dan fungsi yang mengembalikan mereka, semua yang kita akan bertemu pada waktunya.
Perhitungan dalam program konversi suhu dimulai dengan pernyataan penugasan.
lower = 0;
upper = 300;
step = 20;
yang mengatur variabel ke nilai awal mereka. Pernyataan individu diakhiri oleh titik koma.
Setiap baris dari tabel dihitung dengan cara yang sama, jadi kita menggunakan loop yang berulang kali per baris output; ini adalah tujuan dari while putaran.
while (fahr <= upper) {
...
}
While itu lingkaran beroperasi sebagai berikut: Kondisi dalam tanda kurung diuji. Jika benar (fahr kurang dari atau sama dengan upper), tubuh loop (tiga pernyataan diapit oleh kurung) dijalankan. Kemudian kondisi ini kembali diuji, dan jika benar, tubuh dijalankan lagi. Ketika tes menjadi palsu (fahr melebihi upper) loop berakhir, dan eksekusi berlanjut pada pernyataan yang mengikuti loop. Tidak ada pernyataan lebih lanjut dalam program ini, sehingga berakhir.
Tubuh seorang while dapat menjadi salah satu atau lebih pernyataan diapit oleh kurung, seperti dalam konverter suhu, atau pernyataan tunggal tanpa kawat gigi, seperti dalam
while (i < j)
i = 2 * i;
Dalam kedua kasus, kita akan selalu memasukkan statement dikendalikan oleh while oleh salah satu tab stop (yang kami telah menunjukkan sebagai empat spasi) sehingga Anda dapat melihat sekilas yang laporan keuangannya berada di dalam lingkaran. Lekukan ini menekankan struktur logis dari program tersebut. Meskipun C compiler tidak peduli tentang bagaimana program terlihat, lekukan yang tepat dan jarak sangat penting dalam membuat program yang mudah bagi orang untuk membaca. Sebaiknya menulis hanya satu pernyataan per baris, dan menggunakan kosong sekitar operator untuk memperjelas pengelompokan. Posisi kawat gigi kurang penting, meskipun orang memegang keyakinan yang penuh gairah. Kami telah memilih salah satu dari beberapa gaya populer. Pilih gaya yang cocok untuk anda, kemudian menggunakannya secara konsisten.
Sebagian besar pekerjaan akan dilakukan dalam tubuh loop. Suhu Celsius dihitung dan ditugaskan untuk variabel celsius oleh pernyataan
celsius = 5 * (fahr-32) / 9;
Alasan untuk mengalikan dengan 5 dan membaginya dengan 9 bukan hanya mengalikan dengan 5/9 adalah bahwa dalam C, seperti di banyak bahasa lain, pembagian integer memotong: setiap bagian pecahan dibuang. Sejak 5 dan 9 adalah bilangan bulat. 5/9 akan dipotong ke nol dan sehingga semua suhu Celsius akan dilaporkan sebagai nol.
Contoh ini juga menunjukkan sedikit lebih tentang bagaimana karya printf. Printf adalah tujuan umum fungsi format output, yang akan kami jelaskan secara rinci dalam Bab 7. Argumen pertama adalah string karakter yang akan dicetak, dengan masing-masing% menunjukkan di mana salah satu dari yang lain (kedua, ketiga, 14 ...) argumen yang akan diganti, dan dalam bentuk apa itu harus dicetak. Misalnya,%d menentukan argumen integer, sehingga pernyataan
printf("%d\t%d\n", fahr, celsius);
menyebabkan nilai dari dua bilangan bulat fahr dan celsius yang akan dicetak, dengan tab (\ t) di antara mereka.
Setiap konstruksi% pada argumen pertama printf dipasangkan dengan argumen kedua yang sesuai, argumen ketiga, dll, mereka harus cocok dengan baik oleh jumlah dan jenis, atau Anda akan mendapatkan jawaban yang salah.
omong-omong, printf bukan bagian dari bahasa C, tidak ada input atau output didefinisikan dalam C itu sendiri. Printf hanya fungsi yang berguna dari perpustakaan standar fungsi yang biasanya dapat diakses oleh program C. Perilaku Printf didefinisikan dalam standar ANSI, bagaimanapun, jadi sifat-sifatnya harus sama dengan compiler dan perpustakaan yang sesuai dengan standar.
Dalam rangka untuk berkonsentrasi pada C itu sendiri, kita tidak berbicara banyak tentang input dan output sampai pasal 7. Secara khusus, kami akan menunda masukan diformat sampai saat itu. Jika Anda harus memasukkan nomor, baca pembahasan fungsi scanf. Scanf seperti printf, - kecuali bahwa membaca masukan alih-alih menulis output.
Ada beberapa masalah dengan program konversi suhu. Yang lebih sederhana adalah bahwa output tidak sangat prettyv karena angka-angka tersebut tidak benar-dibenarkan. Itu mudah untuk memperbaiki, jika kita menambah setiap% d dalam laporan printf dengan lebar, angka yang dicetak akan rightjustified di bidang mereka. Sebagai contoh, kita bisa mengatakan
printf("%3d %6d\n", fahr, celsius);
untuk mencetak angka pertama dari setiap baris di lapangan tiga digit lebar, dan yang kedua di bidang enam digit lebar, seperti ini:
0 -17
20 -6
40 4
60 15
80 26
100 37
...
Masalah yang lebih serius adalah bahwa karena kita telah menggunakan aritmatika integer, suhu Celsius tidak begitu akurat, misalnya, 0oF sebenarnya tentang-17.8oC, bukan -17. Untuk mendapatkan jawaban yang lebih akurat, kita harus menggunakan aritmatika floating-point bukan integer. Hal ini membutuhkan beberapa perubahan dalam program ini. Berikut ini adalah versi kedua:
#include
/* print Fahrenheit-Celsius table
for fahr = 0, 20, ..., 300; floating-point version */
main()
{
float fahr, celsius;
float lower, upper, step;
lower = 0; /* lower limit of temperatuire scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%3.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}
Ini adalah sama seperti sebelumnya, kecuali bahwa fahr and celsius dinyatakan sebagai float dan rumus untuk konversi ditulis dalam cara yang lebih alami. Kami tidak dapat menggunakan 5/9 di versi sebelumnya karena pembagian integer akan memotong ke nol. Sebuah titik desimal dalam konstanta menunjukkan bahwa itu floating point, bagaimanapun, jadi 5.0/9.0 tidak terpotong karena merupakan rasio dua nilai floating-point.
Jika operator aritmatika memiliki operan integer, operasi bilangan bulat dilakukan. Jika operator aritmatika memiliki satu floating-point operan dan satu bilangan bulat operan, bagaimanapun, integer akan dikonversi ke floating point sebelum operasi dilakukan. Jika kita telah menulis (fahr-32), 32 akan secara otomatis dikonversi ke floating point. Namun demikian, menulis konstanta floating-point dengan poin desimal eksplisit bahkan ketika mereka memiliki nilai-nilai yang tidak terpisahkan menekankan sifat floating-point mereka untuk pembaca manusia.
Aturan rinci ketika bilangan bulat dikonversi ke floating point ada di Bab 2. Untuk saat ini, melihat bahwa tugas
fahr = lower;
dan tes
while (fahr <= upper)
juga bekerja dengan cara alam – int diubah menjadi float sebelum operasi dilakukan.
Spesifikasi konversi printf %3.0f mengatakan bahwa angka floating-point (disini fahr) yang akan dicetak setidaknya tiga karakter lebar, tanpa titik desimal dan tidak ada angka pecahan. % 6.1f menjelaskan nomor lain (celsius) yang akan dicetak sedikitnya enam karakter lebar, dengan 1 digit di belakang koma. Outputnya terlihat seperti ini:
0 -17.8
20 -6.7
40 4.4
...
Lebar dan presisi dapat dihilangkan dari spesifikasi:% 6f mengatakan bahwa jumlah ini berada di \ / - setidaknya enam karakter lebar;% .2 f menetapkan dua karakter setelah titik desimal, tapi lebar adalah tidak dibatasi, dan % f hanya mengatakan untuk mencetak nomor sebagai floating point.
%d
mencetak sebagai integer desimal
%6d
mencetak sebagai integer desimal, minimal 6 karakter lebar
%f
dicetak sebagai floating point
%6f
dicetak sebagai floating point, minimal 6 karakter lebar
%.2f
dicetak sebagai floating point, 2 karakter setelah titik desimal
%6.2f
dicetak sebagai floating point, setidaknya 6 lebar dan 2 setelah titik desimal
antara lain, printf juga mengakui %o untuk oktal, %x untuk heksadesimal, %c untuk karakter, %s untuk karakter string dan %% untuk dirinya sendiri.
Latihan 1-3. Memodifikasi program konversi suhu untuk mencetak judul di atas meja.
Latihan 1-4. Tulis program untuk mencetak Celcius sesuai dengan tabel Fahrenheit.
Pernyataan for
Ada banyak cara yang berbeda untuk menulis sebuah program untuk suatu tugas tertentu. Mari kita coba variasi pada suhu converter.
#include /* mencetak tabel Fahrenheit-Celsius */
main()
{
int fahr;
for (fahr = 0; fahr <= 300; fahr = fahr + 20) printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
Ini menghasilkan jawaban yang sama, tapi jelas terlihat berbeda. Salah satu perubahan utama adalah penghapusan sebagian besar variabel, hanya fahr tetap, dan kami telah membuat sebuah int.Bawah dan atas batas dan ukuran langkah hanya muncul sebagai konstanta dalam untuk pernyataan, sendiri merupakan konstruksi baru, dan ekspresi yang menghitung suhu Celsius sekarang muncul sebagai argumen ketiga printf bukannya pernyataan penugasan terpisah.
Perubahan terakhir ini adalah turunan dari aturan umum - dalam konteks di mana ia diperbolehkan untuk menggunakan nilai dari beberapa jenis, Anda dapat menggunakan ekspresi yang lebih rumit dari tipe tersebut. Karena argumen ketiga printf harus menjadi nilai floating-point untuk mencocokkan %6.1f,setiap ekspresi floating-point dapat terjadi di sini.
Pernyataan for itu adalah loop, generalisasi dari while. Jika Anda bandingkan dengan while sebelumnya, operasinya harus jelas. Dalam kurung, ada tiga bagian, yang dipisahkan oleh titik koma. Bagian pertama, inisialisasi
fahr = 0
dilakukan sekali, sebelum loop yang tepat dimasukkan. Bagian kedua adalah tes atau kondisi yang mengontrol loop:
fahr <= 300
Kondisi ini dievaluasi, jika memang benar, tubuh loop (di sini satu ptintf) dijalankan. Maka langkah kenaikan
fahr = fahr + 20
dijalankan, dan kondisi re-evaluasi. Loop berakhir jika kondisi telah menjadi palsu. Seperti dengan while, tubuh loop bisa menjadi pernyataan tunggal atau sekelompok pernyataan diapit oleh kurung. Inisialisasi, kondisi dan peningkatan dapat berupa ekspresi.
Pilihan antara while dan for adalah sewenang-wenang, berdasarkan yang tampaknya lebih jelas. For biasanya sesuai untuk loop di mana inisialisasi dan kenaikan adalah pernyataan tunggal dan logis terkait, karena lebih kompak dari while,dan itu membuat pernyataan kontrol loop bersama-sama di satu tempat.
Latihan: Memodifikasi program konversi suhu untuk mencetak tabel dalam urutan terbalik, yaitu, dari 300 derajat ke 0.
Konstanta simbolik(Symbolic Constants)
Pengamatan terakhir sebelum kami meninggalkan konversi suhu selamanya. Ini praktik buruk untuk mengubur `` angka ajaib'' seperti 300 dan 20 dalam sebuah program, mereka menyampaikan sedikit informasi kepada seseorang yang mungkin harus membaca program nanti, dan mereka sulit untuk berubah dengan cara yang sistematis. Salah satu cara untuk berurusan dengan angka ajaib adalah untuk memberi mereka nama-nama bermakna. A # mendefinisikan garis mendefinisikan nama simbolis atau konstan simbolis menjadi string tertentu karakter:
#define nama daftar pengganti
Setelah itu, setiap terjadinya nama (tidak dalam tanda kutip dan bukan bagian dari nama lain) akan digantikan oleh teks pengganti yang sesuai. Nama ini memiliki bentuk yang sama sebagai nama variabel: urutan huruf dan angka yang dimulai dengan huruf a. Teks pengganti dapat berupa urutan karakter, tetapi tidak terbatas pada angka-angka.
#include
#define LOWER 0
#define UPPER 300
#define STEP 20
main()
{
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP) printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
kuantitas LOWER, UPPER dan STEP adalah konstanta simbolis, bukan variabel, sehingga mereka tidak muncul dalam deklarasi. Nama konstanta simbolis secara konvensional ditulis dalam huruf besar sehingga mereka dapat BER mudah dibedakan dari huruf kecil nama variabel. Perhatikan bahwa tidak ada titik koma di akhir baris #define.
karakter input dan Output (Character Input and Output)
Kita akan mempertimbangkan keluarga program terkait untuk memproses data karakter. Anda akan menemukan bahwa banyak program hanya diperluas versi prototipe yang kita bahas di sini.
Model input dan output didukung oleh perpustakaan standar sangat sederhana. Input teks atau output, terlepas dari mana itu berasal atau di mana ia pergi ke, dibahas sebagai aliran karakter. Aliran teks adalah urutan karakter dibagi menjadi baris; setiap baris terdiri dari nol atau lebih karakter diikuti oleh karakter baris baru. Ini adalah tanggung jawab perpustakaan untuk membuat setiap input atau output aliran mengkonfirmasi model ini, programmer C menggunakan perpustakaan tidak perlu khawatir tentang bagaimana garis diwakili luar program.
Perpustakaan standar menyediakan beberapa fungsi untuk membaca atau menulis satu karakter pada satu waktu, yang getchar dan putchar yang paling sederhana. Setiap kali disebut, getchar membaca karakter input berikutnya dari aliran teks dan kembali bahwa sebagai nilainya. Artinya, setelah
c = getchar();
variabel c berisi karakter berikutnya dari input. Karakter biasanya datang dari keyboard, masukan dari file dibahas nanti.Fungsi putchar mencetak karakter setiap kali itu disebut:
putchar(c);
mencetak isi dari variabel integer c sebagai karakter, biasanya di layar. Panggilan ke putchar dan printf dapat disisipkan, output akan muncul dalam urutan di mana panggilan akan dibuat.
Menyalin file(File Copying)
Mengingat getchar dan putchar, Anda dapat menulis jumlah yang mengejutkan kode yang berguna tanpa mengetahui apa-apa lagi tentang input dan output. Contoh paling sederhana adalah program yang salinan input ke output yang salah satu karakter pada satu waktu:
membaca karakter
while (charater tidak end-of-file indicator)
Output karakter hanya membaca
membaca karakter
Konversi ini ke C memberikan:
#include
/* copy input to output; 1st version */
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
Operator relasional ! = Berarti `` tidak sama dengan''.
Apa yang tampaknya menjadi karakter pada keyboard atau layar tentu saja, seperti yang lainnya, tersimpan secara internal hanya sebagai pola bit. Tipe char secara khusus dimaksudkan untuk menyimpan data karakter tersebut, tetapi setiap tipe integer dapat digunakan. Kami menggunakan int untuk alasan halus namun penting.
Masalahnya adalah membedakan akhir masukan dari data yang valid. Solusinya adalah bahwa getchar mengembalikan nilai tersendiri saat tidak ada lagi masukan, nilai yang tidak dapat bingung dengan karakter yang nyata. Nilai ini disebut EOF, untuk `` akhir file''. Kita harus menyatakan c menjadi tipe yang cukup besar untuk menampung setiap nilai yang getchar kembali. Kita tidak bisa menggunakan arang karena c harus cukup besar untuk menampung EOF di samping setiap arang mungkin. Oleh karena itu kami menggunakan int.
EOF adalah bilangan bulat didefinisikan dalam, tetapi nilai numerik tertentu tidak masalah asalkan tidak sama seperti nilai arang. Dengan menggunakan konstanta simbolis, kita yakin bahwa tidak ada dalam program ini tergantung pada nilai numerik tertentu.
Program untuk menyalin akan ditulis lebih singkat oleh C programmer berpengalaman. Dalam C, tugas apapun, seperti
c = getchar();
adalah ekspresi dan memiliki nilai, yang merupakan nilai dari sisi kiri setelah penugasan. Ini berarti bahwa tugas yang dapat muncul sebagai bagian dari ekspresi yang lebih besar. Jika penugasan karakter ke c diletakkan di dalam tes bagian dari while loop, program salinan dapat ditulis dengan cara ini:
#include
/* copy input to output; 2nd version */
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
Sementara karakter while, memberikannya ke c, dan kemudian menguji apakah karakter adalah akhir-of-file sinyal. Kalau tidak, tubuh while dijalankan, mencetak karakter. While kemudian mengulangi. Ketika akhir input akhirnya tercapai, while berakhir dan begitu juga main.
Versi ini memusatkan input - sekarang ada hanya satu referensi untuk getchar - dan menyusut program. Program yang dihasilkan lebih kompak, dan, sekali idiom dikuasai, lebih mudah dibaca. Anda akan melihat gaya ini sering. (Ini mungkin untuk mendapatkan dibawa pergi dan membuat kode tak tertembus, namun, kecenderungan yang akan kita coba untuk mengekang.)
Tanda kurung di sekitar penugasan, dalam kondisi yang diperlukan. Didahulukan dari ! = Adalah lebih tinggi dari =, yang berarti bahwa dengan tidak adanya tanda kurung tes relasional ! = Akan dilakukan sebelum tugas =. Jadi pernyataan
c = getchar() != EOF
setara dengan
c = (getchar() != EOF)
Ini memiliki efek yang tidak diinginkan dari pengaturan c dengan 0 atau 1, tergantung pada apakah atau tidak panggilan getchar kembali akhir file.
Latihan: Pastikan ekspresi getchar ()! = EOF adalah 0 atau 1.
Latihan: Menulis sebuah program untuk mencetak nilai EOF.
Menghitung karakter
Program berikutnya menghitung karakter, itu adalah mirip dengan program copy.
#include
/* count characters in input; 1st version */
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
pernyataan
++nc;
menyajikan operator baru , + + , yang berarti kenaikan per satu . Anda malah bisa menulis nc = nc + 1 + + tapi nc lebih ringkas dan sering lebih efisien . Ada operator yang sesuai - untuk pengurangan dengan 1 . Operator + + dan - dapat berupa operator prefix ( + + nc ) atau operator postfix ( nc + + ) ; dua bentuk ini memiliki nilai yang berbeda dalam ekspresi , seperti akan ditunjukkan dalam Bab 2 , tapi + + nc dan nc + + baik kenaikan nc . Untuk saat ini kami akan akan menempel pada bentuk prefix .
Program menghitung karakter terakumulasi dalam jumlah variabel panjang bukan sebuah int . bilangan bulat panjang setidaknya 32 bit . Meskipun pada beberapa mesin , int dan panjang adalah ukuran yang sama , pada orang lain int adalah 16 bit , dengan nilai maksimum 32.767 , dan itu akan mengambil relatif sedikit masukan meluap int counter. Spesifikasi konversi % ld mengatakan printf bahwa argumen yang sesuai adalah integer panjang .
Dimungkinkan untuk mengatasi dengan angka yang lebih besar dengan menggunakan ganda (float presisi ganda ) . Kami juga akan menggunakan untuk pernyataan bukan sementara , untuk menggambarkan cara lain untuk menulis loop .
#include
/* count characters in input; 2nd version */
main()
{
double nc;
for (nc = 0; gechar() != EOF; ++nc);
printf("%.0f\n", nc);
}
printf menggunakan % f untuk kedua float dan double ; % .0 f menekan pencetakan titik desimal dan bagian fraksi , yang adalah nol .
Tubuh ini untuk loop kosong , karena semua pekerjaan dilakukan dalam tes dan kenaikan bagian. Tapi aturan tata bahasa dari C akan meminta untuk pernyataan memiliki tubuh . The titik koma terisolasi , yang disebut pernyataan null, ada untuk memenuhi kebutuhan tersebut. Kami meletakkannya di baris terpisah untuk membuatnya terlihat .
Sebelum kita meninggalkan program menghitung karakter , mengamati bahwa jika input tidak berisi karakter , sementara atau tes gagal pada panggilan pertama untuk getchar , dan program ini menghasilkan nol , jawaban yang benar . Hal ini penting . Salah satu hal yang menyenangkan tentang sementara dan adalah bahwa mereka menguji di bagian atas loop , sebelum melanjutkan dengan tubuh. Jika tidak ada yang dilakukan , tidak ada yang dilakukan , bahkan jika itu berarti tidak akan melalui tubuh lingkaran . Program harus bertindak cerdas ketika diberi masukan nol-panjang . Sementara dan untuk laporan membantu memastikan bahwa program melakukan hal-hal yang wajar dengan kondisi batas .
Menghitung baris
Program berikutnya menghitung baris input. Seperti yang telah disebutkan di atas, perpustakaan standar memastikan bahwa aliran input teks muncul sebagai urutan baris, masing-masing diakhiri oleh baris baru. Oleh karena itu, menghitung baris hanya menghitung baris:
#include
/* count lines in input */ main()
{
int c, nl;
nl = 0;
while ((c = getchar()) != EOF) if (c == '\n')
++nl; printf(”%d\n”, nl);
}
Tubuh sementara sekarang terdiri dari if , yang pada gilirannya mengontrol kenaikan + + nl . Pernyataan jika tes kondisi kurung , dan jika kondisi benar , mengeksekusi pernyataan ( atau kelompok pernyataan dalam kawat gigi ) yang berikut. Kami telah kembali menjorok untuk menunjukkan apa yang dikendalikan oleh apa .
Equals ganda tanda == adalah notasi C untuk `` sama dengan '' ( seperti Pascal single = atau Fortran ini . EQ . ) . Simbol ini digunakan untuk membedakan uji kesetaraan dari = tunggal yang menggunakan C untuk tugas . Sebuah kata dari hati-hati : pendatang baru ke C sesekali menulis = ketika mereka berarti == . Seperti yang akan kita lihat dalam Bab 2 , hasilnya biasanya ekspresi hukum , sehingga Anda akan mendapatkan ada peringatan .
Sebuah karakter yang ditulis diantara tanda kutip tunggal mewakili nilai integer sama dengan nilai numerik dari karakter dalam set karakter mesin . Ini disebut karakter konstan , meskipun itu hanya cara lain untuk menulis bilangan bulat kecil . Jadi, misalnya , 'A' adalah konstanta karakter , dalam karakter ASCII set nilainya adalah 65 , representasi internal karakter A. Tentu saja, 'A ' adalah lebih disukai lebih dari 65 : artinya jelas , dan itu adalah independen dari set karakter tertentu .
Urutan escape yang digunakan dalam string konstanta juga hukum dalam konstanta karakter, jadi ' \ n' singkatan dari nilai karakter baris baru , yang 10 di ASCII . Anda harus mencatat dengan seksama bahwa ' \ n ' adalah karakter tunggal , dan dalam ekspresi hanya sebuah integer; di sisi lain , ' \ n ' adalah konstanta string yang terjadi hanya berisi satu karakter . Topik string dibandingkan karakter dibahas lebih lanjut dalam Bab 2 .
Latihan . Menulis sebuah program untuk menghitung kosong , tab , dan baris baru
Latihan . Tulis program untuk menyalin input ke output , menggantikan setiap string dari satu atau lebih kosong dengan kosong tunggal .
Latihan . Tulis program untuk menyalin input ke output , menggantikan setiap tab oleh \ t , masing-masing oleh backspace \ b , dan masing-masing backslash oleh \ \ . Hal ini membuat tab dan backspaces terlihat dalam cara yang jelas .
Menghitung kata
Yang keempat dalam seri kami program yang berguna menghitung baris, kata, dan karakter, dengan definisi longgar bahwa kata adalah setiap urutan karakter yang tidak mengandung kosong, tab atau baris baru. Ini adalah versi telanjang-tulang dari UNIX Program wc.
#include
#define IN 1 /*Inside a word*/
#define OUT 0 /*putside a word*/
/* count lines, words, and characters in input */ main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == '\n') ++nl;
if (c == ' ' || c == '\n' || c = '\t') state = OUT;
else if (state == OUT) { state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}
Setiap kali program mendapati karakter pertama dari sebuah kata, ia menghitung satu kata lagi. Catatan variabel keadaan apakah program tersebut saat ini dalam kata atau tidak, awalnya itu adalah `` tidak dalam kata'', yang ditugaskan nilai OUT. Kami lebih memilih konstanta simbolis IN dan OUT dengan nilai-nilai literal 1 dan 0 karena mereka membuat program lebih mudah dibaca. Dalam program kecil seperti ini, itu membuat sedikit perbedaan, tetapi dalam program yang lebih besar, peningkatan kejelasan adalah layak usaha ekstra sederhana untuk menulis dengan cara ini dari awal. Anda juga akan menemukan bahwa lebih mudah untuk membuat perubahan luas dalam program di mana nomor ajaib muncul hanya sebagai konstanta simbolis.
Garis
nl = nw = nc = 0;
set ketiga variabel ke nol. Ini bukan kasus khusus, tetapi konsekuensi dari kenyataan bahwa tugas adalah ekspresi dengan nilai dan tugas terkait dari kanan ke kiri. Seolah-olah kita telah menulis
nl = (nw = (nc = 0));
Operator | | berarti OR, sehingga garis
if (c == ' ' || c == '\n' || c = '\t')
mengatakan `` jika c adalah c kosong atau baris baru atau c adalah tab''. (Ingat bahwa urutan escape \ t adalah representasi terlihat dari karakter tab.) Ada operator yang sesuai untuk && AND, diutamakan yang hanya lebih tinggi dari | |. Ekspresi dihubungkan dengan && atau | | dievaluasi kiri ke kanan, dan itu dijamin bahwa evaluasi akan berhenti segera setelah kebenaran atau kepalsuan dikenal. Jika c adalah kosong, tidak ada kebutuhan untuk menguji apakah itu adalah baris baru atau tab, jadi tes ini tidak dilakukan. Hal ini tidak terlalu penting di sini, tapi signifikan dalam situasi yang lebih rumit, seperti yang kita akan segera melihat.
Contoh ini juga menunjukkan lain, yang menentukan tindakan alternatif jika kondisi bagian dari jika pernyataan adalah palsu. Bentuk umumnya adalah
if (expression)
statement1
else
statement2
Satu dan hanya satu dari dua pernyataan yang berhubungan dengan if-else dilakukan. Jika ekspresi adalah benar, statement1 dieksekusi, jika tidak, statement2 dieksekusi. Setiap pernyataan bisa menjadi pernyataan tunggal atau beberapa pada kawat gigi. Dalam program jumlah kata, satu setelah yang lain merupakan jika yang mengontrol dua pernyataan di kawat gigi.
Latihan 1-11. Bagaimana Anda akan menguji program jumlah kata? Apa macam input yang paling mungkin untuk mengungkap bug jika ada?
Latihan 1-12. Menulis sebuah program yang mencetak satu input nya kata per baris.
Array
Mari adalah menulis sebuah program untuk menghitung jumlah kejadian dari setiap digit, karakter spasi (kosong, tab, baris baru), dan dari semua karakter lain. Ini adalah buatan, tetapi memungkinkan kita untuk menggambarkan beberapa aspek dari C dalam satu program.
Ada dua belas kategori input, sehingga sangat nyaman untuk menggunakan sebuah array untuk menampung jumlah kejadian dari setiap digit, bukan sepuluh variabel individu. Berikut adalah salah satu versi dari program ini:
#include
/* count digits, white space, others */
main()
{
int c, i, nwhite, nother; int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i) ndigit[i] = 0;
while ((c = getchar()) != EOF) if (c >= '0' && c <= '9')
++ndigit[c-'0'];
else if (c == ' ' || c == '\n' || c == '\t') ++nwhite;
else
++nother;
printf("digits =");
for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n", nwhite, nother);
}
Output dari program ini pada dirinya sendiri adalah
digits = 9 3 0 0 0 0 0 0 0 1, white space = 123, other = 345
deklarasi
int ndigit[10];
menyatakan ndigit menjadi sebuah array dari 10 bilangan bulat. Subskrip Array selalu mulai dari nol di C, sehingga unsur-unsur yang ndigit [0], ndigit [1], ..., ndigit [9]. Hal ini tercermin dalam untuk loop yang menginisialisasi dan mencetak array.
Sebuah subscript dapat berupa ekspresi integer, yang meliputi variabel bilangan bulat seperti saya, dan konstanta integer.
Program ini khusus bergantung pada sifat dari representasi karakter angka. Misalnya, tes
if (c >= '0' && c <= '9')
menentukan apakah karakter dalam c adalah digit. Jika ya, nilai numerik dari angka yang
c – '0'
Ini bekerja hanya jika '0 ', '1', ..., '9 'memiliki nilai meningkat berturut-turut. Untungnya, hal ini berlaku untuk semua set karakter.
Menurut definisi, karakter hanya bilangan bulat kecil, sehingga variabel char dan konstanta yang identik dengan ints dalam ekspresi aritmatika. Ini wajar dan nyaman, misalnya c-'0 'adalah ekspresi integer dengan nilai antara 0 dan 9 sesuai dengan karakter '0' to '9 'disimpan dalam c, dan dengan demikian subscript berlaku untuk ndigit array.
Keputusan mengenai apakah karakter adalah digit, spasi, atau sesuatu yang lain dibuat dengan urutan
if (c >= '0' && c <= '9') ++ndigit[c-'0'];
else if (c == ' ' || c == '\n' || c == '\t') ++nwhite;
else
++nother;
pola
if (condition1)statement1
else if (condition2)statement2
...
...
else
statementn
sering terjadi dalam program-program sebagai cara untuk mengekspresikan keputusan multi-way. Kondisi dievaluasi agar dari atas sampai beberapa kondisi puas, pada saat itu bagian pernyataan yang sesuai dijalankan, dan seluruh konstruksi selesai. (Setiap pernyataan dapat beberapa laporan diapit oleh kurung.) Jika tidak ada kondisi puas, pernyataan setelah final lain dijalankan jika hadir. Jika yang lain akhir dan pernyataan yang dihilangkan, seperti dalam program jumlah kata, tidak ada tindakan berlangsung. Ada dapat sejumlah
else if(condition)
statement
kelompok antara awal jika dan final lain.
Sebagai soal gaya, disarankan untuk memformat konstruksi ini karena kami telah menunjukkan, jika masing-masing jika yang menjorok melewati sebelumnya yang lain, urutan panjang keputusan akan berbaris dari sisi kanan halaman. Pernyataan switch, yang akan dibahas dalam Bab 4, menyediakan cara lain untuk menulis cabang multi-cara yang khususnya cocok bila kondisi ini apakah beberapa integer atau ekspresi karakter cocok dengan salah satu dari serangkaian konstanta. Untuk Sebaliknya, kami akan menyajikan versi beralih dari program ini dalam Bagian 3.4.
Latihan 1-13. Tulis program untuk mencetak histogram dari panjang kata dalam input. Sangat mudah untuk menarik histogram dengan bar horizontal, orientasi vertikal lebih menantang.
Latihan 1-14. Tulis program untuk mencetak histogram frekuensi karakter yang berbeda dalam input.
Fungsi
Dalam C , fungsi adalah setara dengan subroutine atau fungsi dalam Fortran , atau prosedur atau fungsi di Pascal . Sebuah fungsi menyediakan cara yang nyaman untuk merangkum beberapa perhitungan , yang kemudian dapat digunakan tanpa khawatir tentang pelaksanaannya . Dengan fungsi yang dirancang dengan baik , adalah mungkin untuk mengabaikan bagaimana pekerjaan dilakukan , mengetahui apa yang dilakukan sudah cukup . C membuat sue fungsi mudah , convinient dan efisien , Anda akan sering melihat fungsi pendek didefinisikan dan disebut hanya sekali , hanya karena menjelaskan beberapa potongan kode . Sejauh ini kita telah menggunakan hanya fungsi seperti printf , getchar dan putchar yang telah disediakan bagi kita , sekarang saatnya untuk menulis beberapa kita sendiri . Karena C memiliki tidak ada operator eksponensial seperti ** dari Fortran , mari kita menggambarkan mekanisme definisi fungsi dengan menulis kekuatan fungsi ( m , n ) untuk meningkatkan integer m ke bilangan bulat positif n listrik . Artinya, nilai daya ( 2,5 ) adalah 32 . Fungsi ini tidak rutin exponentiation praktis , karena hanya menangani kekuatan positif dari bilangan bulat kecil , tapi itu cukup baik untuk ilustrasi . ( The perpustakaan standar berisi fungsi pow ( x , y ) yang menghitung xy. )
Berikut adalah kekuatan fungsi dan program utama untuk latihan itu , sehingga Anda dapat melihat seluruh struktur sekaligus.
#include
int power(int m, int n);
/* test power function */
main()
{
int i;
for (i = 0; i < 10; ++i)
printf(”%d %d %d\n”, i, power(2,i), power(-3,i));return 0;}
/* power: raise base to n-th power; n >= 0 */
int power(int base, int n)
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i) p = p * base;
return p;
}
Definisi fungsi memiliki formulir ini:
kembali-tipe fungsi-nama (deklarasi parameter, jika ada)
{
deklarasi
pernyataan
}
Definisi fungsi dapat muncul dalam urutan apapun, dan dalam satu file atau beberapa sumber, meskipun tidak ada fungsi dapat dibagi antara file. Jika program sumber muncul dalam beberapa file, Anda mungkin harus mengatakan lebih untuk mengkompilasi dan beban daripada jika itu semua muncul dalam satu, tapi itu adalah sistem operasi materi, bukan atribut bahasa. Untuk saat ini, kita akan mengasumsikan bahwa kedua fungsi berada di file yang sama, jadi apa pun yang telah Anda pelajari tentang menjalankan program C akan tetap bekerja. Fungsi listrik disebut dua kali oleh utama, di baris
printf("%d %d %d\n", i, power(2,i), power(-3,i));
Setiap panggilan melewati dua argumen untuk kekuasaan, yang setiap kali mengembalikan sebuah integer yang akan diformat dan dicetak. Dalam ekspresi, kekuasaan (2, i) adalah integer seperti 2 dan saya adalah. (Tidak semua fungsi menghasilkan nilai integer, kami akan mengambil ini dalam Bab 4.)
Baris pertama dari kekuasaan itu sendiri,
int power(int base, int n)
menyatakan jenis dan nama parameter, dan jenis hasil bahwa fungsi mengembalikan. Nama-nama yang digunakan oleh listrik untuk parameter lokal untuk kekuasaan, dan tidak terlihat oleh fungsi lain: rutinitas lainnya dapat menggunakan nama yang sama tanpa konflik. Hal ini juga berlaku dari variabel i dan p: i dalam kekuasaan tidak berhubungan dengan i dalam utama.
Kita umumnya akan menggunakan parameter untuk variabel bernama dalam daftar kurung dalam suatu fungsi. Istilah argumen formal dan argumen aktual kadang-kadang digunakan untuk membedakan yang sama.
Nilai daya yang menghitung dikembalikan ke utama dengan kembalinya: pernyataan. Setiap ekspresi dapat mengikuti kembali:
return expression;
Sebuah fungsi tidak perlu mengembalikan nilai, sebuah pernyataan kembali tanpa ekspresi menyebabkan kontrol, tapi tidak ada nilai yang berguna, harus dikembalikan ke pemanggil, seperti halnya `` jatuh dari akhir'' dari suatu fungsi dengan mencapai brace yang tepat mengakhiri. Dan fungsi panggilan dapat mengabaikan nilai dikembalikan oleh fungsi.
Anda mungkin telah memperhatikan bahwa ada pernyataan kembali pada akhir utama. Sejak utama adalah fungsi seperti yang lain, mungkin mengembalikan nilai ke pemanggil, yang adalah berlaku lingkungan di mana program tersebut dieksekusi. Biasanya, nilai kembali dari nol menyiratkan penghentian normal, nilai-nilai non-nol sinyal kondisi terminasi yang tidak biasa atau keliru. Dalam kepentingan kesederhanaan, kami telah menghilangkan pernyataan kembali dari fungsi utama kami sampai saat ini, tapi kami akan mencakup mereka selanjutnya, sebagai pengingat bahwa program harus kembali status lingkungan mereka.
Deklarasi
int power(int base, int n);
sebelum utama mengatakan bahwa kekuasaan adalah fungsi yang mengharapkan dua argumen int dan mengembalikan sebuah int. Deklarasi ini, yang disebut prototipe fungsi, harus setuju dengan definisi dan penggunaan kekuasaan. Ini adalah kesalahan jika definisi fungsi atau kegunaan itu tidak setuju dengan prototipe.
nama parameter harus tidak setuju. Memang, nama parameter adalah opsional dalam prototipe fungsi, jadi untuk prototipe kita bisa menulis
int power(int, int);
Nama yang dipilih adalah dokumentasi yang baik namun, jadi kita akan sering menggunakannya.
Sebuah catatan sejarah: perubahan terbesar antara ANSI C dan versi sebelumnya adalah bagaimana fungsi dideklarasikan dan didefinisikan. Dalam definisi asli dari C, fungsi listrik akan ditulis seperti ini:
/* power: raise base to n-th power; n >= 0 */
/* (old-style version) */
power(base, n) int base, n;
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i) p = p * base;
return p;
}
Parameter diberi nama antara tanda kurung, dan jenis mereka dideklarasikan sebelum membuka penjepit kiri, parameter dideklarasikan diambil sebagai int. (Tubuh fungsi adalah sama seperti sebelumnya.)
Deklarasi kekuasaan pada awal program akan tampak seperti ini:
int power();
Tidak ada daftar parameter diizinkan, sehingga compiler tidak bisa dengan mudah memeriksa kekuatan yang disebut dengan benar. Memang, karena dengan daya standar akan telah diasumsikan untuk kembali int, seluruh deklarasi mungkin juga telah dihilangkan.
Sintaks baru prototipe fungsi membuat lebih mudah untuk compiler untuk mendeteksi kesalahan dalam jumlah argumen atau jenis mereka. Gaya lama deklarasi dan definisi masih bekerja di ANSI C, setidaknya untuk masa transisi, tetapi kami sangat menyarankan agar Anda menggunakan bentuk baru ketika Anda memiliki compiler yang mendukungnya.
Latihan 1.15. Rewrite program konversi suhu Bagian 1.2 untuk menggunakan fungsi untuk konversi.
Argumen - Panggil dengan Nilai (Arguments - Call by Value)
Salah satu aspek dari fungsi C mungkin asing bagi programmer yang digunakan untuk beberapa bahasa lain, khususnya Fortran. Dalam C, semua argumen fungsi berlalu `` dengan nilai.'' Ini berarti bahwa fungsi dipanggil diberi nilai argumen dalam variabel sementara daripada aslinya. Hal ini menyebabkan beberapa sifat yang berbeda dari yang terlihat dengan `` panggilan dengan referensi'' bahasa seperti Fortran atau dengan parameter var di Pascal, di mana disebut rutin memiliki akses ke argumen asli, bukan salinan lokal.
Panggilan dengan nilai aset, bagaimanapun, bukan kewajiban. Ini biasanya menyebabkan program yang lebih kompak dengan variabel asing lebih sedikit, karena parameter dapat diperlakukan sebagai variabel lokal diinisialisasi nyaman dalam apa yang disebut rutin. Sebagai contoh, di sini adalah versi kekuasaan yang menggunakan properti ini.
/* power: raise base to n-th power; n >= 0; version 2 */
int power(int base, int n)
{
int p;
for (p = 1; n > 0;--n) p = p * base;
return p;
}
Parameter n digunakan sebagai variabel sementara, dan menghitung mundur (untuk loop yang berjalan mundur) sampai menjadi nol, tidak ada lagi kebutuhan untuk variabel i. Apa pun yang dilakukan untuk n dalam kekuasaan tidak berpengaruh pada argumen bahwa kekuasaan awalnya disebut dengan.
Bila perlu, adalah mungkin untuk mengatur fungsi untuk memodifikasi variabel dalam rutinitas panggilan. Penelepon harus memberikan alamat variabel yang akan diatur (secara teknis pointer ke ariable), dan fungsi dipanggil harus menyatakan parameter untuk menjadi pointer dan mengakses variabel secara tidak langsung melalui itu. Kami akan mencakup petunjuk dalam Bab 5.
Cerita ini berbeda untuk array. Ketika nama array digunakan sebagai argumen, nilai dilewatkan ke fungsi adalah lokasi atau alamat dari awal array - tidak ada menyalin elemen array. Dengan subscripting nilai ini, fungsi tersebut dapat mengakses dan mengubah argumen array. Ini adalah topik pada bagian berikutnya.
Array karakter
Jenis yang paling umum dari array dalam C adalah array karakter. Untuk menggambarkan penggunaan karakter array dan fungsi untuk memanipulasi mereka, mari kita menulis sebuah program yang membaca satu set baris teks dan mencetak terpanjang. Garis ini cukup sederhana:
while (there's another line)
if (it's longer than the previous longest) (save it)
(save its length)print longest line
Garis ini membuat jelas bahwa program membagi secara alami menjadi potongan-potongan. One piece mendapatkan baris baru, yang lain menyimpannya, dan sisanya mengontrol proses.
Karena hal membagi begitu baik, itu akan baik untuk menulis mereka seperti itu juga. Oleh karena itu, mari kita menulis fungsi getline terpisah untuk mengambil baris berikutnya dari input. Kami akan mencoba untuk membuat fungsi yang berguna dalam konteks lain. Minimal, getline harus mengembalikan sinyal tentang kemungkinan akhir file, desain yang lebih berguna akan mengembalikan panjang garis, atau nol jika akhir file ditemui. Nol adalah diterima end-of-file kembali karena tidak pernah panjang garis valid. Setiap baris teks memiliki setidaknya satu karakter, bahkan garis yang hanya berisi baris baru memiliki panjang 1.
Ketika kita menemukan garis yang lebih panjang dari garis terpanjang sebelumnya, harus disimpan di suatu tempat. Hal ini menunjukkan fungsi kedua, copy, untuk menyalin baris baru ke tempat yang aman.
Akhirnya, kita membutuhkan sebuah program utama untuk mengontrol getline dan copy.
Berikut adalah hasilnya.
#include
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/*print the longest input line*/
main()
{
int len; /*current line length*/
int max; /*maximum length seen so far*/
char line[MAXLINE]; /* longest line saved here */
max=0;
while((len=getline(line, MAXLINE))>0)
if(len>max){
max=len;
copy(longest, line);
}
if (max > 0) /* there was a line */ printf("%s", longest);
return 0;
}
/* getline: read a line into s, return length */ int getline(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) s[i] = c;
if (c == '\n') { s[i] = c; ++i;
}
s[i] = '\0'; return i;
}
/* copy: copy 'from' into 'to'; assume to is big enough */ void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0') ++i;
}
Fungsi getline dan copy dideklarasikan pada awal program, yang kita asumsikan terkandung dalam satu file.
utama dan getline berkomunikasi melalui sepasang argumen dan nilai kembali. Dalam getline, argumen dinyatakan oleh garis
int getline(char s[], int lim);
yang menentukan bahwa argumen pertama, s, adalah array, dan yang kedua, lim, adalah bilangan bulat. Tujuan penyediaan ukuran array dalam deklarasi adalah untuk menyisihkan penyimpanan. Panjang array s tidak perlu di getline karena ukurannya diatur dalam utama. menggunakan getline kembali untuk mengirim nilai kembali ke pemanggil, seperti kekuatan fungsi lakukan. Baris ini juga menyatakan bahwa getline mengembalikan sebuah int, karena int adalah tipe kembali default, itu bisa dihilangkan.
Beberapa fungsi mengembalikan nilai yang berguna, yang lainnya, seperti copy, hanya digunakan untuk efek mereka dan kembali nilai. Jenis kembalinya copy batal, yang menyatakan secara eksplisit bahwa tidak ada nilai yang dikembalikan. getline menempatkan karakter '\ 0' (karakter null, yang nilainya nol) pada akhir array itu adalah menciptakan, untuk menandai akhir dari string karakter. Konversi ini juga digunakan oleh bahasa C: ketika string konstan seperti
"hello\n"
muncul dalam sebuah program C, akan disimpan sebagai array dari karakter yang mengandung karakter dalam string dan diakhiri dengan '\ 0' untuk menandai akhir.
Spesifikasi format % s dalam printf mengharapkan argumen yang sesuai untuk menjadi string direpresentasikan dalam bentuk ini . copy juga bergantung pada fakta bahwa argumen input diakhiri dengan ' \ 0 ' , dan salinan karakter ini ke output .
Perlu disebutkan secara sepintas bahwa bahkan sebuah program sekecil satu ini menyajikan beberapa masalah desain lengket . Misalnya, apa yang harus lakukan utama jika menemukan garis yang lebih besar dari batas ? getline bekerja dengan aman , dalam hal ini berhenti ketika mengumpulkan array penuh , bahkan jika tidak ada baris baru telah terlihat . Dengan pengujian panjang dan karakter terakhir kembali , utama dapat menentukan apakah jalur ini terlalu lama , dan kemudian mengatasinya karena keinginan . Dalam kepentingan singkatnya , kita telah mengabaikan masalah ini .
Tidak ada cara untuk pengguna dari getline tahu sebelumnya berapa lama garis masukan mungkin , sehingga pemeriksaan getline untuk overflow . Di sisi lain , pengguna copy sudah tahu ( atau bisa mengetahui ) seberapa besar string , jadi kita telah memilih untuk tidak menambahkan memeriksa untuk itu error .
Latihan . Merevisi rutin utama dari program terpanjang -line sehingga benar akan mencetak panjang jalur input panjang sewenang-wenang , dan sebanyak mungkin teks.
Latihan . Tulis program untuk mencetak semua baris input yang lebih panjang dari 80 karakter .
Latihan . Menulis sebuah program untuk menghapus trailing kosong dan tab dari setiap baris masukan , dan menghapus baris yang sama sekali kosong .
Latihan . Tulis terbalik fungsi ( s ) yang membalikkan string karakter s . Gunakan untuk menulis sebuah program yang membalikkan input garis pada suatu waktu .
Variabel eksternal dan Ruang Lingkup ( External Variables and Scope)
Variabel dalam utama , seperti garis , terpanjang , dan lain-lain , pribadi atau lokal untuk utama. Karena mereka dinyatakan dalam utama, ada fungsi lain dapat memiliki akses langsung kepada mereka . Hal yang sama juga terjadi pada variabel dalam fungsi lain , misalnya , variabel i dalam getline tidak berhubungan dengan i di copy . Setiap variabel lokal dalam fungsi datang ke dalam keberadaan hanya bila fungsi ini dipanggil , dan menghilang ketika fungsi keluar . Inilah sebabnya mengapa variabel seperti biasanya dikenal sebagai variabel otomatis , mengikuti istilah dalam bahasa lain . Kami akan menggunakan istilah otomatis selanjutnya untuk merujuk pada variabel lokal . ( Bab 4 membahas kelas penyimpanan statis , di mana variabel lokal yang mempertahankan nilai-nilai mereka antara panggilan . Karena variabel otomatis datang dan pergi dengan fungsi doa , mereka tidak mempertahankan nilai-nilai mereka dari satu panggilan ke yang berikutnya , dan harus secara eksplisit diatur pada setiap entri . Jika mereka tidak diatur , mereka akan berisi sampah .
Sebagai alternatif untuk variabel otomatis , adalah mungkin untuk mendefinisikan variabel yang bersifat eksternal ke semua fungsi , yaitu , variabel yang dapat diakses oleh nama oleh fungsi apapun . ( Mekanisme ini agak seperti Fortran UMUM atau variabel Pascal dideklarasikan pada blok terluar . ) Karena variabel eksternal yang secara global dapat diakses , mereka dapat digunakan sebagai pengganti dari daftar argumen untuk berkomunikasi data antara fungsi . Selanjutnya, karena variabel eksternal tetap eksis secara permanen , daripada muncul dan menghilang sebagai fungsi dipanggil dan keluar , mereka mempertahankan nilai-nilai mereka bahkan setelah fungsi yang mengatur mereka telah kembali .
Variabel eksternal harus didefinisikan , tepat satu kali , di luar fungsi apapun, ini menyisihkan penyimpanan untuk itu . Variabel juga harus dinyatakan dalam setiap fungsi yang ingin mengaksesnya , ini menyatakan jenis variabel . Deklarasi tersebut mungkin merupakan pernyataan extern eksplisit atau mungkin implisit dari konteks . Untuk membuat beton diskusi , mari kita menulis ulang program terpanjang -line dengan garis , terpanjang , dan max sebagai variabel eksternal . Hal ini memerlukan mengubah panggilan , deklarasi , dan tubuh semua tiga fungsi .
#include
#define MAXLINE 1000 /*maximum input line size*/
int max; /*maximum length seen so far*/
char line[MAXLINE]; /*current input line*/
char longest[MAXLINE]; /*longest line saved here*/
int getline(void);
void copy(void); /* print longest input line; specialized version */
main()
{
int len;
extern int max;
extern char longest[];
max = 0;while ((len = getline()) > 0) if (len > max) {
max = len; copy();
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* getline: specialized version */
int getline(void)
{
int c, i;
extern char line[];
for (i = 0; i < MAXLINE - 1
&& (c=getchar)) != EOF && c != '\n'; ++i) line[i] = c;
if (c == '\n') { line[i] = c; ++i;
}
line[i] = '\0'; return i;
}
/* copy: specialized version */
void copy(void)
{
int i;
extern char line[], longest[];
i = 0;
while ((longest[i] = line[i]) != '\0') ++i;
}
Variabel eksternal utama, getline dan copy didefinisikan oleh baris pertama dari contoh di atas , yang menyatakan jenis mereka dan menyebabkan penyimpanan dialokasikan untuk mereka . Sintaksis , definisi eksternal seperti definisi variabel lokal , tapi karena mereka terjadi di luar fungsi , variabel eksternal . Sebelum fungsi dapat menggunakan variabel eksternal , nama variabel harus diketahui fungsinya; deklarasi adalah sama seperti sebelumnya kecuali untuk kata kunci extern ditambahkan .
Dalam keadaan tertentu , deklarasi extern dapat dihilangkan . Jika definisi dari variabel eksternal terjadi pada file sumber sebelum penggunaannya dalam fungsi tertentu , maka tidak ada kebutuhan untuk deklarasi extern dalam fungsi. Deklarasi extern dalam utama, getline dan copy dengan demikian berlebihan . Bahkan , praktek umum adalah untuk menempatkan definisi dari semua variabel eksternal pada awal file sumber , dan kemudian menghilangkan semua deklarasi extern .
Jika program ini dalam beberapa file sumber , dan variabel didefinisikan dalam file1 dan digunakan dalam file2 file3 dan , maka deklarasi extern diperlukan dalam file2 file3 dan untuk menghubungkan kejadian dari variabel. Praktek yang biasa adalah untuk mengumpulkan deklarasi extern variabel dan fungsi dalam file terpisah , secara historis disebut header , yang disertakan dengan # include di depan setiap file sumber . Akhiran . H adalah konvensional untuk nama sundulan . Fungsi perpustakaan standar , misalnya , dinyatakan dalam header seperti . Topik ini dibahas panjang lebar dalam Bab 4 , dan perpustakaan itu sendiri dalam Bab 7 dan Lampiran B.
Sejak versi khusus getline dan copy tidak memiliki argumen , logika akan menunjukkan bahwa prototipe mereka pada awal file harus getline ( ) dan copy ( ) . Tapi untuk kompatibilitas dengan program C yang lebih tua standar mengambil daftar kosong sebagai deklarasi gaya lama , dan mematikan semua daftar argumen pemeriksaan ; kekosongan kata harus digunakan untuk daftar secara eksplisit kosong . Kita akan membahas ini lebih lanjut dalam Bab 4 .
Anda harus mencatat bahwa kita menggunakan definisi kata-kata dan pernyataan hati-hati ketika kita merujuk ke variabel eksternal di bagian ini `` Definition '' mengacu pada tempat di mana variabel dibuat atau ditugaskan penyimpanan ; . `` Deklarasi '' mengacu pada tempat di mana sifat variabel dinyatakan tetapi tidak ada penyimpanan dialokasikan .
By the way , ada kecenderungan untuk membuat segala sesuatu yang terlihat variabel extern karena muncul untuk menyederhanakan komunikasi - daftar argumen pendek dan variabel selalu ada ketika Anda ingin mereka . Tetapi variabel eksternal selalu ada bahkan ketika Anda tidak ingin mereka . Terlalu mengandalkan variabel eksternal yang penuh dengan bahaya karena mengarah pada program yang datanya koneksi tidak semua jelas - variabel dapat diubah dengan cara yang tak terduga dan bahkan sengaja , dan program ini sulit untuk memodifikasi . Versi kedua dari program terpanjang -line lebih rendah daripada yang pertama , sebagian untuk alasan ini , dan sebagian karena ia menghancurkan sifat umum dari dua fungsi yang berguna dengan menulis ke dalamnya nama-nama variabel mereka memanipulasi .
Pada titik ini kita telah membahas apa yang bisa disebut inti konvensional C. Dengan segelintir ini blok bangunan , itu mungkin untuk menulis program yang berguna yang cukup besar , dan itu mungkin akan menjadi ide yang baik jika Anda berhenti cukup lama untuk melakukannya . Latihan ini menunjukkan program kompleksitas agak lebih besar dari yang sebelumnya dalam bab ini .
Latihan . Tulis detab program yang menggantikan tab di input dengan jumlah yang tepat dari ruang kosong untuk ke halte tab berikutnya . Asumsikan seperangkat tetap tab berhenti , mengatakan setiap kolom n . Harus n menjadi variabel atau parameter simbolis ?
Latihan . Tulis entab program yang menggantikan string kosong dengan jumlah minimal tab dan kosong untuk mencapai jarak yang sama . Gunakan berhenti tab yang sama seperti untuk detab . Ketika salah satu tab atau kosong tunggal akan cukup untuk mencapai berhenti tab , yang harus diberikan preferensi ?
Latihan . Menulis sebuah program untuk `` lipat '' baris input panjang menjadi dua atau lebih pendek baris setelah karakter non - kosong terakhir yang terjadi sebelum kolom ke-n dari input. Pastikan program anda melakukan sesuatu yang cerdas dengan garis yang sangat panjang , dan jika tidak ada kekosongan atau tab sebelum kolom tertentu .
Latihan . Menulis sebuah program untuk menghapus semua komentar dari program C . Jangan lupa untuk menangani string dikutip dan konstanta karakter dengan benar . C Komentar tidak bersarang .
Latihan . Tulis program untuk memeriksa program C untuk kesalahan sintaks dasar seperti kurung tak tertandingi , tanda kurung dan kawat gigi . Jangan lupa tentang tanda kutip , baik tunggal dan ganda , escape sequence , dan komentar . (Program ini sulit jika Anda melakukannya di umum penuh. )
By Gonoh
Mari kita mulai dengan pengenalan cepat di C. Tujuan kami adalah untuk menunjukkan unsur-unsur penting dari bahasa dalam program-program nyata, tetapi tanpa terhenti dalam rincian, peraturan, dan pengecualian. Pada titik ini, kita tidak mencoba untuk menjadi lengkap atau bahkan tepat (kecuali bahwa contoh adalah dimaksudkan untuk menjadi benar). Kami ingin mendapatkan Anda secepat mungkin ke titik di mana Anda dapat menulis program yang berguna, dan untuk itu kita harus berkonsentrasi pada dasar-dasar: variabel dan konstanta, aritmatika, aliran kontrol, fungsi, dan dasar-dasar input dan output. Kami sengaja meninggalkan keluar dari ini fitur bab C yang penting untuk menulis lebih besar program. Ini termasuk pointer, struktur, sebagian besar set kaya C dari operator, beberapa controlflow pernyataan, dan perpustakaan standar.
Pendekatan ini dan kekurangannya. Paling penting adalah bahwa cerita lengkap pada setiap tertentu fitur tidak ditemukan di sini, dan tutorial, dengan menjadi singkat, mungkin juga menyesatkan. Dan karena contoh tidak menggunakan kekuatan penuh dari C, mereka tidak ringkas dan elegan seperti mereka mungkin menjadi. Kami telah mencoba untuk meminimalkan efek ini, tetapi memperingatkan. Kelemahan lain adalah bahwa nanti bab tentu akan mengulang beberapa bab ini. Kami berharap bahwa pengulangan akan membantu Anda lebih dari itu mengganggu.
Dalam kasus apapun, programmer berpengalaman harus mampu ekstrapolasi dari materi dalam hal ini bab dengan kebutuhan program mereka sendiri. Pemula harus melengkapi dengan menulis kecil, program serupa dari mereka sendiri. Kedua kelompok dapat menggunakannya sebagai kerangka di mana untuk menggantung deskripsi yang lebih rinci yang dimulai pada Bab 2.
Memulai
Satu-satunya cara untuk belajar bahasa pemrograman baru adalah dengan menulisprogram di dalamnya. Pertama Program untuk menulis adalah sama untuk semua bahasa:
Cetak kata-kata
hello, world
Ini adalah rintangan besar, untuk melompati itu Anda harus mampu menciptakan teks program di suatu tempat, compile berhasil, beban itu, menjalankannya, dan mencari tahu di mana output pergi. Dengan rincian mekanik menguasai, segala sesuatu yang lain relatif mudah.
Dalam C, program untuk mencetak ``hello, world’’ is
#include
main()
{
printf("hello, world\n");
}
Hanya bagaimana untuk menjalankan program ini tergantung pada sistem yang Anda gunakan. Sebagai contoh spesifik, pada sistem operasi UNIX Anda harus membuat program dalam sebuah file yang namanya berakhiran ``.c’’, seperti hello.c, kemudian compile dengan perintahcc
hello.c
Jika Anda belum dirusak apa-apa, seperti menghilangkan karakter atau salah mengeja sesuatu, yang kompilasi akan melanjutkan diam-diam, dan membuat sebuah file eksekusi bernama a.out. Jika Anda menjalankan a.out dengan mengetikkan perintah
a.out
akan mencetak
hello, world
Pada sistem lain, aturan akan berbeda, periksa dengan ahli lokal. Sekarang, untuk beberapa penjelasan tentang program itu sendiri. Sebuah program C, apapun ukurannya, terdiri fungsi dan variabel. Sebuah fungsi berisi pernyataan yang menentukan komputasi operasi yang harus dilakukan, dan nilai-nilai variabel store digunakan selama perhitungan. Fungsi C seperti subrutin dan fungsi dalam Fortran atau prosedur dan fungsi Pascal. Kami contoh adalah fungsi bernama main. Normally you are at liberty to give functions whatever names you like, but ``main'' khusus - program anda mulai mengeksekusi pada awal utama. Ini berarti bahwa setiap program harus memiliki main di suatu tempat.
Main will usually call other functions to help perform its job, some that you wrote, and others from libraries that are provided for you. The first line of the program,
#include
mengatakan kepada kompiler untuk menyertakan informasi tentang standar perpustakaan input / output; baris muncul pada awal banyak file sumber C. Perpustakaan standar dijelaskan dalam Bab 7 dan Lampiran B.
Salah satu metode komunikasi data antara fungsi adalah untuk fungsi panggilan untuk memberikan daftar nilai, disebut argumen, dengan fungsi itu panggilan. Tanda kurung setelah nama fungsi mengelilingi daftar argumen. Dalam contoh ini, main didefinisikan sebagai fungsi yang mengharapkan tidak ada argumen, yang ditunjukkan dengan daftar kosong ( ).
#include
termasuk informasi tentang standar Library
Main() mendefinisikan sebuah fungsi yang di
Sebut “main” yang tidak menerima nilai
Nilai argumen
{ laporan main diapit oleh kurung
printf("hello, world\n"); main memanggil fungsi library printf
untuk mencetak urutan karakter
}\ n mewakili karakter baris baru
Program C pertama
Laporan dari fungsi diapit oleh kurung {}. Fungsi main hanya berisi satu pernyataan,
printf(”hello, world\n”);
Sebuah fungsi disebut dengan penamaan itu, diikuti dengan daftar kurung argumen, sehingga panggilan ini fungsi printf dengan argumen “hello, world\n”. Printf adalah fungsi library yang mencetak output, dalam hal ini string karakter antara tanda kutip.
Sebuah urutan karakter dalam tanda kutip ganda, seperti “hello, world\n”, disebut karakter string atau konstanta string. Untuk saat ini kita gunakan hanya karakter string akan sebagai argumen untuk printf dan fungsi lainnya.
Urutan \n dalam string adalah notasi C untuk karakter baris baru, yang bila dicetak kemajuan output ke margin kiri pada baris berikutnya. Jika Anda meninggalkan keluar in the string is C notation for the newline character, which when printed advances the output to the left margin on the next line. If you leave out the \n (percobaan berharga), Anda akan menemukan bahwa tidak ada garis muka setelah output dicetak. Anda harus menggunakan \n untuk memasukkan karakter baris baru di printf argumen, jika Anda mencoba sesuatu seperti,
printf(”hello, world”);
compiler C akan menghasilkan pesan kesalahan.
Printf tidak pernah memasok karakter baris baru secara otomatis, sehingga beberapa panggilan dapat digunakan untuk membangun sebuah jalur output secara bertahap. Program pertama kami bisa juga ditulis
#include
main()
{
printf("hello, ");
printf("world");
printf("\n");
}
untuk menghasilkan output yang identik.
Perhatikan bahwa \n hanya mewakili satu karakter. Sebuah urutan escape seperti \n menyediakan mekanisme umum dan extensible untuk mewakili sulit tipe atau karakter tak terlihat. Di antara lain bahwa C menyediakan adalah \t untuk tab, \b backspace untuk, \ "untuk kutipan ganda dan \ \ untuk backslash itu sendiri.
latihan 1-1 Jalankan ``hello, world'' Program pada sistem Anda. Percobaan dengan meninggalkan keluar bagian dari program, untuk melihat apa pesan kesalahan yang Anda dapatkan.
Latihan 1-2 Percobaan untuk mencari tahu apa yang terjadi ketika prints's argumen string mengandung \ c, di mana c adalah beberapa karakter tidak tercantum di atas.
Variabel dan Aritmatika Ekspresi
Program berikutnya menggunakan rumus oC = (5/9) (oF-32) untuk mencetak tabel berikut suhu Fahrenheit dan Celcius atau setara Celcius mereka:
1 -17
20 -6
40 4
60 15
80 26
100 37
120 48
140 60
160 71
180 82
200 93
220 104
240 115
260 126
280 137
300 148
Program itu sendiri masih terdiri dari definisi fungsi tunggal bernama main. Hal ini lebih lama daripada yang dicetak ``hello, world'', tapi tidak rumit. Hal ini memperkenalkan beberapa ide-ide baru, termasuk komentar, deklarasi, variabel, ekspresi aritmatika, loop, dan output diformat.
#include
/* mencetak tabel Fahrenheit-Celsius
for fahr = 0, 20, ..., 300 */
main()
{
int fahr, celsius;
int lower, upper, step;
lower = 0; /* batas bawah skala suhu */
upper = 300; /* batas atas */
step = 20; /* ukuran langkah */
fahr = lower;
while (fahr <= upper) {
celsius = 5 * (fahr-32) / 9;
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
}
Dua baris
/* mencetak tabel Fahrenheit-Celsius
for fahr = 0, 20, ..., 300 */
adalah komentar, yang dalam hal ini menjelaskan secara singkat apa program tidak. Setiap karakter antara / * dan * / diabaikan oleh compiler, mereka dapat digunakan secara bebas untuk membuat program lebih mudah untuk memahami. Komentar dapat muncul di mana saja di mana kosong, tab atau baris baru bisa.
Dalam C, semua variabel harus dideklarasikan sebelum mereka digunakan, biasanya pada awal fungsi sebelum pernyataan dieksekusi. Sebuah deklarasi mengumumkan sifat variabel, terdiri dari nama dan daftar variabel, seperti
int fahr, celsius;
int lower, upper, step;
Jenis yang int berarti bahwa variabel yang tercantum adalah bilangan bulat, sebaliknya dengan float, yang berarti floating point, yaitu, angka yang mungkin memiliki bagian pecahan. Kisaran kedua int dan float tergantung pada mesin yang Anda gunakan, 16-bit ints, yang terletak antara -32768 dan 32767, yang umum, seperti 32-bit ints. Sejumlah float biasanya kuantitas 32-bit, dengan setidaknya enam angka signifikan dan besarnya umumnya antara sekitar 10-38 dan 1038.
C menyediakan beberapa tipe data lain selain int and float, termasuk:
char
karakter - satu byte
short
integer pendek
long
Integer panjang
double
double-precision floating point
Ukuran benda-benda ini juga tergantung-mesin. Ada juga array, struktur dan serikat ini tipe dasar, pointer kepada mereka, dan fungsi yang mengembalikan mereka, semua yang kita akan bertemu pada waktunya.
Perhitungan dalam program konversi suhu dimulai dengan pernyataan penugasan.
lower = 0;
upper = 300;
step = 20;
yang mengatur variabel ke nilai awal mereka. Pernyataan individu diakhiri oleh titik koma.
Setiap baris dari tabel dihitung dengan cara yang sama, jadi kita menggunakan loop yang berulang kali per baris output; ini adalah tujuan dari while putaran.
while (fahr <= upper) {
...
}
While itu lingkaran beroperasi sebagai berikut: Kondisi dalam tanda kurung diuji. Jika benar (fahr kurang dari atau sama dengan upper), tubuh loop (tiga pernyataan diapit oleh kurung) dijalankan. Kemudian kondisi ini kembali diuji, dan jika benar, tubuh dijalankan lagi. Ketika tes menjadi palsu (fahr melebihi upper) loop berakhir, dan eksekusi berlanjut pada pernyataan yang mengikuti loop. Tidak ada pernyataan lebih lanjut dalam program ini, sehingga berakhir.
Tubuh seorang while dapat menjadi salah satu atau lebih pernyataan diapit oleh kurung, seperti dalam konverter suhu, atau pernyataan tunggal tanpa kawat gigi, seperti dalam
while (i < j)
i = 2 * i;
Dalam kedua kasus, kita akan selalu memasukkan statement dikendalikan oleh while oleh salah satu tab stop (yang kami telah menunjukkan sebagai empat spasi) sehingga Anda dapat melihat sekilas yang laporan keuangannya berada di dalam lingkaran. Lekukan ini menekankan struktur logis dari program tersebut. Meskipun C compiler tidak peduli tentang bagaimana program terlihat, lekukan yang tepat dan jarak sangat penting dalam membuat program yang mudah bagi orang untuk membaca. Sebaiknya menulis hanya satu pernyataan per baris, dan menggunakan kosong sekitar operator untuk memperjelas pengelompokan. Posisi kawat gigi kurang penting, meskipun orang memegang keyakinan yang penuh gairah. Kami telah memilih salah satu dari beberapa gaya populer. Pilih gaya yang cocok untuk anda, kemudian menggunakannya secara konsisten.
Sebagian besar pekerjaan akan dilakukan dalam tubuh loop. Suhu Celsius dihitung dan ditugaskan untuk variabel celsius oleh pernyataan
celsius = 5 * (fahr-32) / 9;
Alasan untuk mengalikan dengan 5 dan membaginya dengan 9 bukan hanya mengalikan dengan 5/9 adalah bahwa dalam C, seperti di banyak bahasa lain, pembagian integer memotong: setiap bagian pecahan dibuang. Sejak 5 dan 9 adalah bilangan bulat. 5/9 akan dipotong ke nol dan sehingga semua suhu Celsius akan dilaporkan sebagai nol.
Contoh ini juga menunjukkan sedikit lebih tentang bagaimana karya printf. Printf adalah tujuan umum fungsi format output, yang akan kami jelaskan secara rinci dalam Bab 7. Argumen pertama adalah string karakter yang akan dicetak, dengan masing-masing% menunjukkan di mana salah satu dari yang lain (kedua, ketiga, 14 ...) argumen yang akan diganti, dan dalam bentuk apa itu harus dicetak. Misalnya,%d menentukan argumen integer, sehingga pernyataan
printf("%d\t%d\n", fahr, celsius);
menyebabkan nilai dari dua bilangan bulat fahr dan celsius yang akan dicetak, dengan tab (\ t) di antara mereka.
Setiap konstruksi% pada argumen pertama printf dipasangkan dengan argumen kedua yang sesuai, argumen ketiga, dll, mereka harus cocok dengan baik oleh jumlah dan jenis, atau Anda akan mendapatkan jawaban yang salah.
omong-omong, printf bukan bagian dari bahasa C, tidak ada input atau output didefinisikan dalam C itu sendiri. Printf hanya fungsi yang berguna dari perpustakaan standar fungsi yang biasanya dapat diakses oleh program C. Perilaku Printf didefinisikan dalam standar ANSI, bagaimanapun, jadi sifat-sifatnya harus sama dengan compiler dan perpustakaan yang sesuai dengan standar.
Dalam rangka untuk berkonsentrasi pada C itu sendiri, kita tidak berbicara banyak tentang input dan output sampai pasal 7. Secara khusus, kami akan menunda masukan diformat sampai saat itu. Jika Anda harus memasukkan nomor, baca pembahasan fungsi scanf. Scanf seperti printf, - kecuali bahwa membaca masukan alih-alih menulis output.
Ada beberapa masalah dengan program konversi suhu. Yang lebih sederhana adalah bahwa output tidak sangat prettyv karena angka-angka tersebut tidak benar-dibenarkan. Itu mudah untuk memperbaiki, jika kita menambah setiap% d dalam laporan printf dengan lebar, angka yang dicetak akan rightjustified di bidang mereka. Sebagai contoh, kita bisa mengatakan
printf("%3d %6d\n", fahr, celsius);
untuk mencetak angka pertama dari setiap baris di lapangan tiga digit lebar, dan yang kedua di bidang enam digit lebar, seperti ini:
0 -17
20 -6
40 4
60 15
80 26
100 37
...
Masalah yang lebih serius adalah bahwa karena kita telah menggunakan aritmatika integer, suhu Celsius tidak begitu akurat, misalnya, 0oF sebenarnya tentang-17.8oC, bukan -17. Untuk mendapatkan jawaban yang lebih akurat, kita harus menggunakan aritmatika floating-point bukan integer. Hal ini membutuhkan beberapa perubahan dalam program ini. Berikut ini adalah versi kedua:
#include
/* print Fahrenheit-Celsius table
for fahr = 0, 20, ..., 300; floating-point version */
main()
{
float fahr, celsius;
float lower, upper, step;
lower = 0; /* lower limit of temperatuire scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%3.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}
Ini adalah sama seperti sebelumnya, kecuali bahwa fahr and celsius dinyatakan sebagai float dan rumus untuk konversi ditulis dalam cara yang lebih alami. Kami tidak dapat menggunakan 5/9 di versi sebelumnya karena pembagian integer akan memotong ke nol. Sebuah titik desimal dalam konstanta menunjukkan bahwa itu floating point, bagaimanapun, jadi 5.0/9.0 tidak terpotong karena merupakan rasio dua nilai floating-point.
Jika operator aritmatika memiliki operan integer, operasi bilangan bulat dilakukan. Jika operator aritmatika memiliki satu floating-point operan dan satu bilangan bulat operan, bagaimanapun, integer akan dikonversi ke floating point sebelum operasi dilakukan. Jika kita telah menulis (fahr-32), 32 akan secara otomatis dikonversi ke floating point. Namun demikian, menulis konstanta floating-point dengan poin desimal eksplisit bahkan ketika mereka memiliki nilai-nilai yang tidak terpisahkan menekankan sifat floating-point mereka untuk pembaca manusia.
Aturan rinci ketika bilangan bulat dikonversi ke floating point ada di Bab 2. Untuk saat ini, melihat bahwa tugas
fahr = lower;
dan tes
while (fahr <= upper)
juga bekerja dengan cara alam – int diubah menjadi float sebelum operasi dilakukan.
Spesifikasi konversi printf %3.0f mengatakan bahwa angka floating-point (disini fahr) yang akan dicetak setidaknya tiga karakter lebar, tanpa titik desimal dan tidak ada angka pecahan. % 6.1f menjelaskan nomor lain (celsius) yang akan dicetak sedikitnya enam karakter lebar, dengan 1 digit di belakang koma. Outputnya terlihat seperti ini:
0 -17.8
20 -6.7
40 4.4
...
Lebar dan presisi dapat dihilangkan dari spesifikasi:% 6f mengatakan bahwa jumlah ini berada di \ / - setidaknya enam karakter lebar;% .2 f menetapkan dua karakter setelah titik desimal, tapi lebar adalah tidak dibatasi, dan % f hanya mengatakan untuk mencetak nomor sebagai floating point.
%d
mencetak sebagai integer desimal
%6d
mencetak sebagai integer desimal, minimal 6 karakter lebar
%f
dicetak sebagai floating point
%6f
dicetak sebagai floating point, minimal 6 karakter lebar
%.2f
dicetak sebagai floating point, 2 karakter setelah titik desimal
%6.2f
dicetak sebagai floating point, setidaknya 6 lebar dan 2 setelah titik desimal
antara lain, printf juga mengakui %o untuk oktal, %x untuk heksadesimal, %c untuk karakter, %s untuk karakter string dan %% untuk dirinya sendiri.
Latihan 1-3. Memodifikasi program konversi suhu untuk mencetak judul di atas meja.
Latihan 1-4. Tulis program untuk mencetak Celcius sesuai dengan tabel Fahrenheit.
Pernyataan for
Ada banyak cara yang berbeda untuk menulis sebuah program untuk suatu tugas tertentu. Mari kita coba variasi pada suhu converter.
#include
main()
{
int fahr;
for (fahr = 0; fahr <= 300; fahr = fahr + 20) printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
Ini menghasilkan jawaban yang sama, tapi jelas terlihat berbeda. Salah satu perubahan utama adalah penghapusan sebagian besar variabel, hanya fahr tetap, dan kami telah membuat sebuah int.Bawah dan atas batas dan ukuran langkah hanya muncul sebagai konstanta dalam untuk pernyataan, sendiri merupakan konstruksi baru, dan ekspresi yang menghitung suhu Celsius sekarang muncul sebagai argumen ketiga printf bukannya pernyataan penugasan terpisah.
Perubahan terakhir ini adalah turunan dari aturan umum - dalam konteks di mana ia diperbolehkan untuk menggunakan nilai dari beberapa jenis, Anda dapat menggunakan ekspresi yang lebih rumit dari tipe tersebut. Karena argumen ketiga printf harus menjadi nilai floating-point untuk mencocokkan %6.1f,setiap ekspresi floating-point dapat terjadi di sini.
Pernyataan for itu adalah loop, generalisasi dari while. Jika Anda bandingkan dengan while sebelumnya, operasinya harus jelas. Dalam kurung, ada tiga bagian, yang dipisahkan oleh titik koma. Bagian pertama, inisialisasi
fahr = 0
dilakukan sekali, sebelum loop yang tepat dimasukkan. Bagian kedua adalah tes atau kondisi yang mengontrol loop:
fahr <= 300
Kondisi ini dievaluasi, jika memang benar, tubuh loop (di sini satu ptintf) dijalankan. Maka langkah kenaikan
fahr = fahr + 20
dijalankan, dan kondisi re-evaluasi. Loop berakhir jika kondisi telah menjadi palsu. Seperti dengan while, tubuh loop bisa menjadi pernyataan tunggal atau sekelompok pernyataan diapit oleh kurung. Inisialisasi, kondisi dan peningkatan dapat berupa ekspresi.
Pilihan antara while dan for adalah sewenang-wenang, berdasarkan yang tampaknya lebih jelas. For biasanya sesuai untuk loop di mana inisialisasi dan kenaikan adalah pernyataan tunggal dan logis terkait, karena lebih kompak dari while,dan itu membuat pernyataan kontrol loop bersama-sama di satu tempat.
Latihan: Memodifikasi program konversi suhu untuk mencetak tabel dalam urutan terbalik, yaitu, dari 300 derajat ke 0.
Konstanta simbolik(Symbolic Constants)
Pengamatan terakhir sebelum kami meninggalkan konversi suhu selamanya. Ini praktik buruk untuk mengubur `` angka ajaib'' seperti 300 dan 20 dalam sebuah program, mereka menyampaikan sedikit informasi kepada seseorang yang mungkin harus membaca program nanti, dan mereka sulit untuk berubah dengan cara yang sistematis. Salah satu cara untuk berurusan dengan angka ajaib adalah untuk memberi mereka nama-nama bermakna. A # mendefinisikan garis mendefinisikan nama simbolis atau konstan simbolis menjadi string tertentu karakter:
#define nama daftar pengganti
Setelah itu, setiap terjadinya nama (tidak dalam tanda kutip dan bukan bagian dari nama lain) akan digantikan oleh teks pengganti yang sesuai. Nama ini memiliki bentuk yang sama sebagai nama variabel: urutan huruf dan angka yang dimulai dengan huruf a. Teks pengganti dapat berupa urutan karakter, tetapi tidak terbatas pada angka-angka.
#include
#define LOWER 0
#define UPPER 300
#define STEP 20
main()
{
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP) printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
kuantitas LOWER, UPPER dan STEP adalah konstanta simbolis, bukan variabel, sehingga mereka tidak muncul dalam deklarasi. Nama konstanta simbolis secara konvensional ditulis dalam huruf besar sehingga mereka dapat BER mudah dibedakan dari huruf kecil nama variabel. Perhatikan bahwa tidak ada titik koma di akhir baris #define.
karakter input dan Output (Character Input and Output)
Kita akan mempertimbangkan keluarga program terkait untuk memproses data karakter. Anda akan menemukan bahwa banyak program hanya diperluas versi prototipe yang kita bahas di sini.
Model input dan output didukung oleh perpustakaan standar sangat sederhana. Input teks atau output, terlepas dari mana itu berasal atau di mana ia pergi ke, dibahas sebagai aliran karakter. Aliran teks adalah urutan karakter dibagi menjadi baris; setiap baris terdiri dari nol atau lebih karakter diikuti oleh karakter baris baru. Ini adalah tanggung jawab perpustakaan untuk membuat setiap input atau output aliran mengkonfirmasi model ini, programmer C menggunakan perpustakaan tidak perlu khawatir tentang bagaimana garis diwakili luar program.
Perpustakaan standar menyediakan beberapa fungsi untuk membaca atau menulis satu karakter pada satu waktu, yang getchar dan putchar yang paling sederhana. Setiap kali disebut, getchar membaca karakter input berikutnya dari aliran teks dan kembali bahwa sebagai nilainya. Artinya, setelah
c = getchar();
variabel c berisi karakter berikutnya dari input. Karakter biasanya datang dari keyboard, masukan dari file dibahas nanti.Fungsi putchar mencetak karakter setiap kali itu disebut:
putchar(c);
mencetak isi dari variabel integer c sebagai karakter, biasanya di layar. Panggilan ke putchar dan printf dapat disisipkan, output akan muncul dalam urutan di mana panggilan akan dibuat.
Menyalin file(File Copying)
Mengingat getchar dan putchar, Anda dapat menulis jumlah yang mengejutkan kode yang berguna tanpa mengetahui apa-apa lagi tentang input dan output. Contoh paling sederhana adalah program yang salinan input ke output yang salah satu karakter pada satu waktu:
membaca karakter
while (charater tidak end-of-file indicator)
Output karakter hanya membaca
membaca karakter
Konversi ini ke C memberikan:
#include
/* copy input to output; 1st version */
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
Operator relasional ! = Berarti `` tidak sama dengan''.
Apa yang tampaknya menjadi karakter pada keyboard atau layar tentu saja, seperti yang lainnya, tersimpan secara internal hanya sebagai pola bit. Tipe char secara khusus dimaksudkan untuk menyimpan data karakter tersebut, tetapi setiap tipe integer dapat digunakan. Kami menggunakan int untuk alasan halus namun penting.
Masalahnya adalah membedakan akhir masukan dari data yang valid. Solusinya adalah bahwa getchar mengembalikan nilai tersendiri saat tidak ada lagi masukan, nilai yang tidak dapat bingung dengan karakter yang nyata. Nilai ini disebut EOF, untuk `` akhir file''. Kita harus menyatakan c menjadi tipe yang cukup besar untuk menampung setiap nilai yang getchar kembali. Kita tidak bisa menggunakan arang karena c harus cukup besar untuk menampung EOF di samping setiap arang mungkin. Oleh karena itu kami menggunakan int.
EOF adalah bilangan bulat didefinisikan dalam
Program untuk menyalin akan ditulis lebih singkat oleh C programmer berpengalaman. Dalam C, tugas apapun, seperti
c = getchar();
adalah ekspresi dan memiliki nilai, yang merupakan nilai dari sisi kiri setelah penugasan. Ini berarti bahwa tugas yang dapat muncul sebagai bagian dari ekspresi yang lebih besar. Jika penugasan karakter ke c diletakkan di dalam tes bagian dari while loop, program salinan dapat ditulis dengan cara ini:
#include
/* copy input to output; 2nd version */
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
Sementara karakter while, memberikannya ke c, dan kemudian menguji apakah karakter adalah akhir-of-file sinyal. Kalau tidak, tubuh while dijalankan, mencetak karakter. While kemudian mengulangi. Ketika akhir input akhirnya tercapai, while berakhir dan begitu juga main.
Versi ini memusatkan input - sekarang ada hanya satu referensi untuk getchar - dan menyusut program. Program yang dihasilkan lebih kompak, dan, sekali idiom dikuasai, lebih mudah dibaca. Anda akan melihat gaya ini sering. (Ini mungkin untuk mendapatkan dibawa pergi dan membuat kode tak tertembus, namun, kecenderungan yang akan kita coba untuk mengekang.)
Tanda kurung di sekitar penugasan, dalam kondisi yang diperlukan. Didahulukan dari ! = Adalah lebih tinggi dari =, yang berarti bahwa dengan tidak adanya tanda kurung tes relasional ! = Akan dilakukan sebelum tugas =. Jadi pernyataan
c = getchar() != EOF
setara dengan
c = (getchar() != EOF)
Ini memiliki efek yang tidak diinginkan dari pengaturan c dengan 0 atau 1, tergantung pada apakah atau tidak panggilan getchar kembali akhir file.
Latihan: Pastikan ekspresi getchar ()! = EOF adalah 0 atau 1.
Latihan: Menulis sebuah program untuk mencetak nilai EOF.
Menghitung karakter
Program berikutnya menghitung karakter, itu adalah mirip dengan program copy.
#include
/* count characters in input; 1st version */
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
pernyataan
++nc;
menyajikan operator baru , + + , yang berarti kenaikan per satu . Anda malah bisa menulis nc = nc + 1 + + tapi nc lebih ringkas dan sering lebih efisien . Ada operator yang sesuai - untuk pengurangan dengan 1 . Operator + + dan - dapat berupa operator prefix ( + + nc ) atau operator postfix ( nc + + ) ; dua bentuk ini memiliki nilai yang berbeda dalam ekspresi , seperti akan ditunjukkan dalam Bab 2 , tapi + + nc dan nc + + baik kenaikan nc . Untuk saat ini kami akan akan menempel pada bentuk prefix .
Program menghitung karakter terakumulasi dalam jumlah variabel panjang bukan sebuah int . bilangan bulat panjang setidaknya 32 bit . Meskipun pada beberapa mesin , int dan panjang adalah ukuran yang sama , pada orang lain int adalah 16 bit , dengan nilai maksimum 32.767 , dan itu akan mengambil relatif sedikit masukan meluap int counter. Spesifikasi konversi % ld mengatakan printf bahwa argumen yang sesuai adalah integer panjang .
Dimungkinkan untuk mengatasi dengan angka yang lebih besar dengan menggunakan ganda (float presisi ganda ) . Kami juga akan menggunakan untuk pernyataan bukan sementara , untuk menggambarkan cara lain untuk menulis loop .
#include
/* count characters in input; 2nd version */
main()
{
double nc;
for (nc = 0; gechar() != EOF; ++nc);
printf("%.0f\n", nc);
}
printf menggunakan % f untuk kedua float dan double ; % .0 f menekan pencetakan titik desimal dan bagian fraksi , yang adalah nol .
Tubuh ini untuk loop kosong , karena semua pekerjaan dilakukan dalam tes dan kenaikan bagian. Tapi aturan tata bahasa dari C akan meminta untuk pernyataan memiliki tubuh . The titik koma terisolasi , yang disebut pernyataan null, ada untuk memenuhi kebutuhan tersebut. Kami meletakkannya di baris terpisah untuk membuatnya terlihat .
Sebelum kita meninggalkan program menghitung karakter , mengamati bahwa jika input tidak berisi karakter , sementara atau tes gagal pada panggilan pertama untuk getchar , dan program ini menghasilkan nol , jawaban yang benar . Hal ini penting . Salah satu hal yang menyenangkan tentang sementara dan adalah bahwa mereka menguji di bagian atas loop , sebelum melanjutkan dengan tubuh. Jika tidak ada yang dilakukan , tidak ada yang dilakukan , bahkan jika itu berarti tidak akan melalui tubuh lingkaran . Program harus bertindak cerdas ketika diberi masukan nol-panjang . Sementara dan untuk laporan membantu memastikan bahwa program melakukan hal-hal yang wajar dengan kondisi batas .
Menghitung baris
Program berikutnya menghitung baris input. Seperti yang telah disebutkan di atas, perpustakaan standar memastikan bahwa aliran input teks muncul sebagai urutan baris, masing-masing diakhiri oleh baris baru. Oleh karena itu, menghitung baris hanya menghitung baris:
#include
/* count lines in input */ main()
{
int c, nl;
nl = 0;
while ((c = getchar()) != EOF) if (c == '\n')
++nl; printf(”%d\n”, nl);
}
Tubuh sementara sekarang terdiri dari if , yang pada gilirannya mengontrol kenaikan + + nl . Pernyataan jika tes kondisi kurung , dan jika kondisi benar , mengeksekusi pernyataan ( atau kelompok pernyataan dalam kawat gigi ) yang berikut. Kami telah kembali menjorok untuk menunjukkan apa yang dikendalikan oleh apa .
Equals ganda tanda == adalah notasi C untuk `` sama dengan '' ( seperti Pascal single = atau Fortran ini . EQ . ) . Simbol ini digunakan untuk membedakan uji kesetaraan dari = tunggal yang menggunakan C untuk tugas . Sebuah kata dari hati-hati : pendatang baru ke C sesekali menulis = ketika mereka berarti == . Seperti yang akan kita lihat dalam Bab 2 , hasilnya biasanya ekspresi hukum , sehingga Anda akan mendapatkan ada peringatan .
Sebuah karakter yang ditulis diantara tanda kutip tunggal mewakili nilai integer sama dengan nilai numerik dari karakter dalam set karakter mesin . Ini disebut karakter konstan , meskipun itu hanya cara lain untuk menulis bilangan bulat kecil . Jadi, misalnya , 'A' adalah konstanta karakter , dalam karakter ASCII set nilainya adalah 65 , representasi internal karakter A. Tentu saja, 'A ' adalah lebih disukai lebih dari 65 : artinya jelas , dan itu adalah independen dari set karakter tertentu .
Urutan escape yang digunakan dalam string konstanta juga hukum dalam konstanta karakter, jadi ' \ n' singkatan dari nilai karakter baris baru , yang 10 di ASCII . Anda harus mencatat dengan seksama bahwa ' \ n ' adalah karakter tunggal , dan dalam ekspresi hanya sebuah integer; di sisi lain , ' \ n ' adalah konstanta string yang terjadi hanya berisi satu karakter . Topik string dibandingkan karakter dibahas lebih lanjut dalam Bab 2 .
Latihan . Menulis sebuah program untuk menghitung kosong , tab , dan baris baru
Latihan . Tulis program untuk menyalin input ke output , menggantikan setiap string dari satu atau lebih kosong dengan kosong tunggal .
Latihan . Tulis program untuk menyalin input ke output , menggantikan setiap tab oleh \ t , masing-masing oleh backspace \ b , dan masing-masing backslash oleh \ \ . Hal ini membuat tab dan backspaces terlihat dalam cara yang jelas .
Menghitung kata
Yang keempat dalam seri kami program yang berguna menghitung baris, kata, dan karakter, dengan definisi longgar bahwa kata adalah setiap urutan karakter yang tidak mengandung kosong, tab atau baris baru. Ini adalah versi telanjang-tulang dari UNIX Program wc.
#include
#define IN 1 /*Inside a word*/
#define OUT 0 /*putside a word*/
/* count lines, words, and characters in input */ main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == '\n') ++nl;
if (c == ' ' || c == '\n' || c = '\t') state = OUT;
else if (state == OUT) { state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}
Setiap kali program mendapati karakter pertama dari sebuah kata, ia menghitung satu kata lagi. Catatan variabel keadaan apakah program tersebut saat ini dalam kata atau tidak, awalnya itu adalah `` tidak dalam kata'', yang ditugaskan nilai OUT. Kami lebih memilih konstanta simbolis IN dan OUT dengan nilai-nilai literal 1 dan 0 karena mereka membuat program lebih mudah dibaca. Dalam program kecil seperti ini, itu membuat sedikit perbedaan, tetapi dalam program yang lebih besar, peningkatan kejelasan adalah layak usaha ekstra sederhana untuk menulis dengan cara ini dari awal. Anda juga akan menemukan bahwa lebih mudah untuk membuat perubahan luas dalam program di mana nomor ajaib muncul hanya sebagai konstanta simbolis.
Garis
nl = nw = nc = 0;
set ketiga variabel ke nol. Ini bukan kasus khusus, tetapi konsekuensi dari kenyataan bahwa tugas adalah ekspresi dengan nilai dan tugas terkait dari kanan ke kiri. Seolah-olah kita telah menulis
nl = (nw = (nc = 0));
Operator | | berarti OR, sehingga garis
if (c == ' ' || c == '\n' || c = '\t')
mengatakan `` jika c adalah c kosong atau baris baru atau c adalah tab''. (Ingat bahwa urutan escape \ t adalah representasi terlihat dari karakter tab.) Ada operator yang sesuai untuk && AND, diutamakan yang hanya lebih tinggi dari | |. Ekspresi dihubungkan dengan && atau | | dievaluasi kiri ke kanan, dan itu dijamin bahwa evaluasi akan berhenti segera setelah kebenaran atau kepalsuan dikenal. Jika c adalah kosong, tidak ada kebutuhan untuk menguji apakah itu adalah baris baru atau tab, jadi tes ini tidak dilakukan. Hal ini tidak terlalu penting di sini, tapi signifikan dalam situasi yang lebih rumit, seperti yang kita akan segera melihat.
Contoh ini juga menunjukkan lain, yang menentukan tindakan alternatif jika kondisi bagian dari jika pernyataan adalah palsu. Bentuk umumnya adalah
if (expression)
statement1
else
statement2
Satu dan hanya satu dari dua pernyataan yang berhubungan dengan if-else dilakukan. Jika ekspresi adalah benar, statement1 dieksekusi, jika tidak, statement2 dieksekusi. Setiap pernyataan bisa menjadi pernyataan tunggal atau beberapa pada kawat gigi. Dalam program jumlah kata, satu setelah yang lain merupakan jika yang mengontrol dua pernyataan di kawat gigi.
Latihan 1-11. Bagaimana Anda akan menguji program jumlah kata? Apa macam input yang paling mungkin untuk mengungkap bug jika ada?
Latihan 1-12. Menulis sebuah program yang mencetak satu input nya kata per baris.
Array
Mari adalah menulis sebuah program untuk menghitung jumlah kejadian dari setiap digit, karakter spasi (kosong, tab, baris baru), dan dari semua karakter lain. Ini adalah buatan, tetapi memungkinkan kita untuk menggambarkan beberapa aspek dari C dalam satu program.
Ada dua belas kategori input, sehingga sangat nyaman untuk menggunakan sebuah array untuk menampung jumlah kejadian dari setiap digit, bukan sepuluh variabel individu. Berikut adalah salah satu versi dari program ini:
#include
/* count digits, white space, others */
main()
{
int c, i, nwhite, nother; int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i) ndigit[i] = 0;
while ((c = getchar()) != EOF) if (c >= '0' && c <= '9')
++ndigit[c-'0'];
else if (c == ' ' || c == '\n' || c == '\t') ++nwhite;
else
++nother;
printf("digits =");
for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n", nwhite, nother);
}
Output dari program ini pada dirinya sendiri adalah
digits = 9 3 0 0 0 0 0 0 0 1, white space = 123, other = 345
deklarasi
int ndigit[10];
menyatakan ndigit menjadi sebuah array dari 10 bilangan bulat. Subskrip Array selalu mulai dari nol di C, sehingga unsur-unsur yang ndigit [0], ndigit [1], ..., ndigit [9]. Hal ini tercermin dalam untuk loop yang menginisialisasi dan mencetak array.
Sebuah subscript dapat berupa ekspresi integer, yang meliputi variabel bilangan bulat seperti saya, dan konstanta integer.
Program ini khusus bergantung pada sifat dari representasi karakter angka. Misalnya, tes
if (c >= '0' && c <= '9')
menentukan apakah karakter dalam c adalah digit. Jika ya, nilai numerik dari angka yang
c – '0'
Ini bekerja hanya jika '0 ', '1', ..., '9 'memiliki nilai meningkat berturut-turut. Untungnya, hal ini berlaku untuk semua set karakter.
Menurut definisi, karakter hanya bilangan bulat kecil, sehingga variabel char dan konstanta yang identik dengan ints dalam ekspresi aritmatika. Ini wajar dan nyaman, misalnya c-'0 'adalah ekspresi integer dengan nilai antara 0 dan 9 sesuai dengan karakter '0' to '9 'disimpan dalam c, dan dengan demikian subscript berlaku untuk ndigit array.
Keputusan mengenai apakah karakter adalah digit, spasi, atau sesuatu yang lain dibuat dengan urutan
if (c >= '0' && c <= '9') ++ndigit[c-'0'];
else if (c == ' ' || c == '\n' || c == '\t') ++nwhite;
else
++nother;
pola
if (condition1)statement1
else if (condition2)statement2
...
...
else
statementn
sering terjadi dalam program-program sebagai cara untuk mengekspresikan keputusan multi-way. Kondisi dievaluasi agar dari atas sampai beberapa kondisi puas, pada saat itu bagian pernyataan yang sesuai dijalankan, dan seluruh konstruksi selesai. (Setiap pernyataan dapat beberapa laporan diapit oleh kurung.) Jika tidak ada kondisi puas, pernyataan setelah final lain dijalankan jika hadir. Jika yang lain akhir dan pernyataan yang dihilangkan, seperti dalam program jumlah kata, tidak ada tindakan berlangsung. Ada dapat sejumlah
else if(condition)
statement
kelompok antara awal jika dan final lain.
Sebagai soal gaya, disarankan untuk memformat konstruksi ini karena kami telah menunjukkan, jika masing-masing jika yang menjorok melewati sebelumnya yang lain, urutan panjang keputusan akan berbaris dari sisi kanan halaman. Pernyataan switch, yang akan dibahas dalam Bab 4, menyediakan cara lain untuk menulis cabang multi-cara yang khususnya cocok bila kondisi ini apakah beberapa integer atau ekspresi karakter cocok dengan salah satu dari serangkaian konstanta. Untuk Sebaliknya, kami akan menyajikan versi beralih dari program ini dalam Bagian 3.4.
Latihan 1-13. Tulis program untuk mencetak histogram dari panjang kata dalam input. Sangat mudah untuk menarik histogram dengan bar horizontal, orientasi vertikal lebih menantang.
Latihan 1-14. Tulis program untuk mencetak histogram frekuensi karakter yang berbeda dalam input.
Fungsi
Dalam C , fungsi adalah setara dengan subroutine atau fungsi dalam Fortran , atau prosedur atau fungsi di Pascal . Sebuah fungsi menyediakan cara yang nyaman untuk merangkum beberapa perhitungan , yang kemudian dapat digunakan tanpa khawatir tentang pelaksanaannya . Dengan fungsi yang dirancang dengan baik , adalah mungkin untuk mengabaikan bagaimana pekerjaan dilakukan , mengetahui apa yang dilakukan sudah cukup . C membuat sue fungsi mudah , convinient dan efisien , Anda akan sering melihat fungsi pendek didefinisikan dan disebut hanya sekali , hanya karena menjelaskan beberapa potongan kode . Sejauh ini kita telah menggunakan hanya fungsi seperti printf , getchar dan putchar yang telah disediakan bagi kita , sekarang saatnya untuk menulis beberapa kita sendiri . Karena C memiliki tidak ada operator eksponensial seperti ** dari Fortran , mari kita menggambarkan mekanisme definisi fungsi dengan menulis kekuatan fungsi ( m , n ) untuk meningkatkan integer m ke bilangan bulat positif n listrik . Artinya, nilai daya ( 2,5 ) adalah 32 . Fungsi ini tidak rutin exponentiation praktis , karena hanya menangani kekuatan positif dari bilangan bulat kecil , tapi itu cukup baik untuk ilustrasi . ( The perpustakaan standar berisi fungsi pow ( x , y ) yang menghitung xy. )
Berikut adalah kekuatan fungsi dan program utama untuk latihan itu , sehingga Anda dapat melihat seluruh struktur sekaligus.
#include
int power(int m, int n);
/* test power function */
main()
{
int i;
for (i = 0; i < 10; ++i)
printf(”%d %d %d\n”, i, power(2,i), power(-3,i));return 0;}
/* power: raise base to n-th power; n >= 0 */
int power(int base, int n)
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i) p = p * base;
return p;
}
Definisi fungsi memiliki formulir ini:
kembali-tipe fungsi-nama (deklarasi parameter, jika ada)
{
deklarasi
pernyataan
}
Definisi fungsi dapat muncul dalam urutan apapun, dan dalam satu file atau beberapa sumber, meskipun tidak ada fungsi dapat dibagi antara file. Jika program sumber muncul dalam beberapa file, Anda mungkin harus mengatakan lebih untuk mengkompilasi dan beban daripada jika itu semua muncul dalam satu, tapi itu adalah sistem operasi materi, bukan atribut bahasa. Untuk saat ini, kita akan mengasumsikan bahwa kedua fungsi berada di file yang sama, jadi apa pun yang telah Anda pelajari tentang menjalankan program C akan tetap bekerja. Fungsi listrik disebut dua kali oleh utama, di baris
printf("%d %d %d\n", i, power(2,i), power(-3,i));
Setiap panggilan melewati dua argumen untuk kekuasaan, yang setiap kali mengembalikan sebuah integer yang akan diformat dan dicetak. Dalam ekspresi, kekuasaan (2, i) adalah integer seperti 2 dan saya adalah. (Tidak semua fungsi menghasilkan nilai integer, kami akan mengambil ini dalam Bab 4.)
Baris pertama dari kekuasaan itu sendiri,
int power(int base, int n)
menyatakan jenis dan nama parameter, dan jenis hasil bahwa fungsi mengembalikan. Nama-nama yang digunakan oleh listrik untuk parameter lokal untuk kekuasaan, dan tidak terlihat oleh fungsi lain: rutinitas lainnya dapat menggunakan nama yang sama tanpa konflik. Hal ini juga berlaku dari variabel i dan p: i dalam kekuasaan tidak berhubungan dengan i dalam utama.
Kita umumnya akan menggunakan parameter untuk variabel bernama dalam daftar kurung dalam suatu fungsi. Istilah argumen formal dan argumen aktual kadang-kadang digunakan untuk membedakan yang sama.
Nilai daya yang menghitung dikembalikan ke utama dengan kembalinya: pernyataan. Setiap ekspresi dapat mengikuti kembali:
return expression;
Sebuah fungsi tidak perlu mengembalikan nilai, sebuah pernyataan kembali tanpa ekspresi menyebabkan kontrol, tapi tidak ada nilai yang berguna, harus dikembalikan ke pemanggil, seperti halnya `` jatuh dari akhir'' dari suatu fungsi dengan mencapai brace yang tepat mengakhiri. Dan fungsi panggilan dapat mengabaikan nilai dikembalikan oleh fungsi.
Anda mungkin telah memperhatikan bahwa ada pernyataan kembali pada akhir utama. Sejak utama adalah fungsi seperti yang lain, mungkin mengembalikan nilai ke pemanggil, yang adalah berlaku lingkungan di mana program tersebut dieksekusi. Biasanya, nilai kembali dari nol menyiratkan penghentian normal, nilai-nilai non-nol sinyal kondisi terminasi yang tidak biasa atau keliru. Dalam kepentingan kesederhanaan, kami telah menghilangkan pernyataan kembali dari fungsi utama kami sampai saat ini, tapi kami akan mencakup mereka selanjutnya, sebagai pengingat bahwa program harus kembali status lingkungan mereka.
Deklarasi
int power(int base, int n);
sebelum utama mengatakan bahwa kekuasaan adalah fungsi yang mengharapkan dua argumen int dan mengembalikan sebuah int. Deklarasi ini, yang disebut prototipe fungsi, harus setuju dengan definisi dan penggunaan kekuasaan. Ini adalah kesalahan jika definisi fungsi atau kegunaan itu tidak setuju dengan prototipe.
nama parameter harus tidak setuju. Memang, nama parameter adalah opsional dalam prototipe fungsi, jadi untuk prototipe kita bisa menulis
int power(int, int);
Nama yang dipilih adalah dokumentasi yang baik namun, jadi kita akan sering menggunakannya.
Sebuah catatan sejarah: perubahan terbesar antara ANSI C dan versi sebelumnya adalah bagaimana fungsi dideklarasikan dan didefinisikan. Dalam definisi asli dari C, fungsi listrik akan ditulis seperti ini:
/* power: raise base to n-th power; n >= 0 */
/* (old-style version) */
power(base, n) int base, n;
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i) p = p * base;
return p;
}
Parameter diberi nama antara tanda kurung, dan jenis mereka dideklarasikan sebelum membuka penjepit kiri, parameter dideklarasikan diambil sebagai int. (Tubuh fungsi adalah sama seperti sebelumnya.)
Deklarasi kekuasaan pada awal program akan tampak seperti ini:
int power();
Tidak ada daftar parameter diizinkan, sehingga compiler tidak bisa dengan mudah memeriksa kekuatan yang disebut dengan benar. Memang, karena dengan daya standar akan telah diasumsikan untuk kembali int, seluruh deklarasi mungkin juga telah dihilangkan.
Sintaks baru prototipe fungsi membuat lebih mudah untuk compiler untuk mendeteksi kesalahan dalam jumlah argumen atau jenis mereka. Gaya lama deklarasi dan definisi masih bekerja di ANSI C, setidaknya untuk masa transisi, tetapi kami sangat menyarankan agar Anda menggunakan bentuk baru ketika Anda memiliki compiler yang mendukungnya.
Latihan 1.15. Rewrite program konversi suhu Bagian 1.2 untuk menggunakan fungsi untuk konversi.
Argumen - Panggil dengan Nilai (Arguments - Call by Value)
Salah satu aspek dari fungsi C mungkin asing bagi programmer yang digunakan untuk beberapa bahasa lain, khususnya Fortran. Dalam C, semua argumen fungsi berlalu `` dengan nilai.'' Ini berarti bahwa fungsi dipanggil diberi nilai argumen dalam variabel sementara daripada aslinya. Hal ini menyebabkan beberapa sifat yang berbeda dari yang terlihat dengan `` panggilan dengan referensi'' bahasa seperti Fortran atau dengan parameter var di Pascal, di mana disebut rutin memiliki akses ke argumen asli, bukan salinan lokal.
Panggilan dengan nilai aset, bagaimanapun, bukan kewajiban. Ini biasanya menyebabkan program yang lebih kompak dengan variabel asing lebih sedikit, karena parameter dapat diperlakukan sebagai variabel lokal diinisialisasi nyaman dalam apa yang disebut rutin. Sebagai contoh, di sini adalah versi kekuasaan yang menggunakan properti ini.
/* power: raise base to n-th power; n >= 0; version 2 */
int power(int base, int n)
{
int p;
for (p = 1; n > 0;--n) p = p * base;
return p;
}
Parameter n digunakan sebagai variabel sementara, dan menghitung mundur (untuk loop yang berjalan mundur) sampai menjadi nol, tidak ada lagi kebutuhan untuk variabel i. Apa pun yang dilakukan untuk n dalam kekuasaan tidak berpengaruh pada argumen bahwa kekuasaan awalnya disebut dengan.
Bila perlu, adalah mungkin untuk mengatur fungsi untuk memodifikasi variabel dalam rutinitas panggilan. Penelepon harus memberikan alamat variabel yang akan diatur (secara teknis pointer ke ariable), dan fungsi dipanggil harus menyatakan parameter untuk menjadi pointer dan mengakses variabel secara tidak langsung melalui itu. Kami akan mencakup petunjuk dalam Bab 5.
Cerita ini berbeda untuk array. Ketika nama array digunakan sebagai argumen, nilai dilewatkan ke fungsi adalah lokasi atau alamat dari awal array - tidak ada menyalin elemen array. Dengan subscripting nilai ini, fungsi tersebut dapat mengakses dan mengubah argumen array. Ini adalah topik pada bagian berikutnya.
Array karakter
Jenis yang paling umum dari array dalam C adalah array karakter. Untuk menggambarkan penggunaan karakter array dan fungsi untuk memanipulasi mereka, mari kita menulis sebuah program yang membaca satu set baris teks dan mencetak terpanjang. Garis ini cukup sederhana:
while (there's another line)
if (it's longer than the previous longest) (save it)
(save its length)print longest line
Garis ini membuat jelas bahwa program membagi secara alami menjadi potongan-potongan. One piece mendapatkan baris baru, yang lain menyimpannya, dan sisanya mengontrol proses.
Karena hal membagi begitu baik, itu akan baik untuk menulis mereka seperti itu juga. Oleh karena itu, mari kita menulis fungsi getline terpisah untuk mengambil baris berikutnya dari input. Kami akan mencoba untuk membuat fungsi yang berguna dalam konteks lain. Minimal, getline harus mengembalikan sinyal tentang kemungkinan akhir file, desain yang lebih berguna akan mengembalikan panjang garis, atau nol jika akhir file ditemui. Nol adalah diterima end-of-file kembali karena tidak pernah panjang garis valid. Setiap baris teks memiliki setidaknya satu karakter, bahkan garis yang hanya berisi baris baru memiliki panjang 1.
Ketika kita menemukan garis yang lebih panjang dari garis terpanjang sebelumnya, harus disimpan di suatu tempat. Hal ini menunjukkan fungsi kedua, copy, untuk menyalin baris baru ke tempat yang aman.
Akhirnya, kita membutuhkan sebuah program utama untuk mengontrol getline dan copy.
Berikut adalah hasilnya.
#include
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/*print the longest input line*/
main()
{
int len; /*current line length*/
int max; /*maximum length seen so far*/
char line[MAXLINE]; /* longest line saved here */
max=0;
while((len=getline(line, MAXLINE))>0)
if(len>max){
max=len;
copy(longest, line);
}
if (max > 0) /* there was a line */ printf("%s", longest);
return 0;
}
/* getline: read a line into s, return length */ int getline(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) s[i] = c;
if (c == '\n') { s[i] = c; ++i;
}
s[i] = '\0'; return i;
}
/* copy: copy 'from' into 'to'; assume to is big enough */ void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0') ++i;
}
Fungsi getline dan copy dideklarasikan pada awal program, yang kita asumsikan terkandung dalam satu file.
utama dan getline berkomunikasi melalui sepasang argumen dan nilai kembali. Dalam getline, argumen dinyatakan oleh garis
int getline(char s[], int lim);
yang menentukan bahwa argumen pertama, s, adalah array, dan yang kedua, lim, adalah bilangan bulat. Tujuan penyediaan ukuran array dalam deklarasi adalah untuk menyisihkan penyimpanan. Panjang array s tidak perlu di getline karena ukurannya diatur dalam utama. menggunakan getline kembali untuk mengirim nilai kembali ke pemanggil, seperti kekuatan fungsi lakukan. Baris ini juga menyatakan bahwa getline mengembalikan sebuah int, karena int adalah tipe kembali default, itu bisa dihilangkan.
Beberapa fungsi mengembalikan nilai yang berguna, yang lainnya, seperti copy, hanya digunakan untuk efek mereka dan kembali nilai. Jenis kembalinya copy batal, yang menyatakan secara eksplisit bahwa tidak ada nilai yang dikembalikan. getline menempatkan karakter '\ 0' (karakter null, yang nilainya nol) pada akhir array itu adalah menciptakan, untuk menandai akhir dari string karakter. Konversi ini juga digunakan oleh bahasa C: ketika string konstan seperti
"hello\n"
muncul dalam sebuah program C, akan disimpan sebagai array dari karakter yang mengandung karakter dalam string dan diakhiri dengan '\ 0' untuk menandai akhir.
Spesifikasi format % s dalam printf mengharapkan argumen yang sesuai untuk menjadi string direpresentasikan dalam bentuk ini . copy juga bergantung pada fakta bahwa argumen input diakhiri dengan ' \ 0 ' , dan salinan karakter ini ke output .
Perlu disebutkan secara sepintas bahwa bahkan sebuah program sekecil satu ini menyajikan beberapa masalah desain lengket . Misalnya, apa yang harus lakukan utama jika menemukan garis yang lebih besar dari batas ? getline bekerja dengan aman , dalam hal ini berhenti ketika mengumpulkan array penuh , bahkan jika tidak ada baris baru telah terlihat . Dengan pengujian panjang dan karakter terakhir kembali , utama dapat menentukan apakah jalur ini terlalu lama , dan kemudian mengatasinya karena keinginan . Dalam kepentingan singkatnya , kita telah mengabaikan masalah ini .
Tidak ada cara untuk pengguna dari getline tahu sebelumnya berapa lama garis masukan mungkin , sehingga pemeriksaan getline untuk overflow . Di sisi lain , pengguna copy sudah tahu ( atau bisa mengetahui ) seberapa besar string , jadi kita telah memilih untuk tidak menambahkan memeriksa untuk itu error .
Latihan . Merevisi rutin utama dari program terpanjang -line sehingga benar akan mencetak panjang jalur input panjang sewenang-wenang , dan sebanyak mungkin teks.
Latihan . Tulis program untuk mencetak semua baris input yang lebih panjang dari 80 karakter .
Latihan . Menulis sebuah program untuk menghapus trailing kosong dan tab dari setiap baris masukan , dan menghapus baris yang sama sekali kosong .
Latihan . Tulis terbalik fungsi ( s ) yang membalikkan string karakter s . Gunakan untuk menulis sebuah program yang membalikkan input garis pada suatu waktu .
Variabel eksternal dan Ruang Lingkup ( External Variables and Scope)
Variabel dalam utama , seperti garis , terpanjang , dan lain-lain , pribadi atau lokal untuk utama. Karena mereka dinyatakan dalam utama, ada fungsi lain dapat memiliki akses langsung kepada mereka . Hal yang sama juga terjadi pada variabel dalam fungsi lain , misalnya , variabel i dalam getline tidak berhubungan dengan i di copy . Setiap variabel lokal dalam fungsi datang ke dalam keberadaan hanya bila fungsi ini dipanggil , dan menghilang ketika fungsi keluar . Inilah sebabnya mengapa variabel seperti biasanya dikenal sebagai variabel otomatis , mengikuti istilah dalam bahasa lain . Kami akan menggunakan istilah otomatis selanjutnya untuk merujuk pada variabel lokal . ( Bab 4 membahas kelas penyimpanan statis , di mana variabel lokal yang mempertahankan nilai-nilai mereka antara panggilan . Karena variabel otomatis datang dan pergi dengan fungsi doa , mereka tidak mempertahankan nilai-nilai mereka dari satu panggilan ke yang berikutnya , dan harus secara eksplisit diatur pada setiap entri . Jika mereka tidak diatur , mereka akan berisi sampah .
Sebagai alternatif untuk variabel otomatis , adalah mungkin untuk mendefinisikan variabel yang bersifat eksternal ke semua fungsi , yaitu , variabel yang dapat diakses oleh nama oleh fungsi apapun . ( Mekanisme ini agak seperti Fortran UMUM atau variabel Pascal dideklarasikan pada blok terluar . ) Karena variabel eksternal yang secara global dapat diakses , mereka dapat digunakan sebagai pengganti dari daftar argumen untuk berkomunikasi data antara fungsi . Selanjutnya, karena variabel eksternal tetap eksis secara permanen , daripada muncul dan menghilang sebagai fungsi dipanggil dan keluar , mereka mempertahankan nilai-nilai mereka bahkan setelah fungsi yang mengatur mereka telah kembali .
Variabel eksternal harus didefinisikan , tepat satu kali , di luar fungsi apapun, ini menyisihkan penyimpanan untuk itu . Variabel juga harus dinyatakan dalam setiap fungsi yang ingin mengaksesnya , ini menyatakan jenis variabel . Deklarasi tersebut mungkin merupakan pernyataan extern eksplisit atau mungkin implisit dari konteks . Untuk membuat beton diskusi , mari kita menulis ulang program terpanjang -line dengan garis , terpanjang , dan max sebagai variabel eksternal . Hal ini memerlukan mengubah panggilan , deklarasi , dan tubuh semua tiga fungsi .
#include
#define MAXLINE 1000 /*maximum input line size*/
int max; /*maximum length seen so far*/
char line[MAXLINE]; /*current input line*/
char longest[MAXLINE]; /*longest line saved here*/
int getline(void);
void copy(void); /* print longest input line; specialized version */
main()
{
int len;
extern int max;
extern char longest[];
max = 0;while ((len = getline()) > 0) if (len > max) {
max = len; copy();
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* getline: specialized version */
int getline(void)
{
int c, i;
extern char line[];
for (i = 0; i < MAXLINE - 1
&& (c=getchar)) != EOF && c != '\n'; ++i) line[i] = c;
if (c == '\n') { line[i] = c; ++i;
}
line[i] = '\0'; return i;
}
/* copy: specialized version */
void copy(void)
{
int i;
extern char line[], longest[];
i = 0;
while ((longest[i] = line[i]) != '\0') ++i;
}
Variabel eksternal utama, getline dan copy didefinisikan oleh baris pertama dari contoh di atas , yang menyatakan jenis mereka dan menyebabkan penyimpanan dialokasikan untuk mereka . Sintaksis , definisi eksternal seperti definisi variabel lokal , tapi karena mereka terjadi di luar fungsi , variabel eksternal . Sebelum fungsi dapat menggunakan variabel eksternal , nama variabel harus diketahui fungsinya; deklarasi adalah sama seperti sebelumnya kecuali untuk kata kunci extern ditambahkan .
Dalam keadaan tertentu , deklarasi extern dapat dihilangkan . Jika definisi dari variabel eksternal terjadi pada file sumber sebelum penggunaannya dalam fungsi tertentu , maka tidak ada kebutuhan untuk deklarasi extern dalam fungsi. Deklarasi extern dalam utama, getline dan copy dengan demikian berlebihan . Bahkan , praktek umum adalah untuk menempatkan definisi dari semua variabel eksternal pada awal file sumber , dan kemudian menghilangkan semua deklarasi extern .
Jika program ini dalam beberapa file sumber , dan variabel didefinisikan dalam file1 dan digunakan dalam file2 file3 dan , maka deklarasi extern diperlukan dalam file2 file3 dan untuk menghubungkan kejadian dari variabel. Praktek yang biasa adalah untuk mengumpulkan deklarasi extern variabel dan fungsi dalam file terpisah , secara historis disebut header , yang disertakan dengan # include di depan setiap file sumber . Akhiran . H adalah konvensional untuk nama sundulan . Fungsi perpustakaan standar , misalnya , dinyatakan dalam header seperti
Sejak versi khusus getline dan copy tidak memiliki argumen , logika akan menunjukkan bahwa prototipe mereka pada awal file harus getline ( ) dan copy ( ) . Tapi untuk kompatibilitas dengan program C yang lebih tua standar mengambil daftar kosong sebagai deklarasi gaya lama , dan mematikan semua daftar argumen pemeriksaan ; kekosongan kata harus digunakan untuk daftar secara eksplisit kosong . Kita akan membahas ini lebih lanjut dalam Bab 4 .
Anda harus mencatat bahwa kita menggunakan definisi kata-kata dan pernyataan hati-hati ketika kita merujuk ke variabel eksternal di bagian ini `` Definition '' mengacu pada tempat di mana variabel dibuat atau ditugaskan penyimpanan ; . `` Deklarasi '' mengacu pada tempat di mana sifat variabel dinyatakan tetapi tidak ada penyimpanan dialokasikan .
By the way , ada kecenderungan untuk membuat segala sesuatu yang terlihat variabel extern karena muncul untuk menyederhanakan komunikasi - daftar argumen pendek dan variabel selalu ada ketika Anda ingin mereka . Tetapi variabel eksternal selalu ada bahkan ketika Anda tidak ingin mereka . Terlalu mengandalkan variabel eksternal yang penuh dengan bahaya karena mengarah pada program yang datanya koneksi tidak semua jelas - variabel dapat diubah dengan cara yang tak terduga dan bahkan sengaja , dan program ini sulit untuk memodifikasi . Versi kedua dari program terpanjang -line lebih rendah daripada yang pertama , sebagian untuk alasan ini , dan sebagian karena ia menghancurkan sifat umum dari dua fungsi yang berguna dengan menulis ke dalamnya nama-nama variabel mereka memanipulasi .
Pada titik ini kita telah membahas apa yang bisa disebut inti konvensional C. Dengan segelintir ini blok bangunan , itu mungkin untuk menulis program yang berguna yang cukup besar , dan itu mungkin akan menjadi ide yang baik jika Anda berhenti cukup lama untuk melakukannya . Latihan ini menunjukkan program kompleksitas agak lebih besar dari yang sebelumnya dalam bab ini .
Latihan . Tulis detab program yang menggantikan tab di input dengan jumlah yang tepat dari ruang kosong untuk ke halte tab berikutnya . Asumsikan seperangkat tetap tab berhenti , mengatakan setiap kolom n . Harus n menjadi variabel atau parameter simbolis ?
Latihan . Tulis entab program yang menggantikan string kosong dengan jumlah minimal tab dan kosong untuk mencapai jarak yang sama . Gunakan berhenti tab yang sama seperti untuk detab . Ketika salah satu tab atau kosong tunggal akan cukup untuk mencapai berhenti tab , yang harus diberikan preferensi ?
Latihan . Menulis sebuah program untuk `` lipat '' baris input panjang menjadi dua atau lebih pendek baris setelah karakter non - kosong terakhir yang terjadi sebelum kolom ke-n dari input. Pastikan program anda melakukan sesuatu yang cerdas dengan garis yang sangat panjang , dan jika tidak ada kekosongan atau tab sebelum kolom tertentu .
Latihan . Menulis sebuah program untuk menghapus semua komentar dari program C . Jangan lupa untuk menangani string dikutip dan konstanta karakter dengan benar . C Komentar tidak bersarang .
Latihan . Tulis program untuk memeriksa program C untuk kesalahan sintaks dasar seperti kurung tak tertandingi , tanda kurung dan kawat gigi . Jangan lupa tentang tanda kutip , baik tunggal dan ganda , escape sequence , dan komentar . (Program ini sulit jika Anda melakukannya di umum penuh. )
By Gonoh
Komentar