Gelagat Menarik Operator Anjakan Kanan
Pengendali anjakan kanan (>>) mempamerkan tingkah laku yang pelik apabila menangani nilai anjakan kanan yang besar . Pertimbangkan program berikut:
<code class="c++">#include <iostream> #include <stdint.h> int foo(int a, int b) { return a >> b; } int bar(uint64_t a, int b) { return a >> b; } int main() { std::cout << "foo(1, 32): " << foo(1, 32) << std::endl; std::cout << "bar(1, 32): " << bar(1, 32) << std::endl; std::cout << "1 >> 32: " << (1 >> 32) << std::endl; //warning std::cout << "(int)1 >> (int)32: " << ((int)1 >> (int)32) << std::endl; //warning }
Output yang dijangkakan untuk foo(1, 32) ialah 0, tetapi secara mengejutkan, ia mengembalikan 1. Ini boleh dikaitkan dengan perkara berikut:
Anjakan Logik lwn. Anjakan Aritmetik
Pada seni bina x86/x86-64, operator anjakan kanan sebenarnya melakukan anjakan kanan logik, yang bermaksud ia mengisi ruang yang kosong bit dengan 0, tanpa mengira tanda operan kiri. Tingkah laku adalah serupa dengan menggunakan >>> b.
Pengoptimuman Pengkompil
Dalam kes foo(1, 32), nilai 32 sedang dihantar ke int, yang dipotong secara berkesan kepada 32 bit. Oleh kerana nilai maksimum yang boleh disimpan oleh int ialah 231-1, anjakan kanan pada asasnya ialah >>> (32 % 32), yang menilai kepada 0.
Tingkah Laku Tidak Ditakrifkan
Piawaian C yang berkaitan menyatakan bahawa "tingkah laku tidak ditentukan" untuk anjakan kanan dengan kiraan yang lebih besar daripada atau sama dengan lebar operan kiri yang dinaikkan pangkat. Dalam kes ini, kedua-dua 1 >> 32 dan (int)1 >> (int)32 mempunyai kiraan lebih besar daripada 32, membawa kepada keputusan yang tidak dapat diramalkan.
Perbezaan dengan bar(1, 32)
Bar fungsi mengambil masa 64-bit integer tidak bertanda, yang dijamin mempunyai lebar lebih besar daripada 32. Oleh itu, anjakan kanan dalam bar tidak dipengaruhi oleh kelakuan tidak ditentukan.
Kesimpulan
Tingkah laku operator anjakan kanan menjadi samar-samar apabila berurusan dengan nilai anjakan yang besar. Pada seni bina x86/x86-64, anjakan ke kanan logik dilakukan, manakala pada ARM, pelaksanaan yang berbeza boleh digunakan. Disebabkan oleh tingkah laku yang tidak ditentukan, hasil anjakan ke kanan dengan kiraan yang lebih besar daripada atau sama dengan lebar operan harus dielakkan dalam kod mudah alih.
Atas ialah kandungan terperinci ## Mengapakah Operator Shift Kanan Menunjukkan Gelagat Tidak Dijangka dengan Nilai Shift Besar?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!