Output dari kode C ini adalah 49 tetapi dapatkah seseorang menjelaskan caranya? [duplikat]
#include <stdio.h>
#define CUBE(x) (x * x * x)
int main() {
printf("%d", CUBE(4+5));
return 0;
}
Jawaban
Makro akan mengubah kode menjadi:
printf("%d", (4+5 * 4+5 * 4+5));
yang secara efektif:
printf("%d", 4 + (5*4) + (5*4) + 5); // 29
Jika Anda ingin 9
mendapatkan kubus 729
, Anda harus menulis CUBE((4+5))
.
Berikut adalah cara makro diperluas selama proses kompilasi:
printf("%d", (4+5 * 4+5 * 4+5));
Karena *
memiliki prioritas yang lebih tinggi daripada +
, ekspresi ini dievaluasi sebagai (4 + (5 * 4) + (5 * 4) + 5)
, menghasilkan, 49
bukan yang diharapkan 729
.
Untuk menghindari masalah prioritas operator seperti itu, semua argumen makro harus diberi tanda kurung dalam definisi makro serta ekspresi itu sendiri:
#define CUBE(x) ((x) * (x) * (x))
Namun perlu diperhatikan bahwa perluasan CUBE
evaluasi ini x
beberapa kali, yang menjadi masalah jika argumen makro memiliki efek samping, seperti CUBE(i++)
.
Untuk menghindari semua masalah ini, gunakan sebuah fungsi dan biarkan compiler mengoptimalkannya:
int cube(int x) {
return x * x * x;
}
Anda dapat menambahkan static inline
di depan definisi fungsi ini, tetapi pengoptimal modern akan tetap menyebariskan fungsi tanpa ini.
Praprosesor C secara harfiah akan mengganti semua contoh x untuk 4 + 5, menghasilkan kode berikut:
i = 4+5*4+5*4+5;
(perkalian dulu, baru penjumlahan)
Anda perlu memberikan input seperti CUBE((4+5))
jika Anda ingin menambahkan nomor dan kemudian mengirim ke CUBE
. Penyebab th CUBE(4+5)
pada dasarnya diperluas 4+5*4+5*4+5
karena mengatur keseluruhan 4+5
di tempat x
. Jadi, 4+5*4+5*4+5
= 4+20+20+5
karena perkalian datang lebih dulu dan kemudian menjumlahkannya akan menghasilkan 49
.
Tentukan makro seperti #define CUBE(x) ((x)*(x)*(x))
itu sebenarnya pertama-tama lanjutkan (4+5)
operasi untuk setiap (x)
dan kemudian lakukan *
operasi.
Cara lain adalah menggunakan CUBE((4+5))
saat memanggil makro, pada dasarnya pertama-tama tambahkan dua angka dan (4+5)
= 9
lalu lakukan CUBE(9)
, seperti:
#include<stdio.h>
#define CUBE(x) (x * x * x)
int main( )
{
printf("%d", CUBE((4+5)));
return 0;
}
Baca Modern C , lalu standar draf C n1570 , dan dokumentasi GCC dan GDB serta CPP . Lihat juga situs web referensi C ini .
Ambil inspirasi dari proyek sumber terbuka yang ada, misalnya di github , atau perangkat lunak GNU .
Dengan kompiler GCC terbaru , panggil sebagai gcc -Wall -Wextra -g
. Gunakan juga -C -E
opsi untuk mendapatkan formulir yang telah diproses sebelumnya.
Anda mungkin juga tertarik dengan ekstensi pernyataan-expr dari GCC.
Anda CUBE(4+5)
adalah makro-diperluas untuk 4+5*4+5*4+5
yang dihitung sebagai 4+(5*4)+(5*4)+5
menurut didahulukan dari operator C .
Pertimbangkan untuk membuat kode static inline
fungsi seperti
static inline int cube(int x) { return x*x*x; }
atau jika Anda membutuhkan makro, setidaknya
#define CUBE(X) ((X)*(X)*(X))
yang tidak akan berfungsi dengan baik untuk CUBE(i++)
(sementara dengan inline
fungsi, cube(i++)
melakukan apa yang Anda ingin lakukan: kenaikan i
sekali!).
BTW, Anda dapat menggunakan GPP , atau GNU m4 , (atau generator Anda sendiri, atau GNU bison ) untuk menghasilkan beberapa kode C. Sebagai aturan praktis, pikirkan dengan AST : ketika Anda membuat kode C, keluarkan banyak tanda kurung yang tidak berguna, seperti misalnya di Skema Ayam , SWIG , atau di CAIA atau di manydl.c saya
Anda juga dapat menggunakan penganalisis statis Clang pada kode Anda (dan mungkin Frama-C ).
Anda mungkin tertarik membaca beberapa pedoman pengkodean seperti MISRA C atau yang GNU .