ผลลัพธ์ของรหัส C นี้คือ 49 แต่ใครสามารถอธิบายฉันได้บ้าง [ซ้ำ]

Jan 20 2021
#include <stdio.h>

#define CUBE(x) (x * x * x)

int main() {
    printf("%d", CUBE(4+5));
    return 0;
}

คำตอบ

5 MarkSouls Jan 20 2021 at 14:31

มาโครจะเปลี่ยนรหัสเป็น:

printf("%d", (4+5 * 4+5 * 4+5));

ซึ่งมีประสิทธิภาพ:

printf("%d", 4 + (5*4) + (5*4) + 5); // 29

หากคุณต้องการก้อน9ที่จะได้รับคุณควรเขียน729CUBE((4+5))

9 chqrlie Jan 20 2021 at 14:34

นี่คือวิธีขยายมาโครในระหว่างกระบวนการคอมไพล์:

printf("%d", (4+5 * 4+5 * 4+5));

เนื่องจาก*มีลำดับความสำคัญสูงกว่า+นิพจน์นี้จึงถูกประเมินว่า(4 + (5 * 4) + (5 * 4) + 5)สร้างขึ้น49แทนที่จะเป็นที่คาด729ไว้

เพื่อหลีกเลี่ยงปัญหาลำดับความสำคัญของตัวดำเนินการดังกล่าวอาร์กิวเมนต์แมโครทั้งหมดจะต้องอยู่ในวงเล็บในนิยามมาโครเช่นเดียวกับนิพจน์เอง:

#define CUBE(x)  ((x) * (x) * (x))

อย่างไรก็ตามโปรดทราบว่าการขยายตัวของการCUBEประเมินxหลายครั้งซึ่งเป็นปัญหาหากอาร์กิวเมนต์มาโครมีผลข้างเคียงเช่นCUBE(i++).

เพื่อหลีกเลี่ยงปัญหาเหล่านี้ทั้งหมดให้ใช้ฟังก์ชันและปล่อยให้คอมไพเลอร์ปรับให้เหมาะสม:

int cube(int x) {
    return x * x * x;
}

คุณสามารถเพิ่มstatic inlineหน้านิยามฟังก์ชันนี้ได้ แต่เครื่องมือเพิ่มประสิทธิภาพสมัยใหม่จะยังคงแทรกฟังก์ชันไว้โดยไม่มีสิ่งนี้

3 Tecto Jan 20 2021 at 14:32

ตัวประมวลผลก่อนหน้า C จะแทนที่อินสแตนซ์ทั้งหมดของ x เป็น 4 + 5 ตามตัวอักษรซึ่งส่งผลให้เกิดรหัสต่อไปนี้:

i = 4+5*4+5*4+5;

(การคูณก่อนแล้วจึงบวก)

3 SahadatHossain Jan 20 2021 at 14:31

คุณจะต้องให้การป้อนข้อมูลเช่นถ้าคุณต้องการที่จะเพิ่มตัวเลขแล้วส่งไปที่CUBE((4+5)) CUBEสาเหตุ TH CUBE(4+5)มีการขยายพื้นเพื่อ4+5*4+5*4+5เป็นมันชุดทั้งในสถานที่ของ4+5 xดังนั้น4+5*4+5*4+5= คูณมาก่อนแล้วเพิ่มพวกเขาจะให้4+20+20+549

กำหนดมาโครตามที่#define CUBE(x) ((x)*(x)*(x))เป็นจริงขั้นแรกให้(4+5)ดำเนินการสำหรับทุก ๆ ครั้ง(x)แล้วจึงทำการ*ดำเนินการ

อีกวิธีหนึ่งคือใช้CUBE((4+5))ในขณะที่เรียกมาโครโดยพื้นฐานแล้วจะเพิ่มตัวเลขสองตัวและ(4+5)= 9แล้วทำCUBE(9)เช่น:

#include<stdio.h>
#define CUBE(x) (x * x * x)

int main( )
{
    printf("%d", CUBE((4+5)));
    return 0;
}
1 BasileStarynkevitch Jan 20 2021 at 14:29

อ่านสมัยใหม่ Cแล้วn1570 C ร่างมาตรฐานและเอกสารของGCCและGDBและCPP ดูเว็บไซต์อ้างอิง C นี้ด้วย

รับแรงบันดาลใจจากที่มีอยู่โครงการโอเพนซอร์สเช่นบนGitHubหรือซอฟแวร์ GNU

ด้วยคอมไพเลอร์GCCล่าสุดให้เรียกใช้เป็นgcc -Wall -Wextra -gไฟล์. ใช้-C -Eตัวเลือกเพื่อรับแบบฟอร์มที่ประมวลผลล่วงหน้า

คุณอาจสนใจโดยส่วนขยายstatement-exprของ GCC

คุณCUBE(4+5)จะมหภาคขยายไป4+5*4+5*4+5ซึ่งจะคำนวณ4+(5*4)+(5*4)+5ตามแบบอย่างของผู้ประกอบการ C

พิจารณาการเข้ารหัสstatic inlineฟังก์ชันเช่น

static inline int cube(int x) { return x*x*x; }

หรือถ้าคุณต้องการมาโครอย่างน้อย

#define CUBE(X) ((X)*(X)*(X))

ซึ่งจะใช้งานได้ไม่ดีนักCUBE(i++)(ในขณะที่ใช้inlineฟังก์ชั่นcube(i++)ทำในสิ่งที่คุณต้องการให้ทำ: เพิ่มiครั้งเดียว!)

BTW คุณสามารถใช้GPPหรือGNU m4 (หรือเครื่องกำเนิดไฟฟ้าของคุณเองหรือGNU bison ) เพื่อสร้างรหัส C ตามหลักทั่วไปให้คิดด้วยAST s: เมื่อคุณสร้างรหัส C จะปล่อยวงเล็บที่ไร้ประโยชน์มากมายเช่นในChicken Scheme , SWIGหรือในCAIAหรือในmanydl.cของฉัน

คุณยังสามารถใช้Clang static analyzerกับโค้ดของคุณได้ (และอาจจะเป็นFrama-C )

คุณอาจจะสนใจในการอ่านแนวทางการเข้ารหัสบางอย่างเช่นMISRA Cหรือคน GNU