คำถามติดแท็ก c

C เป็นภาษาโปรแกรมทั่วไปที่ใช้สำหรับการเขียนโปรแกรมระบบ (ระบบปฏิบัติการและฝังตัว), ห้องสมุด, เกมและข้ามแพลตฟอร์ม แท็กนี้ควรใช้กับคำถามทั่วไปที่เกี่ยวข้องกับภาษา C ตามที่กำหนดไว้ในมาตรฐาน ISO 9899 (เวอร์ชันล่าสุด 9899: 2018 เว้นแต่ระบุไว้เป็นอย่างอื่น - นอกจากนี้ยังติดแท็กคำขอเฉพาะรุ่นด้วย c89, c99, c11 ฯลฯ ) C แตกต่างจาก C ++ และไม่ควรใช้ร่วมกับแท็ก C ++ หากไม่มีเหตุผล

7
เหตุใดฉันไม่สามารถเข้าถึงตัวชี้ไปยังตัวชี้สำหรับสแต็กอาเรย์
โปรดดูรหัสต่อไปนี้ มันพยายามที่จะส่งผ่านอาร์เรย์เป็นchar**ฟังก์ชั่น: #include <stdio.h> #include <stdlib.h> static void printchar(char **x) { printf("Test: %c\n", (*x)[0]); } int main(int argc, char *argv[]) { char test[256]; char *test2 = malloc(256); test[0] = 'B'; test2[0] = 'A'; printchar(&test2); // works printchar((char **) &test); // crashes because *x in printchar() has an invalid pointer free(test2); …
35 c 

4
อัลกอริทึม strcasecmp มีข้อบกพร่องหรือไม่
ฉันกำลังพยายามปรับใช้strcasecmpฟังก์ชันใน C อีกครั้งและฉันสังเกตว่าสิ่งใดที่ดูเหมือนจะไม่สอดคล้องกันในกระบวนการเปรียบเทียบ จาก man strcmp ฟังก์ชั่น strcmp () เปรียบเทียบสองสตริง s1 และ s2 โลแคลไม่ถูกนำมาพิจารณา (สำหรับการเปรียบเทียบที่รับรู้โลแคลโปรดดู strcoll (3)) มันจะคืนค่าจำนวนเต็มน้อยกว่าเท่ากับหรือมากกว่าศูนย์ถ้าพบ s1 ตามลำดับจะน้อยกว่าเพื่อจับคู่หรือมากกว่า s2 จาก man strcasecmp strcasecmp () ฟังก์ชั่นทำการเปรียบเทียบไบต์โดยไบต์ของสตริง s1 และ s2 โดยไม่สนใจกรณีของตัวละคร มันจะคืนค่าจำนวนเต็มน้อยกว่าเท่ากับหรือมากกว่าศูนย์ถ้าพบ s1 ตามลำดับจะน้อยกว่าเพื่อจับคู่หรือมากกว่า s2 int strcmp(const char *s1, const char *s2); int strcasecmp(const char *s1, const char *s2); รับข้อมูลนี้ฉันไม่เข้าใจผลลัพธ์ของรหัสต่อไปนี้: …
34 c  strcmp 

7
การเปรียบเทียบตัวชี้ทำงานใน C อย่างไร การเปรียบเทียบพอยน์เตอร์ที่ไม่ได้ชี้ไปที่อาเรย์นั้นเป็นสิ่งที่ดีหรือไม่?
ใน K&R (ภาษาการเขียนโปรแกรม C รุ่นที่ 2) บทที่ 5 ฉันอ่านต่อไปนี้: ขั้นแรกให้เปรียบเทียบตัวชี้ภายใต้สถานการณ์บางอย่าง ถ้าpและqชี้ไปที่สมาชิกของอาร์เรย์เดียวกันแล้วความสัมพันธ์ที่ชอบ==, !=, <, >=ฯลฯ การทำงานอย่างถูกต้อง ซึ่งดูเหมือนว่าบ่งบอกว่ามีเพียงพอยน์เตอร์ที่ชี้ไปยังอาร์เรย์เดียวกันเท่านั้นที่สามารถเปรียบเทียบได้ อย่างไรก็ตามเมื่อฉันลองใช้รหัสนี้ char t = 't'; char *pt = &t; char x = 'x'; char *px = &x; printf("%d\n", pt > px); 1 ถูกพิมพ์ไปที่หน้าจอ ก่อนอื่นฉันคิดว่าฉันจะไม่ได้กำหนดหรือบางประเภทหรือข้อผิดพลาดเพราะptและpxไม่ได้ชี้ไปที่อาร์เรย์เดียวกัน (อย่างน้อยก็ในความเข้าใจของฉัน) เป็นpt > pxเพราะพอยน์เตอร์ทั้งสองชี้ไปที่ตัวแปรที่เก็บอยู่ในสแต็กและสแต็กโตขึ้นดังนั้นที่อยู่หน่วยความจำของtมากกว่าที่อยู่x? อะไรคือสาเหตุที่pt > pxแท้จริง ฉันสับสนมากขึ้นเมื่อนำ malloc เข้ามานอกจากนี้ใน …

4
เธรดถูกคัดลอกเมื่อเรียก fork หรือไม่?
หากฉันมีโปรแกรมที่รันด้วยเธรดและเรียกใช้fork()บนระบบที่ใช้ระบบปฏิบัติการยูนิกซ์ระบบจะคัดลอกเธรดหรือไม่ ฉันรู้ว่าหน่วยความจำเสมือนสำหรับกระบวนการปัจจุบันจะถูกคัดลอก 1: 1 ไปยังกระบวนการใหม่ที่เกิดขึ้น ฉันรู้ว่าเธรดมีสแต็กของตนเองในหน่วยความจำเสมือนของกระบวนการ ดังนั้นอย่างน้อยสแต็กของเธรดควรถูกคัดลอกด้วยเช่นกัน อย่างไรก็ตามฉันไม่ทราบว่ามีเธรดอื่น ๆ อีกมากมายที่ไม่ได้อยู่ในหน่วยความจำเสมือนและไม่ได้คัดลอกไป หากไม่มีให้ทำกระบวนการทั้งสองแบ่งปันหัวข้อหรือพวกเขาเป็นอิสระคัดลอก?

6
วิธีที่ถูกต้องในการแปลง 2 ไบต์เป็นจำนวนเต็ม 16 บิตที่ลงนามคืออะไร?
ในคำตอบนี้ , zwolทำให้การเรียกร้องนี้: วิธีที่ถูกต้องในการแปลงข้อมูลสองไบต์จากแหล่งข้อมูลภายนอกให้เป็นจำนวนเต็ม 16 บิตที่มีลายเซ็นคือฟังก์ชันผู้ช่วยเช่นนี้ #include <stdint.h> int16_t be16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 8) | (((uint32_t)data[1]) << 0); return ((int32_t) val) - 0x10000u; } int16_t le16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 0) | (((uint32_t)data[1]) << 8); return ((int32_t) val) - …

1
ทำไมการเขียนทิ้งไบต์ 4K อย่างต่อเนื่องในบัฟเฟอร์
ฉันมีรหัสต่อไปนี้เป็นหลัก: int fileWrite(int file, void * pBuffer, size_t size) { size_t bytesWritten = (size_t)write( file, pBuffer, size ) ; if (bytesWritten != size) { return -1; } return 0; } มันทำงานได้ถ้าขนาดคือ 1GB แต่เมื่อขนาดเป็น ~ 2GB มันจะเหลือ 4K ไบต์อย่างสม่ำเสมอ ฉันสามารถแก้ไขได้โดยการเขียนการวนซ้ำและย้ายบัฟเฟอร์ขึ้น แต่ฉันอยากรู้ว่าทำไมมันล้มเหลวอยู่เสมอ ตัวอย่างเช่นถ้าขนาดคือ 2147483648 เขียนเฉพาะเขียน 2147479552 ปล่อย 4096 ไม่ได้เขียน ทำไมสิ่งนี้ถึงเกิดขึ้นและถูกต้องหรือไม่ที่จะเขียนการวนซ้ำ
30 c  linux  system-calls 

4
(…) เรียกใน C และ C ++ คืออะไร
หนึ่งของการใช้งานของ...คือการแสดงvariadicหน่วยงานใน C และ C ++ มันชื่ออะไร? มันจัดอยู่ในประเภทโอเปอเรเตอร์หรืออย่างอื่นเมื่อใช้งานในลักษณะนั้นหรือไม่? รายละเอียดอื่น ๆ เกี่ยวกับ...? แก้ไข:...ฉันรู้ว่าวัตถุประสงค์ของการ ฉันถามชื่อและการจำแนกซึ่งฉันหวังว่าจะคล้ายกันในทั้ง C และ C ++

2
ทำไมไวยากรณ์ BNF ของ C อนุญาตการประกาศด้วยชุดคำสั่ง init ที่ว่างเปล่า
เมื่อมองผ่าน BNF ไวยากรณ์ของ C ฉันคิดว่ามันแปลกที่กฎการผลิตสำหรับการประกาศมีลักษณะเช่นนี้ (ตามhttps://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of% 20C% 20in% 20Backus-Naur% 20form.htm ): <declaration> ::= {<declaration-specifier>}+ {<init-declarator>}* ; ใช้ทำไม*ปริมาณ (หมายถึงศูนย์หรือมากกว่าเกิดขึ้น) สำหรับinit-declarator? สิ่งนี้อนุญาตให้ใช้ข้อความเช่นint;หรือvoid;เพื่อให้มีความถูกต้องทางไวยากรณ์แม้ว่าจะไม่ถูกต้องทางอรรถศาสตร์ พวกเขาไม่สามารถใช้ตัว+นับจำนวน (อย่างน้อยหนึ่งเหตุการณ์) แทน*กฎการผลิตได้หรือไม่ ฉันพยายามคอมไพล์โปรแกรมอย่างง่ายเพื่อดูว่าคอมไพเลอร์เอาท์พุทอะไรและมันทำอะไรเป็นคำเตือน การป้อนข้อมูล: int main(void) { int; } เอาท์พุท: test.c: In function ‘main’: test.c:2:5: warning: useless type name in empty declaration int; ^~~

2
การเพิ่มประสิทธิภาพที่ไม่คาดคิดของ strlen เมื่อสร้างสมนามอาร์เรย์ 2 มิติ
นี่คือรหัสของฉัน: #include <string.h> #include <stdio.h> typedef char BUF[8]; typedef struct { BUF b[23]; } S; S s; int main() { int n; memcpy(&s, "1234567812345678", 17); n = strlen((char *)&s.b) / sizeof(BUF); printf("%d\n", n); n = strlen((char *)&s) / sizeof(BUF); printf("%d\n", n); } ใช้ GCC 8.3.0 หรือ 8.2.1 ที่มีระดับการเพิ่มประสิทธิภาพใด ๆ ยกเว้น-O0ผลผลิตนี้เมื่อผมคาดหวังว่า0 …

4
เป็นโมฆะ * ฟังก์ชั่น () ตัวชี้ไปยังฟังก์ชั่นหรือฟังก์ชั่นกลับเป็นโมฆะ *?
void *function()ฉันสับสนเกี่ยวกับความหมายของ มันเป็นตัวชี้ไปยังฟังก์ชั่นหรือฟังก์ชั่นกลับมาvoid*? ฉันมักจะใช้มันในโครงสร้างข้อมูลเป็นฟังก์ชั่นซ้ำเรียกคืนตัวชี้ แต่เมื่อฉันเห็นรหัสใน multithreading ( pthread) มีการประกาศฟังก์ชั่นเดียวกัน ตอนนี้ฉันสับสนว่าอะไรคือความแตกต่างระหว่างพวกเขา

3
C มีค่า std :: น้อยกว่าจาก C ++ หรือไม่
ฉันเพิ่งตอบคำถามเกี่ยวกับพฤติกรรมที่ไม่ได้กำหนดของการทำp < qใน C เมื่อpและqเป็นตัวชี้ไปยังวัตถุ / อาร์เรย์ที่แตกต่างกัน นั่นทำให้ฉันคิดว่า: C ++ มีพฤติกรรมเหมือนกัน (ไม่ได้กำหนด) <ในกรณีนี้ แต่ยังมีเท็มเพลตไลบรารีมาตรฐานstd::lessซึ่งรับประกันว่าจะส่งคืนสิ่งเดียวกันกับ<ที่สามารถเปรียบเทียบตัวชี้และส่งคืนการสั่งซื้อบางอย่างที่ไม่สอดคล้อง C เสนอบางสิ่งที่มีฟังก์ชั่นคล้ายกันซึ่งจะช่วยให้เปรียบเทียบตัวชี้ตามอำเภอใจ (กับประเภทเดียวกัน) ได้อย่างปลอดภัยหรือไม่? ฉันพยายามมองผ่านมาตรฐาน C11 และไม่พบอะไรเลย แต่ประสบการณ์ของฉันใน C คือขนาดที่เล็กกว่า C ++ ดังนั้นฉันอาจจะพลาดอะไรบางอย่างได้อย่างง่ายดาย

1
ความหมายของวัตถุที่ทับซ้อนกันใน C คืออะไร?
พิจารณาโครงสร้างต่อไปนี้: struct s { int a, b; }; โดยทั่วไป1 โครงสร้างนี้จะมีขนาด 8 และการจัดตำแหน่ง 4 จะเกิดอะไรขึ้นถ้าเราสร้างstruct sวัตถุสองชิ้น (แม่นยำยิ่งกว่านั้นเราเขียนลงในวัตถุสองหน่วยดังกล่าวที่จัดสรรแล้ว) โดยที่วัตถุที่สองซ้อนทับวัตถุแรก char *storage = malloc(3 * sizeof(struct s)); struct s *o1 = (struct s *)storage; // offset 0 struct s *o2 = (struct s *)(storage + alignof(struct s)); // offset 4 // now, o2 …

5
ผลการดำเนินงานระดับบิตในขนาดตัวแปรที่ไม่คาดคิด
บริบท เรากำลังพอร์ตโค้ด C ที่คอมไพล์แล้วโดยใช้คอมไพเลอร์ C แบบ 8 บิตสำหรับไมโครคอนโทรลเลอร์ PIC สำนวนทั่วไปที่ใช้เพื่อป้องกันตัวแปรโกลบอลที่ไม่ได้ลงชื่อ (ตัวอย่างเช่นตัวนับข้อผิดพลาด) จากการย้อนกลับเป็นศูนย์มีดังต่อไปนี้: if(~counter) counter++; ผู้ประกอบการระดับบิตที่นี่กลับค่าบิตทั้งหมดและคำสั่งเป็นจริงหากcounterน้อยกว่าค่าสูงสุด ที่สำคัญทำงานได้โดยไม่คำนึงถึงขนาดของตัวแปร ปัญหา ตอนนี้เรากำลังกำหนดเป้าหมายหน่วยประมวลผล ARM แบบ 32 บิตโดยใช้ GCC เราสังเกตเห็นว่ารหัสเดียวกันให้ผลลัพธ์ที่แตกต่าง เท่าที่เราสามารถบอกได้ดูเหมือนว่าการทำงานส่วนเสริม bitwise คืนค่าที่มีขนาดแตกต่างจากที่เราคาดไว้ ในการทำซ้ำสิ่งนี้เรารวบรวมใน GCC: uint8_t i = 0; int sz; sz = sizeof(i); printf("Size of variable: %d\n", sz); // Size of variable: 1 sz = …

2
การทดสอบการหารได้เร็วขึ้นกว่าตัวดำเนินการ%
ฉันสังเกตเห็นสิ่งที่อยากรู้ในคอมพิวเตอร์ของฉัน *การทดสอบการหารด้วยลายมือเขียนเร็วกว่า%ผู้ปฏิบัติงานอย่างมาก ลองพิจารณาตัวอย่างน้อยที่สุด: * AMD Ryzen Threadripper 2990WX, GCC 9.2.0 static int divisible_ui_p(unsigned int m, unsigned int a) { if (m <= a) { if (m == a) { return 1; } return 0; } m += a; m >>= __builtin_ctz(m); return divisible_ui_p(m, a); } ตัวอย่างที่ถูก จำกัด ด้วยแปลกและa m > …

1
gcc-10.0.1 Segfault เฉพาะ
ฉันมีแพ็คเกจ R ที่มีโค้ดที่คอมไพล์ C ซึ่งค่อนข้างเสถียรมาระยะหนึ่งแล้วและได้รับการทดสอบกับแพลตฟอร์มและคอมไพเลอร์ที่หลากหลาย (windows / osx / debian / fedora gcc / clang) เมื่อเร็ว ๆ นี้มีการเพิ่มแพลตฟอร์มใหม่เพื่อทดสอบแพคเกจอีกครั้ง: Logs from checks with gcc trunk aka 10.0.1 compiled from source on Fedora 30. (For some archived packages, 10.0.0.) x86_64 Fedora 30 Linux FFLAGS="-g -O2 -mtune=native -Wall -fallow-argument-mismatch" CFLAGS="-g -O2 -Wall -pedantic …

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.