ฉันจะประกาศอาร์เรย์ที่มีขนาดตัวแปรได้อย่างไร (ทั่วโลก)


18

ฉันต้องการสร้างสามอาร์เรย์ที่มีความยาวเท่ากัน ตามเอกสารประกอบอาร์เรย์ต้องถูกกำหนดเป็นint myArray[10];ตำแหน่งที่ 10 สามารถทดแทนความยาวที่รู้จัก (จำนวนเต็มอื่น) หรือเติมด้วยอาเร{2, 3, 5, 6, 7}ย์

แต่เมื่อฉันพยายามที่จะประกาศค่าint arrSize = 10;แล้วอาร์เรย์ขึ้นอยู่กับขนาดที่ฉันได้รับต่อไปนี้:int myArray[arrSize];error: array bound is not an integer constant

มีวิธีในการกำหนดขนาดของอาเรย์ที่แตกต่างกันหรือไม่ (ฉันได้รับการสอนการเข้ารหัสฮาร์ดไดรฟ์ไม่ดีและสิ่งที่ต้องหลีกเลี่ยงค่าใช้จ่ายทั้งหมด)


ฉันมีปัญหาที่คล้ายกันและทำสิ่งนี้ ฉันกำลังเรียนรู้ด้วยดังนั้นจึงไม่สามารถพูดได้ว่ามันเป็นวิธีการแก้ปัญหาที่ถูกต้องหรือไม่ ดูส่วนล่างของรหัสโดยใช้เวกเตอร์ฉันใช้เวลาค่อนข้างนานในการเริ่มเข้าใจพวกเขาและฉันก็ยังไม่ชำนาญโดย: #include <string> #include <vector> #include <iostream> #include <algorithm> #include <string.h> ใช้ namespace std; int main () {ชื่อสตริง; ที่อยู่สตริง; เมืองสตริง; ประเทศสตริง คำตอบสตริง; vector <vector <string>> personData; สำหรับ (;;) {vector <string> myTempData; ศาล << "ใส่ชื่อหรือ n เพื่อออก" << endl; getline (cin, ชื่อ); if (name == "n") {bre
Misterxp

คำตอบ:


22

คำถามของคุณมี 2 ส่วนจริง

1 / ฉันจะประกาศขนาดคงที่ของอาร์เรย์ภายนอกอาร์เรย์ได้อย่างไร

คุณสามารถใช้แมโครได้

#define ARRAY_SIZE 10
...
int myArray[ARRAY_SIZE];

หรือใช้ค่าคงที่

const int ARRAY_SIZE = 10;
...
int myArray[ARRAY_SIZE];

ถ้าคุณเริ่มต้นอาร์เรย์และคุณจำเป็นต้องรู้ขนาดของมันคุณสามารถทำได้:

int myArray[] = {1, 2, 3, 4, 5};
const int ARRAY_SIZE = sizeof(myArray) / sizeof(int);

สองคืออยู่กับชนิดขององค์ประกอบของอาร์เรย์ของคุณในแต่ละที่นี่sizeofint

2 / ฉันจะมีอาร์เรย์ที่มีขนาดแบบไดนามิก (เช่นไม่รู้จักจนถึง runtime) ได้อย่างไร

เพื่อที่คุณจะต้องจัดสรรแบบไดนามิกซึ่งทำงานบน Arduino แต่โดยทั่วไปจะไม่แนะนำเพราะอาจทำให้ "ฮีป" กระจัดกระจาย

คุณสามารถทำได้ (วิธี C):

// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source)
if (myArray != 0) {
    myArray = (int*) realloc(myArray, size * sizeof(int));
} else {
    myArray = (int*) malloc(size * sizeof(int));
}

หรือ (วิธี C ++):

// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source or through other program logic)
if (myArray != 0) {
    delete [] myArray;
}
myArray = new int [size];

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับปัญหาการกระจายตัวของฮีปคุณสามารถอ้างอิงคำถามนี้


4
1) ARRAY_SIZE = sizeof myArray / sizeof myArray[0];วิธีนี้คุณสามารถเปลี่ยนประเภทของ myArray ได้โดยไม่ต้องแนะนำบั๊ก ด้วยเหตุผลเดียวกัน, myArray = realloc(myArray, size * sizeof *myArray);. BTW หล่อค่าตอบแทนmalloc()หรือrealloc()ไร้ประโยชน์ด้วย 2) การตรวจสอบmyArray != 0ในรุ่น C จะไม่ได้ผลตามที่เทียบเท่ากับrealloc(NULL, sz) malloc(sz)
Edgar Bonet

const int ARRAY_SIZE = 10; int myArray [ARRAY_SIZE]; คุณคิดว่าเป็นไปได้จริงหรือ สิ่งนี้จะทำให้เกิดข้อผิดพลาดของอาร์เรย์ที่ปรับเปลี่ยนได้ใน C
Arun Joe Cheriyan

@ArunCheriyan ใน CI ไม่รู้ แต่ใน C ++ มันรวบรวมและทำงานได้อย่างสมบูรณ์แบบ เนื่องจาก Arduino ใช้ C ++ ดังนั้นจึงไม่มีปัญหาที่นี่
jfpoilpret

0

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

char *chararray = malloc(sizeof(char)*x);

โดยที่ x (จำนวนเต็ม) สามารถตั้งค่าในรหัสแอปพลิเคชัน (คุณสามารถโหลดจาก eeprom หากคุณต้องการให้เป็นการตั้งค่าแบบถาวร แต่สามารถกำหนดค่าได้)


อย่างไรก็ตามถ้าคุณต้องการประกาศอาร์เรย์ที่มีขนาดเท่ากันคุณก็ต้องประกาศจำนวนค่าคงที่เช่นนี้:

const int arrsize = 10;
char array1[arrsize];
int array2[arrsize];

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


ขนาดการเข้ารหัสที่เป็นสัญลักษณ์แทนอักษรสามารถให้ประโยชน์สองประการคือ 1) เอกสารสัญลักษณ์ที่เลือกอย่างดีหรืออย่างน้อยก็แนะนำเหตุผลของการเลือก; และ 2) เมื่อชิ้นส่วนอื่น ๆ ของโปรแกรมหรือต้องโมดูลจะได้รับการปรับให้เหมาะสมกับทางเลือกที่การแสดงออกโดยใช้สัญลักษณ์เดียวกันสามารถทำให้อัตโนมัติทำให้การบำรุงรักษามากได้ง่ายขึ้น
JRobert

[ปิดหัวข้อเล็กน้อย แต่] "ผู้ใช้" คลุมเครือเนื่องจากอาจหมายถึงหนึ่งในจำนวนคน มันมักจะหมายถึงผู้ใช้ซึ่งเป็นผู้บริโภคผลิตภัณฑ์ขั้นสุดท้ายหากไม่ได้ระบุไว้เป็นอย่างอื่น อาจเป็นโปรแกรมเมอร์คนต่อไปผู้บริโภครหัสถัดไปของคุณทันทีซึ่งอาจเป็นคุณ (โดยทั่วไปในประสบการณ์ของฉัน) หนึ่งปีหรือมากกว่าหลังจากที่ฉันลืมรายละเอียดภายในของมัน หรือนักออกแบบระบบที่มีรหัสของคุณเป็นโมดูลพร้อมใช้ในผลิตภัณฑ์ของเขา / เธอ ฉันสงสัยว่าคุณหมายถึง "ผู้ใช้" คนที่สอง
JRobert

0

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


0

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

int arrSize;
int myArray[arrSize];

สิ่งนี้จะแสดงข้อผิดพลาดตั้งแต่เมื่อประกาศอาร์เรย์โปรแกรมคาดว่าค่าระหว่างวงเล็บจะคงที่ แต่มีวิธีที่คุณสามารถสร้างอาร์เรย์ที่มีตัวแปรที่กำหนดจำนวนของค่าที่อาร์เรย์นี้จะมีผ่านการจัดสรรหน่วยความจำแบบไดนามิกสำหรับชุดค่า (วิธีนี้ได้รับการทดสอบกับอาร์เรย์แบบมิติเดียวเท่านั้นยังไม่ได้ลอง หลายมิติยัง) และมันจะเป็นดังนี้:

//First you create a pointer for the memory space to be separated for the set you're creating
int* myArray;
int arrSize; //Then you define the variable that will determine the amount of elements the array is going to have, you can give it a value whenever you want as long as this int is defined before the values in myArray are set 
myArray=(int*)calloc(arrSize,sizeof(int)) //Here, you establish that the instance myArray (whose memory space has already been separated through the creation of the pointer) will be separated into arrSize amount of elements of type int with a maximum memory value (in bytes) equal to the maximum available for the int type variables

หลังจากนี้สิ่งที่เหลืออยู่ต้องทำคือกำหนดค่าสำหรับทุกองค์ประกอบที่สร้างในอินสแตนซ์ myArray (ซึ่งตอนนี้เป็น Array แล้ว) ตามที่คุณต้องการสำหรับอาร์เรย์ปกติที่สร้างเป็น myArray [arrSize]

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