TL; DR
C mewarisi !
dan ~
operator dari bahasa lain. Keduanya &&
dan ||
ditambahkan bertahun-tahun kemudian oleh orang yang berbeda.
Jawaban panjang
Secara historis, C dikembangkan dari bahasa awal B, yang didasarkan pada BCPL, yang didasarkan pada CPL, yang didasarkan pada Algol.
Algol , kakek buyut C ++, Java dan C #, mendefinisikan benar dan salah dengan cara yang terasa intuitif bagi para programmer: "nilai kebenaran yang, dianggap sebagai angka biner (benar sesuai dengan 1 dan salah ke 0), adalah sama dengan nilai integral intrinsik ”. Namun, satu kelemahan dari ini adalah bahwa logis dan bitwise tidak tidak bisa menjadi operasi yang sama: Pada komputer modern apa pun, ~0
sama dengan -1 daripada 1 dan ~1
sama dengan -2 daripada 0. (Bahkan pada beberapa mainframe berusia enam puluh tahun di mana ~0
mewakili - 0 atau INT_MIN
, ~0 != 1
pada setiap CPU yang pernah dibuat, dan standar bahasa C telah mengharuskannya selama bertahun-tahun, sementara sebagian besar bahasa putrinya bahkan tidak repot-repot mendukung tanda-dan-besarnya atau komplemen seseorang sama sekali.)
Algol mengatasi ini dengan memiliki mode berbeda dan menafsirkan operator berbeda dalam mode boolean dan integral. Yaitu, operasi bitwise adalah pada tipe integer, dan operasi logis adalah pada tipe boolean.
BCPL memiliki tipe boolean yang terpisah, tetapi satu not
operator , untuk bitwise dan logical tidak. Cara cikal bakal awal C ini bekerja adalah:
Nilai dari true adalah pola bit yang seluruhnya terdiri dari yang; nilai salah adalah nol.
Catat itu true = ~ false
(Anda akan mengamati bahwa istilah nilai p telah berkembang berarti sesuatu yang sama sekali berbeda dalam bahasa C-keluarga. Kami akan hari ini panggilan itu “objek representasi” di C.)
Definisi ini akan memungkinkan logis dan bitwise untuk tidak menggunakan instruksi bahasa mesin yang sama. Jika C telah menempuh rute itu, file header di seluruh dunia akan mengatakan #define TRUE -1
.
Tetapi bahasa pemrograman B diketik dengan lemah, dan tidak memiliki tipe boolean atau bahkan floating-point. Semuanya setara int
dengan penggantinya, C. Ini membuatnya menjadi ide yang baik bagi bahasa untuk mendefinisikan apa yang terjadi ketika suatu program menggunakan nilai selain benar atau salah sebagai nilai logis. Pertama-tama didefinisikan ekspresi yang benar sebagai "tidak sama dengan nol." Ini efisien pada minicomputer tempat ia berlari, yang memiliki flag nol CPU.
Ada, pada saat itu, sebuah alternatif: CPU yang sama juga memiliki flag negatif, dan nilai kebenaran BCPL adalah -1, jadi B mungkin telah mendefinisikan semua angka negatif sebagai benar dan semua angka non-negatif sebagai kepalsuan. (Ada satu sisa dari pendekatan ini: UNIX, yang dikembangkan oleh orang yang sama pada saat yang sama, mendefinisikan semua kode kesalahan sebagai bilangan bulat negatif. Banyak panggilan sistemnya mengembalikan salah satu dari beberapa nilai negatif kegagalan yang berbeda.) Jadi bersyukurlah: bisa lebih buruk!
Tetapi mendefinisikan TRUE
sebagai 1
dan FALSE
seperti 0
dalam B berarti bahwa identitas true = ~ false
tidak lagi dipegang, dan itu telah menghilangkan ketikan yang kuat yang memungkinkan Algol untuk ambigu antara ekspresi bitwise dan logis. Untuk itu diperlukan operator logis-bukan yang baru, dan desainer memilih !
, mungkin karena sudah tidak sama dengan yang sudah !=
, yang terlihat seperti bar vertikal melalui tanda sama. Mereka tidak mengikuti konvensi yang sama dengan &&
atau ||
karena belum ada satu pun.
Boleh dibilang, mereka harus memiliki: &
operator di B rusak seperti yang dirancang. Di B dan di C, 1 & 2 == FALSE
meskipun 1
dan 2
keduanya adalah nilai-nilai yang benar, dan tidak ada cara intuitif untuk mengekspresikan operasi logis dalam B. Itu adalah satu kesalahan C mencoba untuk memperbaiki sebagian dengan menambahkan &&
dan ||
, tetapi perhatian utama pada saat itu adalah untuk akhirnya mendapatkan hubungan arus pendek, dan membuat program berjalan lebih cepat. Buktinya adalah bahwa tidak ada ^^
: 1 ^ 2
adalah nilai yang benar meskipun kedua operannya benar, tetapi tidak dapat mengambil manfaat dari hubungan arus pendek.