C – Arrays อาร์เรย์ ภาษา C


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

แทนที่จะประกาศตัวแปรเดี่ยว เช่น number0, number1, … และ number99 คุณประกาศตัวแปรอาร์เรย์หนึ่งตัว เช่น ตัวเลข และใช้ตัวเลข[0], ตัวเลข[1] และ …, ตัวเลข[99] เพื่อแสดง ตัวแปรแต่ละตัว องค์ประกอบเฉพาะในอาร์เรย์สามารถเข้าถึงได้โดยดัชนี

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

อาร์เรย์ ภาษา C


ประกาศอาร์เรย์


ในการประกาศอาร์เรย์ในภาษา C โปรแกรมเมอร์จะระบุประเภทขององค์ประกอบและจำนวนองค์ประกอบที่อาร์เรย์ต้องการดังนี้:

type arrayName [ arraySize ];


นี่เรียกว่า อาร์เรย์ 1 มิติ (single-dimensional array) arraySize ต้องเป็นจำนวนเต็มมากขึ้นอย่างต่อเนื่องกว่าศูนย์และ ชนิดข้อมูล ที่ถูกต้อง ของภาษา C  ตัวอย่างเช่น ในการประกาศอาร์เรย์ 10 องค์ประกอบที่เรียกว่า balance ของชนิดข้อมูล double ให้ใช้คำสั่งนี้ −

double balance[10];


นี่คือ balance เป็นอาร์เรย์ตัวแปรซึ่งจะเพียงพอที่จะมีได้ถึง 10 หมายเลข

การเริ่มต้นอาร์เรย์


คุณสามารถเริ่มต้นอาร์เรย์ใน C ทีละรายการหรือใช้คำสั่งเดียวดังนี้ −

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

จำนวนค่าระหว่างวงเล็บปีกกา { } ต้องไม่เกินจำนวนองค์ประกอบที่เราประกาศสำหรับอาร์เรย์ระหว่างวงเล็บเหลี่ยม [ ]

หากคุณละเว้นขนาดของอาร์เรย์ อาร์เรย์ที่ใหญ่พอที่จะรองรับการเริ่มต้นจะถูกสร้างขึ้น ดังนั้น หากคุณเขียน −

double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

คุณจะสร้างอาร์เรย์เดียวกันกับที่คุณทำในตัวอย่างก่อนหน้านี้ ต่อไปนี้เป็นตัวอย่างการกำหนดองค์ประกอบเดียวของอาร์เรย์ −

balance[4] = 50.0;


ข้อความข้างต้นกำหนด 5 THองค์ประกอบในอาร์เรย์ที่มีมูลค่า 50.0 อาร์เรย์ทั้งหมดมี 0 เป็นดัชนีขององค์ประกอบแรกซึ่งเรียกว่าดัชนีฐาน และดัชนีสุดท้ายของอาร์เรย์จะมีขนาดรวมของอาร์เรย์ลบ 1 ที่แสดงด้านล่างคือการแสดงภาพของอาร์เรย์ที่เรากล่าวถึงข้างต้น:


การเข้าถึงองค์ประกอบอาร์เรย์


องค์ประกอบสามารถเข้าถึงได้โดยการสร้างดัชนีชื่ออาร์เรย์ ทำได้โดยการวางดัชนีขององค์ประกอบภายในวงเล็บเหลี่ยมหลังชื่อของอาร์เรย์ ตัวอย่างเช่น −

double salary = balance[9];


ข้อความข้างต้นจะใช้เวลา 10 วันองค์ประกอบจากอาร์เรย์และกำหนดค่าให้กับตัวแปรเงินเดือน ตัวอย่างต่อไปนี้ แสดงวิธีการใช้แนวคิดทั้งสามที่กล่าวมาข้างต้น ได้แก่ การประกาศ การกำหนด และการเข้าถึงอาร์เรย์ −

#include <stdio.h>
 
int main () {

   int n[ 10 ]; /* n is an array of 10 integers */
   int i,j;
 
   /* initialize elements of array n to 0 */         
   for ( i = 0; i < 10; i++ ) {
      n[ i ] = i + 100; /* set element at location i to i + 100 */
   }
   
   /* output each array element's value */
   for (j = 0; j < 10; j++ ) {
      printf("Element[%d] = %d\n", j, n[j] );
   }
 
   return 0;
}


เมื่อโค้ดด้านบนถูกคอมไพล์และรัน มันจะให้ผลลัพธ์ดังต่อไปนี้ −

Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109


รายละเอียดอาร์เรย์ (Arrays in Detail)


อาร์เรย์มีความสำคัญต่อ C และควรได้รับความสนใจมากขึ้น แนวคิดที่สำคัญที่เกี่ยวข้องกับอาร์เรย์ต่อไปนี้ควรมีความชัดเจนสำหรับโปรแกรมเมอร์ C −

อาร์เรย์หลายมิติ (Multi-dimensional arrays)


นี่คือรูปแบบทั่วไปของการประกาศอาร์เรย์หลายมิติ −

type name[size1][size2]...[sizeN];


ตัวอย่างเช่น การประกาศต่อไปนี้จะสร้างอาร์เรย์จำนวนเต็ม3 มิติ −

int threedim[5][10][4];


อาร์เรย์สองมิติ (Two-dimensional Arrays)


รูปแบบที่ง่ายที่สุดของอาร์เรย์หลายมิติคืออาร์เรย์สองมิติ สาระสำคัญของอาร์เรย์สองมิติคือรายการอาร์เรย์หนึ่งมิติ ในการประกาศอาร์เรย์จำนวนเต็มสองมิติที่มีขนาด [x][y] คุณจะต้องเขียนดังนี้ −

type arrayName [ x ][ y ];


โดยที่ type สามารถเป็นประเภทข้อมูล C ที่ถูกต้องและ arrayName จะเป็นตัวระบุ C ที่ถูกต้อง อาร์เรย์สองมิติถือได้ว่าเป็นตารางที่มีจำนวนแถว x และจำนวนคอลัมน์ y อาร์เรย์ a 2 มิติ ซึ่งประกอบด้วยสามแถวและสี่คอลัมน์สามารถแสดงได้ดังนี้


ดังนั้น ทุกองค์ประกอบในอาร์เรย์ จะถูกระบุโดยชื่อองค์ประกอบของรูปแบบa[ i ][ j ]โดยที่ ‘a’ คือชื่อของอาร์เรย์ และ ‘i’ และ ‘j’ คือตัวห้อยที่ระบุเฉพาะ แต่ละองค์ประกอบใน ‘a’

การเริ่มต้นอาร์เรย์ 2 มิติ


อาร์เรย์หลายมิติสามารถเริ่มต้นได้โดยการระบุค่าในวงเล็บสำหรับแต่ละแถว ต่อไปนี้เป็นอาร์เรย์ที่มี 3 แถว และแต่ละแถวมี 4 คอลัมน์

int a[3][4] = {  
   {0, 1, 2, 3} ,   /*  initializers for row indexed by 0 */
   {4, 5, 6, 7} ,   /*  initializers for row indexed by 1 */
   {8, 9, 10, 11}   /*  initializers for row indexed by 2 */
};


วงเล็บปีกกาซ้อน ซึ่งระบุแถวที่ต้องการ เป็นทางเลือก การเริ่มต้นต่อไปนี้เทียบเท่ากับตัวอย่างก่อนหน้า −

int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};


การเข้าถึงองค์ประกอบอาร์เรย์สองมิติ


องค์ประกอบในอาร์เรย์สองมิติสามารถเข้าถึงได้โดยใช้ตัวห้อย ได้แก่ ดัชนีแถวและดัชนีคอลัมน์ของอาร์เรย์ ตัวอย่างเช่น −

int val = a[2][3];


คำสั่งข้างต้นจะนำองค์ประกอบที่ 4 จากแถวที่ 3 ของอาร์เรย์ คุณสามารถตรวจสอบได้ในรูปด้านบน ให้เราตรวจสอบโปรแกรมต่อไปนี้ที่เราได้ใช้การวนซ้ำซ้อนเพื่อจัดการกับอาร์เรย์สองมิติ −

#include <stdio.h>
 
int main () {

   /* an array with 5 rows and 2 columns*/
   int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
   int i, j;
 
   /* output each array element's value */
   for ( i = 0; i < 5; i++ ) {

      for ( j = 0; j < 2; j++ ) {
         printf("a[%d][%d] = %d\n", i,j, a[i][j] );
      }
   }
   
   return 0;
}


เมื่อโค้ดด้านบนถูกคอมไพล์และรัน มันจะให้ผลลัพธ์ดังต่อไปนี้ −

a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8


ตามที่อธิบายไว้ข้างต้น คุณสามารถมีอาร์เรย์ที่มีมิติข้อมูลจำนวนเท่าใดก็ได้ แม้ว่ามีแนวโน้มว่าอาร์เรย์ส่วนใหญ่ที่คุณสร้างจะมีมิติข้อมูลหนึ่งหรือสองมิติ

การส่งผ่านอาร์เรย์เป็นอาร์กิวเมนต์ฟังก์ชันใน C


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

วิธีที่ 1


พารามิเตอร์ทางการเป็นตัวชี้ −

void myFunction(int *param) {
   .
   .
   .
}


วิธีที่ 2


พารามิเตอร์ทางการเป็นอาร์เรย์ขนาด −

void myFunction(int param[10]) {
   .
   .
   .
}


วิธีที่ 3


พารามิเตอร์ทางการเป็นอาร์เรย์ที่ไม่มีขนาด −

void myFunction(int param[]) {
   .
   .
   .
}


ตัวอย่าง

ตอนนี้ ให้พิจารณาฟังก์ชันต่อไปนี้ ซึ่งรับอาร์เรย์เป็นอาร์กิวเมนต์พร้อมกับอาร์กิวเมนต์อื่น และอิงตามอาร์กิวเมนต์ที่ส่งผ่าน ฟังก์ชันจะส่งกลับค่าเฉลี่ยของตัวเลขที่ส่งผ่านอาร์เรย์ดังนี้:

double getAverage(int arr[], int size) {

   int i;
   double avg;
   double sum = 0;

   for (i = 0; i < size; ++i) {
      sum += arr[i];
   }

   avg = sum / size;

   return avg;
}


ตอนนี้ ให้เราเรียกใช้ฟังก์ชันข้างต้นดังนี้ −

#include <stdio.h>
 
/* function declaration */
double getAverage(int arr[], int size);

int main () {

   /* an int array with 5 elements */
   int balance[5] = {1000, 2, 3, 17, 50};
   double avg;

   /* pass pointer to the array as an argument */
   avg = getAverage( balance, 5 ) ;
 
   /* output the returned value */
   printf( "Average value is: %f ", avg );
    
   return 0;
}


เมื่อโค้ดข้างต้นถูกคอมไพล์และดำเนินการ โค้ดดังกล่าวจะทำให้เกิดผลลัพธ์ดังต่อไปนี้ −

Average value is: 214.400000


อย่างที่คุณเห็น ความยาวของอาร์เรย์ไม่สำคัญเท่าที่เกี่ยวข้องกับฟังก์ชัน เนื่องจาก C ดำเนินการตรวจสอบพารามิเตอร์ที่เป็นทางการโดยไม่มีขอบเขต

ส่งคืนอาร์เรย์จากฟังก์ชันใน C


การเขียนโปรแกรม C ไม่อนุญาตให้ส่งคืนอาร์เรย์ทั้งหมดเป็นอาร์กิวเมนต์ของฟังก์ชัน อย่างไรก็ตาม คุณสามารถส่งคืนตัวชี้ไปยังอาร์เรย์ได้โดยการระบุชื่ออาร์เรย์โดยไม่มีดัชนี

หากคุณต้องการส่งคืนอาร์เรย์มิติเดียวจากฟังก์ชัน คุณจะต้องประกาศฟังก์ชันที่ส่งคืนตัวชี้ดังในตัวอย่างต่อไปนี้:

int * myFunction() {
   .
   .
   .
}


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

ตอนนี้ ให้พิจารณาฟังก์ชันต่อไปนี้ซึ่งจะสร้างตัวเลขสุ่ม 10 ตัวและส่งกลับโดยใช้อาร์เรย์และเรียกใช้ฟังก์ชันนี้ดังนี้

#include <stdio.h>

/* function to generate and return random numbers */
int * getRandom( ) {

   static int  r[10];
   int i;

   /* set the seed */
   srand( (unsigned)time( NULL ) );
  
   for ( i = 0; i < 10; ++i) {
      r[i] = rand();
      printf( "r[%d] = %d\n", i, r[i]);
   }

   return r;
}

/* main function to call above defined function */
int main () {

   /* a pointer to an int */
   int *p;
   int i;

   p = getRandom();
	
   for ( i = 0; i < 10; i++ ) {
      printf( "*(p + %d) : %d\n", i, *(p + i));
   }

   return 0;
}


เมื่อโค้ดข้างต้นถูกคอมไพล์และดำเนินการ โค้ดดังกล่าวจะทำให้เกิดผลลัพธ์ดังต่อไปนี้ −

r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p + 6) : 1827471542
*(p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526


ตัวชี้ไปยังอาร์เรย์ใน C


เป็นไปได้มากว่าคุณจะไม่เข้าใจส่วนนี้จนกว่าคุณจะอ่านบท ‘ตัวชี้’ จนจบ

สมมติว่าคุณมีความเข้าใจพอยน์เตอร์ในภาษา C มาบ้าง เรามาเริ่มกันเลย: ชื่ออาร์เรย์คือตัวชี้คงที่ไปยังองค์ประกอบแรกของอาร์เรย์ ดังนั้นในการประกาศ −

double balance[50];

balance เป็นตัวชี้ไปที่ &บาลานซ์[0] ซึ่งเป็นที่อยู่ขององค์ประกอบแรกของความสมดุลอาเรย์ ดังนั้น ส่วนย่อยของโปรแกรมต่อไปนี้กำหนด p เป็นที่อยู่ขององค์ประกอบแรกของ balance  −

double *p;
double balance[10];

p = balance;


การใช้ชื่ออาร์เรย์เป็นตัวชี้คงที่เป็นเรื่องถูกกฎหมาย และในทางกลับกัน ดังนั้น *(balance + 4) เป็นวิธีที่ถูกต้องในการเข้าถึงข้อมูลที่ balance[4]

เมื่อคุณเก็บที่อยู่ขององค์ประกอบแรกใน ‘p’ คุณจะสามารถเข้าถึงองค์ประกอบอาร์เรย์ได้โดยใช้ *p, *(p+1), *(p+2) และอื่นๆ ด้านล่างนี้เป็นตัวอย่างเพื่อแสดงแนวคิดทั้งหมดที่กล่าวถึงข้างต้น −

#include <stdio.h>

int main () {

   /* an array with 5 elements */
   double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
   double *p;
   int i;

   p = balance;
 
   /* output each array element's value */
   printf( "Array values using pointer\n");
	
   for ( i = 0; i < 5; i++ ) {
      printf("*(p + %d) : %f\n",  i, *(p + i) );
   }

   printf( "Array values using balance as address\n");
	
   for ( i = 0; i < 5; i++ ) {
      printf("*(balance + %d) : %f\n",  i, *(balance + i) );
   }
 
   return 0;
}


เมื่อโค้ดด้านบนถูกคอมไพล์และรัน มันจะให้ผลลัพธ์ดังต่อไปนี้ −

Array values using pointer
*(p + 0) : 1000.000000
*(p + 1) : 2.000000
*(p + 2) : 3.400000
*(p + 3) : 17.000000
*(p + 4) : 50.000000
Array values using balance as address
*(balance + 0) : 1000.000000
*(balance + 1) : 2.000000
*(balance + 2) : 3.400000
*(balance + 3) : 17.000000
*(balance + 4) : 50.000000


ในตัวอย่างข้างต้น p คือตัวชี้ไปยัง double ซึ่งหมายความว่าสามารถเก็บที่อยู่ของตัวแปรประเภท double ได้ เมื่อเรามีที่อยู่ใน p แล้ว *p จะให้ค่าที่อยู่ที่เก็บไว้ใน p ดังที่เราได้แสดงในตัวอย่างข้างต้น

Leave a Reply

Your email address will not be published. Required fields are marked *