การเริ่มต้นอาร์เรย์ 2 มิติโดยไม่ระบุขนาด

ฉันสามารถเริ่มต้นอาร์เรย์หนึ่งมิติใน c โดยมีหรือไม่มีการเริ่มต้นขนาดของมัน:

int x[] = {1,2,3,4,5};
int y[5] = {1,2,3,4,5};

แต่เมื่อฉันพยายามทำเช่นเดียวกันกับอาเรย์สองมิติเช่น

int x[][] = {{1,2,3},
             {4,5,6}};

ฉันได้รับ error: array type has incomplete element type ข้อผิดพลาดเดียวกันนี้จะเกิดขึ้นหากฉันประกาศและเริ่มต้นอาร์เรย์ในบรรทัดที่ต่างกัน อย่างไรก็ตาม ฉันสามารถกำหนดค่าเริ่มต้นได้โดยระบุขนาด:

int x[2][3] = {{1,2,3},
               {4,5,6}};

ไม่มีข้อผิดพลาดกับสิ่งนี้ คำถามของฉันคือ เป็นไปได้ไหมที่จะเริ่มต้นอาร์เรย์หลายมิติโดยไม่ต้องเตรียมข้อมูลเบื้องต้นขนาดของอาร์เรย์ก่อน ฉันถามสิ่งนี้เพราะสำหรับโปรเจ็กต์สุดท้าย ฉันจำเป็นต้องประกาศอาร์เรย์และเริ่มต้นได้ในภายหลัง และขนาดของอาร์เรย์จะไม่มีใครทราบเมื่อทำการคอมไพล์


person Daniel    schedule 23.09.2017    source แหล่งที่มา
comment
ถ้ามันมีขนาดไดนามิก คุณจะระบุรายการตัวเริ่มต้นในโค้ดอย่างไร?   -  person Barmar    schedule 23.09.2017
comment
คุณหมายถึงอะไรโดยการประกาศและเริ่มต้นอาร์เรย์ในบรรทัดที่แตกต่างกัน? วิธีเดียวที่จะเริ่มต้นอาร์เรย์ได้คือการประกาศ   -  person Barmar    schedule 23.09.2017
comment
@Barmar แย่ของฉัน ฉันคิดว่าฉันตั้งใจจะบอกว่ากำหนด เช่นเดียวกับที่มี int x[][]; แล้วพิมพ์อย่างอื่น x[][] =...   -  person Daniel    schedule 23.09.2017
comment
@Barmar สำหรับขนาดไดนามิกนั่นเป็นวิธีการใช้ถ้อยคำที่ไม่ดีในส่วนของฉัน สิ่งที่ฉันหมายถึงคือขนาดถ้าไม่รู้จักอาร์เรย์เมื่อทำการคอมไพล์   -  person Daniel    schedule 23.09.2017
comment
หากต้องการขยายสิ่งที่ @barmer เขียน: คุณสามารถเริ่มต้นตัวแปร ด้วย การประกาศเท่านั้น ซึ่งทำให้นี่เป็นคำจำกัดความ (ไม่ใช่วิธีเดียวสำหรับคำจำกัดความ แต่เป็นคำจำกัดความเดียว) และหากไม่ทราบขนาด ณ เวลาคอมไพล์ คุณจะไม่สามารถเริ่มต้นได้ในเวลาคอมไพล์ (ฟังดูสมเหตุสมผลสำหรับฉัน) บางทีคุณอาจต้องการค้นคว้าในหนังสือ C ของคุณเกี่ยวกับการประกาศ คำจำกัดความ และการเริ่มต้น   -  person too honest for this site    schedule 23.09.2017
comment
เรียนรู้เกี่ยวกับ VLA ซึ่งมีให้ใช้งานตั้งแต่ C99 (แต่ทำให้เป็นทางเลือกใน C11; ยังมีให้บริการอย่างแพร่หลาย)   -  person ad absurdum    schedule 23.09.2017
comment
หากคุณทราบรายการค่าที่จะเริ่มต้น เช่นเดียวกับในความพยายามในการเริ่มต้น int[x][y] คุณจะไม่ทราบขนาดได้อย่างไร การเว้นขนาดว่างไว้เป็นเพียงความสะดวกในโค้ดบรรทัดแรก คอมไพลเลอร์จะนับตัวเริ่มต้นแทนที่จะให้คุณดำเนินการ แต่ก็ยังเป็นที่รู้จักในเวลารวบรวม   -  person Barmar    schedule 24.09.2017
comment
หากคุณไม่ทราบขนาดและค่าเริ่มต้นจนถึงเวลาดำเนินการ คุณจะไม่สามารถเริ่มต้นด้วยตัวอักษรเช่นนั้นได้อย่างชัดเจน ใช้ VLA หรือการจัดสรรแบบไดนามิกด้วย malloc()   -  person Barmar    schedule 24.09.2017
comment
@Comrade_Comski ไม่ว่าคุณจะประกาศอย่างไร คุณสามารถ ไม่เคย กำหนดให้กับอาร์เรย์ คุณสามารถกำหนดให้กับแต่ละองค์ประกอบเท่านั้น   -  person Barmar    schedule 24.09.2017


คำตอบ (3)


เป็นไปได้ไหมที่จะเริ่มต้นอาเรย์หลายมิติโดยไม่ต้องเตรียมข้อมูลเบื้องต้นขนาด?

ไม่ ไม่ใช่ในแบบที่คุณเสนอหรืออะไรทำนองนั้น

ฉันต้องสามารถประกาศอาร์เรย์และเริ่มต้นได้ในภายหลัง และอาร์เรย์เหล่านั้นจะมีขนาดไดนามิก

หากไม่ทราบขนาดในขณะคอมไพล์ คุณควรจัดสรรอาร์เรย์โดยใช้ a = malloc(x * y * sizeof(value_t)) จากนั้นจัดทำดัชนีเข้าไปเช่น a[i + j*y]

person John Zwinck    schedule 23.09.2017
comment
อาร์เรย์ที่มีความยาวผันแปรไม่ได้เป็นไปได้เช่นกันใช่ไหม - person Barmar; 23.09.2017
comment
โปรดทราบว่าคุณควรตรวจสอบการคูณ x*y*sizeof(value_t) เพื่อดูจำนวนเต็มล้น - person ndim; 23.09.2017
comment
VLA ไม่ต้องการการจัดสรรแบบไดนามิก หากคุณต้องการใช้ คุณยังคงสามารถใช้ VLA ได้ การใช้อาร์เรย์ 1D และการคำนวณดัชนีด้วยตนเองไม่ใช่อาร์เรย์ 2D มีแนวโน้มที่จะเกิดข้อผิดพลาดและล้าสมัยมาเป็นเวลา 18 ปี - person too honest for this site; 23.09.2017

Is it possible to initialize a multi dimensional array without first initializing its size?

=> ไม่ มันเป็นไปไม่ได้

สิ่งที่เป็นไปได้คือคุณใช้ขนาดของอาร์เรย์แล้วจัดสรรหน่วยความจำโดยใช้ calloc ฉันขอให้คุณใช้ calloc เพราะวิธีนี้องค์ประกอบอาร์เรย์ทั้งหมดจะเริ่มต้นเป็น 0

ตอนนี้การใช้ calloc จะถูกนำไปใช้เป็น:

สมมติว่าคุณต้องการอาร์เรย์ 2 มิติ ดังนั้นคุณจึงนำตัวแปร แถว และ คอลัมน์ เป็นอินพุตจากผู้ใช้ จากนั้นใช้

int *x;
x = calloc( ( row * column), sizeof(datatype) );

ในกรณีนี้ประเภทข้อมูลจะเป็น int

ในรหัสสั้น ๆ จะปรากฏเป็น:

int row, column, *x;

    /* TAKING INPUT FROM THE USER */
printf("\n\t Enter the number of rows : ");
scanf("%d", &row);
printf("\n\t Enter the number of columns : ");
scanf("%d", &column);

    /* DYNAMICALLY ALLOCATING MEMORY TO x USING calloc */
x = calloc( (row * column), sizeof(int));

ฉันหวังว่ารหัสนี้จะช่วยแก้ปัญหาของคุณได้

ฉันมีอีกสิ่งหนึ่งที่จะแบ่งปันกับคุณ

ในรหัสบรรทัดนี้ของคุณ:

int x[][] = {{1,2,3},
             {4,5,6}};

การเริ่มต้นนี้ขาดสิ่งหนึ่งไปและสิ่งนั้นคือการกล่าวถึงขนาดคอลัมน์มิฉะนั้นโค้ดก็ถูกต้อง

ดังนั้น การแก้ไขรหัสของคุณ:

int x[][3] = {{1,2,3},
             {4,5,6}};

นี่จะทำงานได้ดี

พยายามต่อไป! สิ่งเหล่านี้สามารถรู้ได้ในขณะฝึกซ้อมเท่านั้น

ขอให้มีความสุขในการเขียนโค้ด!

person Jorvis    schedule 24.09.2017

ใช่ แต่คุณไม่มีลูกน้ำ:

int x[2][3] = {{1,2,3},
               {4,5,6}};

องค์ประกอบอาร์เรย์ทั้งหมด (แม้แต่อาร์เรย์ภายใน) จะต้องคั่นด้วยเครื่องหมายจุลภาค

person ACVM    schedule 23.09.2017
comment
นั่นจะไม่ทำให้เกิดข้อผิดพลาดทางไวยากรณ์ใช่หรือไม่ อาร์เรย์มีประเภทที่ไม่สมบูรณ์ใช่ไหม - person Barmar; 23.09.2017
comment
สิ่งที่ฉันรู้ก็คือเขามีข้อผิดพลาดทางไวยากรณ์... stackoverflow.com/questions/15520880/ - person ACVM; 23.09.2017
comment
เขายังมีข้อผิดพลาดทางไวยากรณ์ในเวอร์ชันที่เขาบอกว่าใช้งานได้ ฉันคิดว่าเขาเพิ่งคัดลอกมันผิดในคำถาม - person Barmar; 23.09.2017
comment
คำถามของเขาคือทำอย่างไรโดยไม่ต้องใส่ [2][3] ลงในขนาด - person Barmar; 23.09.2017
comment
อ่า ฉันเห็นแล้ว แย่แล้ว - person ACVM; 23.09.2017