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

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

4
ทำไมฟังก์ชั่นค่าสัมบูรณ์ใน C ไม่ยอมรับอินพุต const?
ใน C ต้นแบบสำหรับฟังก์ชันค่าสัมบูรณ์ (ที่ยอมรับการลอย) คือ float fabsf( float ); ทำไมต้นแบบนี้จึงไม่ยอมรับค่าคงที่เช่นนี้ float fabsf( float const ); fabsf จะไม่เปลี่ยนค่าของอินพุตหรือไม่ หากฉันมีฟังก์ชั่นที่รับอินพุตและเรียกใช้ fabsf ฉันต้องบังคับให้หลีกเลี่ยงการระบุอินพุตเป็น const หรือไม่ วิธีที่เหมาะสมในการจัดการกับความถูกต้อง const ในสถานการณ์นี้คืออะไร?

9
'\ 0' และ printf () ใน C
ในหลักสูตรเบื้องต้นของ C ฉันได้เรียนรู้ว่าในขณะที่การจัดเก็บสตริงจะถูกเก็บไว้ด้วยตัวละคร null \0เมื่อสิ้นสุดมัน แต่ถ้าฉันต้องการที่จะพิมพ์สตริงพูดprintf("hello")แม้ว่าฉันจะพบว่ามันไม่ได้จบลงด้วย\0คำสั่งต่อไปนี้ printf("%d", printf("hello")); Output: 5 แต่นี่ดูเหมือนจะไม่สอดคล้องกันเท่าที่ฉันรู้ว่าตัวแปรเช่นสายอักขระถูกเก็บไว้ในหน่วยความจำหลักและฉันเดาว่าในขณะที่พิมพ์บางอย่างมันอาจถูกเก็บไว้ในหน่วยความจำหลักแล้วทำไมจึงแตกต่างกัน
21 c  printf  stdout  c-strings 

2
มาโครแลมบ์ดาสร้างแลมบ์ดาได้อย่างไร
ฉันพบรหัสชิ้นนี้ใน GitHub แต่ไม่เข้าใจ: #define lambda(ret_type, _body) ({ ret_type _ _body _; }) แล้ว: int (*max)(int, int) = lambda(int, (int x, int y) { return x > y ? x : y; }); int max_value = max(1, 2); // max_value is 2 ขีดล่างทำในสิ่งใด#defineและมันคืนตัวชี้ฟังก์ชันได้อย่างไร

4
ทำไม const char * ไม่ต้องการตัวชี้ไปยังที่อยู่หน่วยความจำ
นี่อาจเป็นคำถามง่าย ๆ แต่ทำไม const char * ไม่จำเป็นต้องระบุที่อยู่หน่วยความจำ ตัวอย่าง: const char* a = "Anthony"; และไม่: const char *a = // Address to const char เหมือนประเภทอื่น ๆ

3
ที่อยู่หน่วยความจำคงที่แบบคงที่ [10] จะสิ้นสุดลงใน 060 เสมอ
ฉันมีโปรแกรม ac ที่มีลักษณะเช่นนี้ main.c #include <stdio.h> #define SOME_VAR 10 static int heap[SOME_VAR]; int main(void) { printf("%p", heap); return 0; } และส่งออกสิ่งนี้เมื่อฉันรันโปรแกรมที่คอมไพล์แล้วสองสามครั้ง 0x58aa7c49060 0x56555644060 0x2f8d1f8e060 0x92f58280060 0x59551c53060 0xd474ed6e060 0x767c4561060 0xf515aeda060 0xbe62367e060 ทำไมมันถึงลงท้ายด้วย 060 เสมอ? และอาร์เรย์เก็บไว้ในกองหรือไม่ แก้ไข: ฉันใช้ Linux และฉันเปิด ASLR ฉันรวบรวมโปรแกรมโดยใช้ gcc
17 c  arrays  memory 

1
เหตุใดที่อยู่ของ __libc_start_main จึงเหมือนกันภายใน GDB แม้ว่า ASLR จะเปิดอยู่
Breakpoint 1, 0x00007ffff7de8060 in __libc_start_main () from /usr/lib/libc.so.6 (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/firstlove/projects/org-ioslide/example/a.out Breakpoint 1, 0x00007ffff7de8060 in __libc_start_main () from /usr/lib/libc.so.6 (gdb) r The program being debugged has been started already. Start it …
16 c  linux  gdb  libc  aslr 

3
เหตุใดขนาดของชนิดข้อมูลจึงแตกต่างกันเมื่อค่าถูกส่งโดยตรงไปยังตัวดำเนินการ sizeof
#include <stdio.h> int main() { char a = 'A'; int b = 90000; float c = 6.5; printf("%d ",sizeof(6.5)); printf("%d ",sizeof(90000)); printf("%d ",sizeof('A')); printf("%d ",sizeof(c)); printf("%d ",sizeof(b)); printf("%d",sizeof(a)); return 0; } ผลลัพธ์คือ: 8 4 4 4 4 1 ทำไมเอาต์พุตต่างกันสำหรับค่าเดียวกัน
15 c  int  sizeof 

1
ทำไม np.dot ไม่แม่นยำ? (อาร์เรย์ n-dim)
สมมติว่าเราใช้np.dotสอง'float32'อาร์เรย์สองมิติ: res = np.dot(a, b) # see CASE 1 print(list(res[0])) # list shows more digits [-0.90448684, -1.1708503, 0.907136, 3.5594249, 1.1374011, -1.3826287] เบอร์ ยกเว้นพวกเขาสามารถเปลี่ยน: กรณีที่ 1 : ฝานa np.random.seed(1) a = np.random.randn(9, 6).astype('float32') b = np.random.randn(6, 6).astype('float32') for i in range(1, len(a)): print(list(np.dot(a[:i], b)[0])) # full shape: (i, 6) [-0.9044868, -1.1708502, …
15 python  c  arrays  numpy  precision 

3
การเรียกใช้ฟังก์ชันที่มีตัวชี้ไปยังไม่ใช่ const และตัวชี้ไปยังอาร์กิวเมนต์ const ของที่อยู่เดียวกัน
ฉันต้องการเขียนฟังก์ชั่นที่ป้อนอาร์เรย์ของข้อมูลและส่งออกอาเรย์อีกหนึ่งข้อมูลโดยใช้พอยน์เตอร์ ฉันสงสัยว่าผลลัพธ์คืออะไรถ้าทั้งคู่srcและdstชี้ไปยังที่อยู่เดียวกันเพราะฉันรู้ว่าคอมไพเลอร์สามารถปรับให้เหมาะสมสำหรับ const มันเป็นพฤติกรรมที่ไม่ได้กำหนดหรือไม่? (ฉันติดแท็กทั้ง C และ C ++ เพราะฉันไม่แน่ใจว่าคำตอบอาจแตกต่างกันหรือไม่และฉันต้องการทราบเกี่ยวกับทั้งคู่) void f(const char *src, char *dst) { dst[2] = src[0]; dst[1] = src[1]; dst[0] = src[2]; } int main() { char s[] = "123"; f(s,s); printf("%s\n", s); return 0; } นอกเหนือจากคำถามข้างต้นแล้วสิ่งนี้ได้กำหนดไว้อย่างชัดเจนหรือไม่หากฉันลบconstในรหัสต้นฉบับ?

5
ทำไมข้อความที่ไม่มีผลต่อการพิจารณาทางกฎหมายใน C
ให้อภัยหากคำถามนี้ไร้เดียงสา พิจารณาโปรแกรมต่อไปนี้: #include <stdio.h> int main() { int i = 1; i = i + 2; 5; i; printf("i: %d\n", i); } ในตัวอย่างข้างต้นข้อความ5;และi;ดูเหมือนฟุ่มเฟือยโดยสิ้นเชิง แต่โค้ดรวบรวมโดยไม่มีคำเตือนหรือข้อผิดพลาดโดยค่าเริ่มต้น (อย่างไรก็ตาม gcc จะโยนwarning: statement with no effect [-Wunused-value]คำเตือนเมื่อวิ่งไปด้วย-Wall) พวกเขาไม่มีผลกับส่วนที่เหลือของโปรแกรมดังนั้นทำไมพวกเขาจึงพิจารณาข้อความที่ถูกต้องตั้งแต่แรก? คอมไพเลอร์ไม่สนใจพวกเขาเหรอ? มีประโยชน์ใด ๆ ในการอนุญาตข้อความดังกล่าวหรือไม่?
13 c 

5
เปรียบเทียบบิตกับบูลีน
ว่าฉันมีชุดของค่าสถานะการเข้ารหัสใน flagsuint16_t ตัวอย่างเช่นAMAZING_FLAG = 0x02. ตอนนี้ฉันมีฟังก์ชั่น ฟังก์ชั่นนี้ต้องตรวจสอบว่าฉันต้องการเปลี่ยนธงหรือไม่เพราะถ้าฉันต้องการทำเช่นนั้นฉันต้องเขียนเป็นแฟลช และนั่นก็มีราคาแพง ดังนั้นฉันต้องการการตรวจสอบซึ่งจะบอกฉันถ้ามีค่าเท่ากับflags & AMAZING_FLAG doSetนี่เป็นความคิดแรก: setAmazingFlag(bool doSet) { if ((flags & AMAZING_FLAG) != (doSet ? AMAZING_FLAG : 0)) { // Really expensive thing // Update flags } } นี่ไม่ใช่คำสั่งที่ใช้งานง่าย ฉันรู้สึกว่าควรจะมีวิธีที่ดีกว่าบางอย่างเช่น: if ((flags & AMAZING_FLAG) != doSet){ } แต่ตอนนี้ไม่ได้ทำงานจริงน่าจะเท่ากับtrue0x01 ดังนั้นมีวิธีที่เป็นระเบียบในการเปรียบเทียบบิตกับบูลีนหรือไม่?

1
เพราะเหตุใดเวลาจึงถูกรายงานตามเวลา () บางครั้ง 1 วินาทีหลังองค์ประกอบวินาทีของ timespec_get () ในรหัส C?
ตัวอย่างโค้ดต่อไปนี้: struct timespec ts; for (int x = 0; x < 100000000; x++) { timespec_get(&ts, TIME_UTC); long cTime = (long) time(NULL); if (cTime != ts.tv_sec && ts.tv_nsec < 3000000) { printf("cTime: %ld\n", cTime); printf("ts.tv_sec: %ld\n", ts.tv_sec); printf("ts.tv_nsec: %ld\n", ts.tv_nsec); } } สร้างผลลัพธ์นี้: ... cTime: 1579268059 ts.tv_sec: 1579268060 ts.tv_nsec: 2527419 cTime: …
12 c  time  posix  timespec 

4
ทำไมฟังก์ชั่นนี้คืนความยาวที่ถูกต้องของสตริง? (การเพิ่มตัวชี้ถ่าน)
นี่คือฟังก์ชั่นที่นับจำนวนตัวอักษรในสตริง: int str_len(const char* s) { int i = 0; while(*(s++)) { i++; } return i; } ทำไมสิ่งนี้ถึงส่งคืนความยาวที่ถูกต้อง? "a"สมมติว่าผมเรียกฟังก์ชั่นนี้ด้วยเชือกที่เรียบง่าย จากนั้นsจะเพิ่มขึ้นในขณะที่ลูปดังนั้นค่าของsและiเป็นทั้ง 0
12 c  while-loop  strlen  c89 

1
เหตุใดจึงกำหนดแมโครให้กับฟังก์ชันด้วยชื่อเดียวกัน
ฉันพบรหัสด้านล่างในhttps://github.com/torvalds/linux/blob/master/arch/x86/include/asm/atomic.h static __always_inline bool arch_atomic_sub_and_test(int i, atomic_t *v) { return GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, e, "er", i); } #define arch_atomic_sub_and_test arch_atomic_sub_and_test สิ่งที่#defineทำจริงๆ? เมื่อใดที่จำเป็นต้องทำ
12 c  linux-kernel 

3
“ ความผันผวน” รับประกันอะไรในรหัส C แบบพกพาสำหรับระบบมัลติคอร์หรือไม่?
หลังจากที่กำลังมองหาที่พวง ของ อื่น ๆ คำถาม และ พวกเขา ตอบฉันได้รับความประทับใจที่ไม่มีข้อตกลงอย่างกว้างขวางในสิ่งที่ "ผันผวน" คำหลักใน C หมายความว่า แม้มาตรฐานของตัวเองดูเหมือนจะไม่เพียงพอที่ชัดเจนสำหรับทุกคนที่จะเห็นด้วยกับสิ่งที่มันหมายถึง ท่ามกลางปัญหาอื่น ๆ : ดูเหมือนว่าจะให้การรับประกันที่แตกต่างกันขึ้นอยู่กับฮาร์ดแวร์ของคุณและขึ้นอยู่กับคอมไพเลอร์ของคุณ มันมีผลต่อการปรับให้เหมาะสมของคอมไพเลอร์ แต่ไม่ใช่การปรับให้เหมาะสมของฮาร์ดแวร์ดังนั้นในโปรเซสเซอร์ขั้นสูงที่ทำการปรับแต่งให้เหมาะสมนั้นไม่ชัดเจนว่าคอมไพเลอร์สามารถป้องกันการปรับให้เหมาะสมที่คุณต้องการป้องกันได้หรือไม่ (คอมไพเลอร์บางตัวสร้างคำแนะนำเพื่อป้องกันการปรับแต่งฮาร์ดแวร์บางอย่างในบางระบบ แต่สิ่งนี้ดูเหมือนจะไม่ได้มาตรฐานในทางใดทางหนึ่ง) เพื่อสรุปปัญหาปรากฏขึ้น (หลังจากอ่านมาก) ว่า "volatile" รับประกันสิ่งที่ต้องการ: ค่าจะอ่าน / เขียนไม่เพียงจาก / ไปยังการลงทะเบียน แต่อย่างน้อยกับแคช L1 หลักในลำดับเดียวกันกับที่ การอ่าน / เขียนจะปรากฏขึ้นในรหัส แต่สิ่งนี้ดูไร้ประโยชน์เนื่องจากการอ่าน / เขียนจาก / ไปยังการลงทะเบียนนั้นเพียงพอแล้วในเธรดเดียวกันในขณะที่การประสานงานกับแคช L1 ไม่รับประกันอะไรเพิ่มเติมเกี่ยวกับการประสานงานกับเธรดอื่น ๆ ฉันนึกภาพไม่ออกเลยว่ามันจะสำคัญเมื่อต้องซิงค์เพียงกับแคช L1 ใช้ 1 การใช้ …

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