ฉันจะประกาศและกำหนดตัวแปรหลายตัวในหนึ่งบรรทัดโดยใช้ C ++ ได้อย่างไร


173

ฉันมักจะคิดเสมอว่าถ้าฉันประกาศตัวแปรทั้งสามนี้พวกเขาจะมีค่า 0

int column, row, index = 0;

แต่ฉันพบว่ามีเพียงดัชนีเท่านั้นที่เท่ากับศูนย์ & อื่น ๆ ที่เป็นขยะเช่น 844553 & 2423445

ฉันจะเริ่มต้นตัวแปรเหล่านี้ทั้งหมดให้เป็นศูนย์โดยไม่ต้องประกาศแต่ละตัวแปรในบรรทัดใหม่ได้อย่างไร


36
ระมัดระวังด้วยการประกาศหลายตัวแปรแบบบรรทัดเดียว ง่ายกว่าที่คุณคิดที่จะประกาศตัวชี้ int ตามด้วยรายการจำนวนเต็มปกติ ( int* a, b, c;ไม่ได้ทำในสิ่งที่ดูเหมือน)
Chris Eberle

4
มีเพียงสามตัวแปรครับเขียน=0สำหรับแต่ละคนในคำจำกัดความของพวกเขา และถ้าคุณต้องการตัวแปรจำนวนมากลองใช้อาร์เรย์: int a[10]={0}จะเริ่มต้นแต่ละค่าa[i]เป็น 0 สำหรับคุณ
สแตน

คอมไพเลอร์ไม่อนุญาตให้มีการสร้างหากมันจะทำงานแตกต่างจากที่โปรแกรมเมอร์ผู้มีเหตุผลคาดหวังว่าจะทำ ... imho
cph2117

1
@ cph2117 โปรแกรมเมอร์ที่เหมาะสมจะคิดว่า'อืมมซินแท็คซ์นี้อาจหมายถึงสองสิ่งที่แตกต่างกันขึ้นอยู่กับวิธีที่ไวยากรณ์ผูกสิ่งต่าง ๆ 'ค้นหามาตรฐานเพื่อค้นหาว่าสิ่งใดเป็นจริงและเข้ากับมัน
underscore_d

หยุดทำสิ่งนี้ มันทำให้การอ่านรหัสยากขึ้น จุดของการเขียนโค้ดในภาษาระดับสูงคือการทำให้ผู้ดูแลสามารถอ่านได้ง่าย
Martin York

คำตอบ:



162

เมื่อคุณประกาศ:

int column, row, index = 0;

เฉพาะดัชนีถูกตั้งค่าเป็นศูนย์

อย่างไรก็ตามคุณสามารถทำสิ่งต่อไปนี้:

int column, row, index;
column = index = row = 0;

แต่โดยส่วนตัวฉันชอบสิ่งต่อไปนี้ซึ่งได้รับการชี้ให้เห็น
มันเป็นรูปแบบที่อ่านง่ายขึ้นในมุมมองของฉัน

int column = 0, row = 0, index = 0;

หรือ

int column = 0;
int row = 0;
int index = 0;

3
ระหว่างสองครั้งสุดท้ายฉันตัดสินใจโดยขึ้นอยู่กับว่าค่าทั้งสองจะต้องเป็นประเภทเดียวกัน ( bool previousInputValue, presentInputValue;) หรือถ้าพวกเขาเพิ่งจะเป็นประเภทเดียวกันตอนนี้ แต่ไม่จำเป็นต้องเป็นจริง ( uint8_t height, width;อาจกลายเป็นuint8_t height; uint16_t width;ในอนาคตและควรจะเป็นuint8_t height; uint8_t width;เริ่มต้นกับ).
altendky

เพราะการเขียนuint8_t height; uint16_t width;แทนการuint8_t height, width;บันทึกได้ 10 ตัวในอนาคต :-) คุณสามารถทำได้แน่นอนตามที่คุณต้องการ แค่ทำให้แน่ใจว่าคุณอ่านได้ง่าย ดังนั้นรูปแบบสุดท้ายจึงชัดเจนที่สุด
แมตต์

รูปแบบสุดท้ายนั้นชัดเจนที่สุดในการระบุประเภทของตัวแปรแต่ละตัวและทำให้ชัดเจนว่าแต่ละค่าเริ่มต้น ที่กล่าวมานั้นไม่ชัดเจนเกี่ยวกับคอลัมน์และแถวที่คาดว่าจะเป็นประเภทเดียวกันหรือไม่ บางทีเราอาจต้องการความชัดเจนint presentValue = 0; typeof(presentValue) previousValue = presentValue;แต่ฉันเชื่อว่าtypeof()นี่เป็นส่วนขยาย GCC ที่ไม่ได้มาตรฐาน
altendky

49

ตามที่ @Josh กล่าวว่าคำตอบที่ถูกต้องคือ:

int column = 0,
    row = 0,
    index = 0;

คุณจะต้องระวังสิ่งเดียวกันกับพอยน์เตอร์ นี้:

int* a, b, c;

เทียบเท่ากับ:

int *a;
int b;
int c;

34
ฉันเกลียดสิ่งที่ตัวชี้มันไม่สมเหตุสมผล เครื่องหมายดอกจันเป็นส่วนหนึ่งของประเภทดังนั้นจึงควรใช้กับพวกเขาทั้งหมด ลองนึกภาพถ้ามีการunsigned long x, y;ประกาศxเป็นunsigned longแต่yเพียงแค่unsignedaka unsigned int! นั่นเป็นสิ่งเดียวกัน! </rant>
Cam Jackson

6
มันสมเหตุสมผลแล้ว "int * a, b, c;"
Jeroen

7
@JeroenBollen ใช่มันทำให้รู้สึกถ้าคุณเขียนเครื่องหมายดอกจันของคุณถัดจากชื่อตัวแปรแทนประเภท แต่ในตัวเองมันไม่สมเหตุสมผล อย่างที่ฉันได้กล่าวไว้ข้างต้นเครื่องหมายดอกจันเป็นส่วนหนึ่งของประเภทไม่ใช่ส่วนหนึ่งของชื่อดังนั้นควรจัดกลุ่มตามประเภท!
Cam Jackson

11
ไม่ใช่ด้านที่จริงแล้วมันสมเหตุสมผล * ที่ไม่จำเป็นต้องเป็นส่วนหนึ่งของประเภทเป็นint *aวิธีการที่*aแสดงถึงintค่า
mdenton8

2
มีการสร้างจุดแล้ว แต่เพียงเพิ่มเข้าไปเป็นโมฆะคือการขาดประเภท แต่คุณยังสามารถทำพอยน์เตอร์ได้ ดังนั้นทำไมvoid* aจะรวบรวมและvoid *a, b, cจะไม่ การหาเหตุผลเข้าข้างตนเองนี้เหมาะกับฉัน
Josh C

25

หากคุณประกาศตัวแปร / วัตถุหนึ่งรายการต่อบรรทัดไม่เพียง แต่จะช่วยแก้ปัญหานี้ได้ แต่มันจะทำให้รหัสชัดเจนขึ้นและป้องกันข้อผิดพลาดที่โง่เขลาเมื่อประกาศตัวชี้

ในการตอบคำถามของคุณโดยตรงคุณต้องกำหนดค่าเริ่มต้นให้เป็น 0 อย่างชัดเจน int a = 0, b = 0, c = 0;.


16
int column(0), row(0), index(0);

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


2
และทุกวันนี้มีการกำหนดค่าเริ่มต้นสม่ำเสมอ (รอการแก้ไข C ++ 17 สำหรับauto... ): คอลัมน์ int { 0 } , แถว{ 0 } , ดัชนี{ 0 } ;
underscore_d


4

แนวทางที่เป็นไปได้:

  • เริ่มต้นตัวแปรท้องถิ่นทั้งหมดด้วยศูนย์
  • มีอาเรย์memsetหรือ{0}อาเรย์
  • ทำให้เป็นสากลหรือคงที่
  • วางไว้ในstructและmemsetหรือมีตัวสร้างที่จะเริ่มต้นพวกเขาเป็นศูนย์

#define COLUMN 0 #define ROW 1 #define INDEX 2 # กำหนด AR_SIZE 3 int ข้อมูล [ AR_SIZE ]; // แค่ความคิด
Ajay

ขออภัยฉันหมายความว่าเพราะเหตุใดคุณจึงรวมบรรทัด " มีอาร์เรย์, memset หรือ {0} อาร์เรย์ " ในคำตอบของคุณ
Mateen Ulhaq

memset (Data, 0, sizeof (Data)); // ถ้ามันสามารถบรรจุได้อย่างมีเหตุผล
Ajay

2

ฉันจะไม่แนะนำสิ่งนี้ แต่ถ้าคุณเป็นหนึ่งบรรทัดจริงๆและเขียน 0 ครั้งเดียวเท่านั้นคุณสามารถทำสิ่งนี้ได้:

int row, column, index = row = column = 0;

0

ดังที่คนอื่น ๆ พูดถึงตั้งแต่ C ++ 17 เป็นต้นไปคุณสามารถใช้ประโยชน์จากการเชื่อมโยงโครงสร้างสำหรับการกำหนดตัวแปรหลายรายการ

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

#include <iostream>
#include <array>

template <int N, typename T> auto assign(T value)
{
    std::array<T, N> out;
    out.fill(value);
    return out;
}

int main()
{
    auto [a, b, c] = assign<3>(1);

    for (const auto& v : {a, b, c})
    {
        std::cout << v << std::endl;
    }

    return 0;
}

Demo


-13

เมื่อคุณประกาศตัวแปรโดยไม่เริ่มต้นตัวเลขสุ่มจากหน่วยความจำจะถูกเลือกและตัวแปรนั้นจะเริ่มต้นเป็นค่านั้น


7
ไม่ได้จริงๆ คอมไพเลอร์ตัดสินใจ 'ตัวแปรนี้จะเป็นที่อยู่ xxx' สิ่งที่เกิดขึ้นจะเป็นที่อยู่ xxx จะเป็นค่าเริ่มต้นเว้นแต่ชุดของบางสิ่งบางอย่างอย่างชัดเจน (โดยการเริ่มต้นหรือการกำหนด)
PM100

3
@ pm100 ดีกว่าและจริงสำหรับการใช้งานเล็กน้อยที่ไม่ได้ไปรบกวนผู้ใช้ ... ที่ยังคงใช้งานเกินจริง ;-) เนื่องจากการใช้ตัวแปร uninitialised คือ UB ดังนั้นในทางทฤษฎีอาจเกิดขึ้นได้รวมถึงรหัสใด ๆ การใช้ตัวแปรนั้นจะถูกถอดออกจากโปรแกรมซึ่งมีแนวโน้มโดยเฉพาะอย่างยิ่งเมื่อมีการปรับแต่ง
underscore_d

1
ค่าของตัวแปรนั้นจะเป็นอะไรก็ตามที่อยู่ที่มันได้รับเช่นขยะ
Pedro Vernetti

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