Web888.vn
  • Khám phá
  • Kiến thức công nghệ
    • Học lập trình
      • Lập trình C/C++
      • Lập trình HTML
      • Lập trình Javascript
        • ReactJS framework
        • AngularJS framework
      • Cơ sở dữ liệu
        • Micrsoft SQL Server
      • Lập trình PHP
    • WORDPRESS
      • WordPress cơ bản
      • WordPress nâng cao
      • Chia sẻ WordPress
    • Machine Learning
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
  • Kinh doanh online – MMO
    • Tiếp thị liên kết
    • Drop shipping
    • Google Adsense
    • Kiếm tiền youtube
    • Tiền điện tử
    • Thương mại điện tử
  • Chia sẻ IT
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
  • Kỹ năng sống
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Học C căn bản
Mảng trong C (array), mảng một chiều, mảng đa chiều

Mảng trong C (array), mảng một chiều, mảng đa chiều

  • 11-01-2023
  • Toanngo92
  • 0 Comments

Có thể khó lưu trữ một tập hợp các phần tử dữ liệu tương tự trong các biến khác nhau. Ví dụ, hãy xem xét rằng bài toánlưu trữ số áo của tất cả 11 cầu thủ của một đội bóng đá phải được ghi lại. Lưu trữ số áo của mỗi người chơi trong các biến có tên riêng chắc chắn sẽ mệt mỏi hơn là có một biến chung cho họ. Đây là lí do chúng ta cần tới khái niệm mảng. Một mảng (array) là một tập hợp các phần tử dữ liệu cùng kiểu. Mỗi phần tử của mảng có cùng kiểu dữ liệu, cùng lớp lưu trữ (storage class) và cùng đặc điểm. Mỗi phần tử được lưu trữ ở các vị trí liên tiếp trên vùng nhớ máy tính. Các phần tử này được gọi là phần tử/thành viên của mảng.

Mục lục

  • Định nghĩa mảng
  • Các phần tử (array element) và chỉ mục/chỉ số (index/subscript) của mảng
  • Một số tiêu chuẩn khi sử dụng mảng
  • Xử lý mảng trong C
  • Mảng 2 chiều
  • Khởi tạo mảng đa chiều
  • Mảng 2 chiều ký tự (chuỗi)

Định nghĩa mảng

Một mảng có một số đặc điểm cụ thể và phải được xác định bằng cách sử dụng chúng. Những đặc điểm này như sau:

  • Lớp lưu trữ (storage class – tùy chọn)
  • Kiểu dữ liệu của các phần tử trong mảng
  • Tên mảng cho biết vị trí của phần tử đầu tiên của mảng
  • Kích thước mảng, một hằng số là biểu thức số nguyên đánh giá giá trị dương

Một mảng được định nghĩa giống như cách định nghĩa một biến, ngoại trừ tên mảng được theo sau bởi một hoặc nhiều biểu thức, được đặt trong dấu ngoặc vuông, [], chỉ định kích thước mảng.

Quy tắc tạo tên mảng cũng giống như quy tắc tạo tên biến. Tên mảng và tên biến không được trùng nhau dễ dẫn đến dễ gây nhầm lẫn. Nếu một khai báo như vậy được đưa ra trong một chương trình, trình biên dịch sẽ hiển thị một thông báo lỗi.

Cú pháp tổng quát:

storage_class data_type array_name[size_expression]

Ví dụ:

int main(){
  int danhsachcauthu[11];
  return 0;
}

Lưu ý, khi xác định mảng, kích thước mảng sẽ là 11, mặc dù các chỉ số của các phần tử riêng lẻ trong mảng sẽ nằm trong khoảng từ 0 đến 10.

Các phần tử (array element) và chỉ mục/chỉ số (index/subscript) của mảng

Mỗi phần tử của một mảng được xác định bởi một Chỉ mục duy nhất hoặc chỉ số dưới được gán cho nó. Kích thước của một mảng được xác định bởi số lượng chỉ số cần thiết để xác định duy nhất từng phần tử. Chỉ số là một số nguyên dương đặt trong dấu ngoặc vuông [] được đặt ngay sau tên mảng, không có khoảng trắng ở giữa. Một chỉ mục giữ các giá trị số nguyên và bắt đầu bằng 0. Do đó, một mảng cầu thủ có 11 phần tử sẽ được biểu diễn dưới dạng: danhsachcauthu[11]. Và để truy vấn từng cầu thủ trong mảng, chúng ta dùng cú pháp truy vấn:

danhsachcauthu[0]
danhsachcauthu[1]
danhsachcauthu[2]
....
danhsachcauthu[10]

Phần tử mảng bắt đầu bằng danhsachcauthu[0], và vì vậy phần tử cuối cùng là danhsachcauthu[10] chứ không phải danhsachcauthu[11]. Điều này là do trong C, chỉ số mảng bắt đầu từ 0; và như vậy đối với một mảng n phần tử, phần tử cuối cùng có chỉ số là n-1. Giới hạn của các giá trị chỉ mục được phép được gọi là giới hạn của chỉ số mảng, Giới hạn dưới và Giới hạn trên. Một chỉ mục hợp lệ phải có một giá trị nguyên giữa các giới hạn hoặc bằng một trong số chúng. Thuật ngữ hợp lệ được sử dụng vì một lý do rất cụ thể. Trong C, nếu lập trình viên truy cập một phần tử bên ngoài phạm vi chỉ mục hợp pháp danhsachcauthu[11], nó sẽ không tạo ra lỗi khi có liên quan đến trình biên dịch C. Tuy nhiên, nó có thể truy cập một số giá trị có thể dẫn đến kết quả không thể đoán trước. Ngoài ra còn có nguy cơ ghi đè lên dữ liệu hoặc mã chương trình. Do đó, lập trình viên phải đảm bảo rằng tất cả các chỉ số đều nằm trong giới hạn hợp lệ.

Một số tiêu chuẩn khi sử dụng mảng

  • Các phần tử của mảng có cùng kiểu. Điều này có nghĩa là nếu một mảng được khai báo kiểu int, thì nó không thể chứa các phần tử thuộc bất kỳ kiểu nào khác.
  • Mỗi phần tử của mảng có thể được sử dụng bất cứ khi nào cần sử dụng bằng cách truy xuất vào index của phần tử đó
  • Một phần tử của mảng có thể được gọi bằng một biến hoặc một biểu thức nguyên.
  • Array có thể mang kiểu dữ liệu int, char, float hoặc double

Xử lý mảng trong C

Một mảng được xử lý khác với một biến trong C. Hai mảng, ngay cả khi chúng có cùng kiểu và kích thước, không thể so sánh bằng. Hơn nữa, không thể gán trực tiếp mảng này cho mảng khác.
Thay vào đó, mỗi phần tử mảng phải được gán riêng cho phần tử tương ứng của mảng khác.
Các giá trị không thể được gán cho toàn bộ một mảng, ngoại trừ tại thời điểm khởi tạo. Tuy nhiên, các phần tử riêng lẻ có thể được gán giá trị mà còn có thể được so sánh bình thường.

Ví dụ:

#include <stdio.h>
void examplearrcompare(){
	int arr[2];
	int arr_2[2];
	arr[0] = 1;
	arr[1] = 2;
	arr_2[0] = 1;
	arr_2[1] = 2;
	if(arr == arr_2){
		printf("bang nhau");
	}else{
	    printf("khong so sanh dc");
	}
}

void examplearrassign(){
	int arr[2] = {1,2};
	arr[0] = 1;
	arr[1] = 2;
}

void examplearrassign2(){
	int i = 0,num = 0;
	printf("Nhap so phan tu mang:");
	scanf("%d",&num);
	int arr[num];
	for(i = 0; i < num; i++){
		printf("Nhap phan tu so %d cua mang:",i+1);
		scanf("%d",&arr[i]);
	}
	for(i = 0 ; i < num; i++){
		printf("\nPhan tu so %d cua mang la: %d",i+1,arr[i]);
	}
}



int main()
{
   examplearrcompare();
   examplearrassign();
   examplearrassign2();

   return 0;
}

Các phần tử mảng không thể được khởi tạo, trừ khi mỗi phần tử được gán một giá trị riêng. Không nên sử dụng mảng nếu không có sự phân bổ thích hợp, vì kết quả trong những trường hợp như vậy là không thể đoán trước.
Điều này là do các vị trí lưu trữ được phân bổ được gán cho mảng không được khởi tạo tự động. Bất cứ khi nào các phần tử của một mảng như vậy được sử dụng trong các biểu thức số học, thì các giá trị đã tồn tại trước đó sẽ được sử dụng, các giá trị này không được đảm bảo là cùng loại với định nghĩa mảng, trừ khi mảng đó các yếu tố được khởi tạo rất rõ ràng. Điều này không chỉ đúng với mảng mà còn đúng với các biến thông thường.
Ví dụ:

#include <stdio.h>
void examplearrassign2(){
	int i = 0,num = 0;
	printf("Nhap so phan tu mang:");
	scanf("%d",&num);
	int arr[num];
	for(i = 0; i < num; i++){
		printf("Nhap phan tu so %d cua mang:",i+1);
		scanf("%d",&arr[i]);
	}
	for(i = 0 ; i < num; i++){
		printf("\nPhan tu so %d cua mang la: %d",i+1,arr[i]);
	}
}

int main()
{
   examplearrassign2();
   return 0;
}

Ví dụ thuật toán tìm kiếm phần tử có giá trị lớn nhất trong mảng và tính giá trị trung bình của các phần tử trong mảng

#include <stdio.h>
void examplearray1(){
	int ary[10];
    int i, total, high;
    for(i=0; i<10; i++)
    {
	printf("\n Enter value: %d : ", i+1);
	scanf("%d",&ary[i]);
    }
     /* Displays highest of the entered values */
     high = ary[0];
     for(i=1; i<10; i++)
     {
		if(ary[i] > high)
			high = ary[i];
     }
     printf("\nHighest value entered was %d", high);
     /*	prints average of values entered for ary[10] */
     for(i=0,total=0; i<10; i++){
     		total = total + ary[i];
	 }
     printf("\nThe average of the elements of ary is %d",total/i);
}
int main()
{
   examplearray1();
   return 0;
}

Ví dụ khai báo mảng ký tự và gán giá trị vào kí tự vào các phần tử bên trong mảng

#include <stdio.h>
void examplearray2(){
	   char alpha[26];
	   int i, j;
	   for(i=65,j=0; i<91; i++,j++)
	   {
	 	alpha[j] = i;
		printf("The character now assigned is %c - %d \n", alpha[j], alpha[j]);
	   }

	  // getchar();
}

int main()
{
   examplearray2();
   return 0;
}

Ngoài ra, chúng ta có thể khởi tạo giá trị các phần tử trong mảng bằng cách gán một danh sách các giá trị được phân tách bằng dấu phẩy và được đặt trong dấu ngoặc nhọn { } cho tên mảng. Các giá trị trong dấu ngoặc nhọn được gán cho các phần tử của mảng theo thứ tự xuất hiện của chúng, trừ mảng ký tự sẽ được nói ở phần tiếp theo.

Ví dụ:

int main(){
   int arr1[3] = {3,2,4};
   int str2[10] = "chuoi vi du";
   float arr3[4] = {1,2.5,30,4.3};
   return 0;
}

Trong trường hợp khởi tạo rõ ràng, storage class là extern hoặc static, các phần tử mảng được đảm bảo (không giống như class automatic) được khởi tạo bằng 0.

Trong tình huống sử dụng cách khởi tạo bằng {}, không cần thiết phải khai báo kích thước của mảng đang được khởi tạo. Nếu kích thước của mảng bị bỏ qua, trình biên dịch sẽ tính toán kích thước mảng bằng cách đếm các giá trị khởi tạo. Ví dụ, khai báo mảng bên ngoài sau đây sẽ đánh giá kích thước của mảng arr là 3 vì có 3 giá trị khởi tạo.

int main(){
  int arr[] = {2,3,5};
  return 0;
}

Mảng ký tự/chuỗi (character arrays/string)

Một chuỗi có thể được định nghĩa là một mảng kiểu ký tự, được kết thúc bằng ký tự NULL. Mỗi ký tự của chuỗi chiếm một byte và ký tự cuối cùng của chuỗi luôn là ký tự ‘\0’. ‘\0’ này được gọi là ký tự null. Nó là một chuỗi thoát như ‘\n’ và là viết tắt của một ký tự có giá trị 0 (không). Vì ‘\0’ luôn là ký tự cuối cùng của một chuỗi, nên các mảng ký tự phải dài hơn một ký tự so với chuỗi dài nhất mà chúng bắt buộc phải giữ. Ví dụ, một mảng arr, chứa 20 ký tự nên được khai báo là:

char arr[21];

Vị trí bổ sung được sử dụng để lưu trữ ký tự rỗng. Hãy nhớ rằng ký tự kết thúc (ký tự loại bỏ) rất quan trọng.
Các giá trị chuỗi có thể được nhập vào bằng hàm scanf(). Đối với chuỗi arr đã khai báo ở trên, câu lệnh nhận giá trị sẽ như sau:

scanf("%s" &arr);
// another input way can allow space in string
gets(arr);
//  another input way can allow space in string
fgets(arr,100,stdin);
// refference https://stackoverflow.com/questions/20572105/why-cant-i-use-a-space-in-my-array-program

Ví dụ:

#include <stdio.h>
void examplestringaschararray(){
   char ary[10];
   int i;
   printf("\n Enter string : ");
   scanf("%s",&ary); 
   printf("\n The string is %s \n\n", ary);
   for (i=0; i<10; i++)
	printf("\t%d", ary[i]);
}
int main(){
  examplestringaschararray();
  return 0;
}

Xét chương trình chạy khi nhập liệu đủ 9 ký tự

 Enter string : toan12345

 The string is toan12345

        116     111     97      110     49      50      51      52      53      0

Xét chương trình chạy khi nhập liệu chưa đủ 9 ký tự


 Enter string : abcd

 The string is abcd

        97      98      99      100     0       -1      -1      -1      41      0

Trong ví dụ trên, khi chỉ có 4 ký tự được nhập thì ký tự thứ 5 là ký tự null. Điều này thực sự chỉ ra rằng chuỗi đã kết thúc. Các ký tự còn lại không thể đoán trước.

Trong trường hợp trên, tầm quan trọng của ký tự null trở nên rõ ràng. Ký tự null thực sự chỉ định phần cuối của chuỗi và là cách duy nhất mà các hàm làm việc với chuỗi sẽ biết vị trí của phần cuối của chuỗi.

Mặc dù C không có kiểu dữ liệu chuỗi nhưng nó cho phép các hằng chuỗi. Hằng chuỗi là một danh sách các ký tự được mã hóa trong dấu ngoặc kép(“”). Giống như bất kỳ hằng nào khác, nó không thể bị thay đổi trong chương trình. C hỗ trợ nhiều hàm chuỗi, được tìm thấy trong file header chuẩn string.h, sẽ được đề cập riêng ở bài chuỗi.

Mảng 2 chiều

Ở các phần trước, chúng ta đã thảo luận về mảng là mảng một chiều. Điều này có nghĩa là các mảng chỉ có một chỉ số index. Mảng có thể có nhiều hơn một chiều. Mảng đa chiều giúp biểu diễn các đối tượng đa chiều dễ dàng hơn, chẳng hạn như biểu đồ có hàng và cột. Mảng nhiều chiều được định nghĩa giống như mảng một chiều, ngoại trừ một cặp dấu ngoặc vuông [] riêng biệt, được yêu cầu trong trường hợp mảng hai chiều. Một mảng ba chiều sẽ có ba cặp dấu ngoặc vuông, v.v.

Cú pháp tổng quát:

storage_class data_type arr[expression1][expression2]...[expressionN]

trong đó ary là một mảng có lớp lưu trữ storage_class, kiểu dữ liệu data_type và exp1, exp2, expN là các biểu thức số nguyên dương cho biết số lượng phần tử mảng được liên kết với các index.

Dạng đơn giản nhất và thông dụng nhất của mảng đa chiều là mảng hai chiều. Mảng hai chiều có thể được coi là một mảng gồm hai mảng ‘một chiều’.Chúng ta có thể hình dung mảng 2 chiều tương tự một bảng bao gồm hàng và cột trong excel. Để định vị thông tin, hàng và cột bắt buộc được xác định và thông tin được đọc từ vị trí mà chúng (hàng và cột) giao nhau.

Vì vậy, ta coi mảng hai chiều là một lưới chứa các hàng và cột trong đó mỗi phần tử được chỉ định duy nhất bằng tọa độ hàng và cột của nó. Ví dụ định nghĩa một mảng 3 hàng và 2 cột như sau:

int arr[3][2];

Mảng này sẽ chứa 3 x 2 = (6) phần tử và chúng có thể được biểu diễn dưới dạng:

Cột
01
Hàng0ptu1pt2
1pt3pt4
2pt5pt6
Bảng mô phỏng phần tử mảng 2 chiều

Khởi tạo mảng đa chiều

Một định nghĩa mảng nhiều chiều có thể bao gồm việc gán các giá trị ban đầu. Phải cẩn thận về thứ tự mà các giá trị ban đầu được gán cho các phần tử mảng (chỉ có thể khởi tạo các mảng bên ngoài và mảng tĩnh). Các phần tử của hàng đầu tiên của mảng hai chiều sẽ được gán giá trị trước, sau đó là các phần tử của hàng thứ hai, v.v. Ví dụ:

int arr[3][4] = {3,2,1,4,5,4,2,3,1,4,7,8};

Dữ liệu sẽ được lưu trữ như sau:

arr[0][0]: 3arr[0][1]: 2arr[0][2]: 1arr[0][3]: 4
arr[1][0]: 5arr[1][1]: 4arr[1][2]: 2arr[1][1]: 3
arr[2][0]: 1arr[2][1]: 4arr[2][2]: 7arr[1][3]: 8

Ví dụ:

#include <stdio.h>
#include <string.h>
void testtwodimenarr(){
	int ary[3][4] = {1,100,3,4,5,6,7,8,9,10,11,12};
	int i,j;
	for(i = 0; i < 3 ; i++){
		for (j = 0; j < 4 ; j++){
			printf("%d |", ary[i][j]);
		}
		printf("\n");
	}
}
void main()
{
  testtwodimenarr();
}

Mảng 2 chiều ký tự (chuỗi)

Ngoài ra, mảng 2 chiều có thể sử dụng trong tình huống danh sách chuỗi ( một danh sách mảng ký tự)

Một chuỗi có thể được biểu diễn dưới dạng một mảng ký tự một chiều. Mỗi ký tự trong chuỗi sẽ được lưu trữ trong một phần tử của mảng. Mảng chuỗi này có thể được tạo bằng cách sử dụng mảng ký tự hai chiều. Chỉ mục bên trái hoặc chỉ số dưới xác định số lượng chuỗi và chỉ mục bên phải chỉ định độ dài tối đa của mỗi chuỗi.

Ví dụ:

char arr[5][10];

Trong ví dụ trên, chúng ta định nghĩa ra mảng bao gồm 5 phần tử chuỗi (mảng ký tự), mỗi chuỗi có 9 phần tử ký tự (bao hồm ký tự null là đủ 10).

Ví dụ sử dụng mảng chuỗi:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

testtwodimenstrarr(){
	int i, n = 0; 
		int item;
		char x[10][12];
		char temp[12];
				
	printf("Enter each string on a separate line\n\n");
	printf("Type 'END' when over \n\n");
	/* read in the list of strings */
		do
		{
			printf("String %d : ", n+1);
			scanf("%s",x[n]);
		} while (strcmp(x[n++], "END"));
	/*reorder the list of strings */
	n--;
	printf("%d",n);
	for(item=0; item<n-1; ++item)
   {
      /* find lowest of remaining strings */
	for(i=item+1; i<n; ++i)
	{
		if(strcmp (x[item], x[i]) > 0)
			{
			/*interchange two stings */
			strcpy (temp, x[item]);
			strcpy (x[item], x[i]);
			strcpy (x[i], temp);
	    	}
	 }
    }
/* Display the arranged list of strings */
printf("Recorded list of strings : \n");
     for(i = 0; i < n ; ++i)
     {
	printf("\nString %d is %s", i+1, x[i]);
     }

}


int main(){
	testtwodimenstrarr();
	return 0;
}

Bài tập

1. Viết chương trình nhập vào chuỗi đém số ký tự nguyên âm của chuỗi
2. Viết chương trình nhập vào một mảng 5 phần tử và sắp xếp mảng theo chiều xuôi, và ngược
3. Viết chương trình đảo ngược mảng sau:
36 , 43, 53, 64, 80

4. Viết chương trình theo yêu cầu sau:
Có 2 mảng arr1 và arr2 có 5 phần tử.
Yêu cầu nhập liệu arr1.
1. Copy toàn bộ phần tử sang arr2
2. Copy toàn bộ phần tử sang arr2 nhưng theo chiều ngược lại

Bài viết liên quan:

Các lệnh rẽ nhánh vô điều kiện trong C – return, goto, break, continue, hàm exit
Vòng lặp trong C – các cấu trúc vòng lặp for, while, do while
Điều kiện trong C – các cấu trúc điều kiện if/else, switch case
Các toán tử và biểu thức trong C
Thao tác Input / Output trong C
Các kiểu dữ liệu cơ bản trong C
Biến và hằng số, định danh trong ngôn ngữ C
Cấu trúc chương trình C, danh sách từ khóa (keywords) trong ngôn ngữ C
Giới thiệu mở đầu – mô tả khái niệm phần mềm trước khi bắt đầu học lập trình C
Lược đồ giải thuật và mã giả để biểu diễn thuật toán bằng hình học và cú pháp và các cấu trúc luồng chạy trong lập trình
Cài đặt Visual Studio Code để lập trình C/C++ trên Windows và MacOs
Cài đặt dev C++ để lập trình C trên Windows 10

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

Mảng trong C (array), mảng một chiều, mảng đa chiều

Hướng dẫn cài đặt Microsoft SQL Server và kết nối CSDL từng bước cho người mới

Vòng lặp trong C – các cấu trúc vòng lặp for, while, do while

Điều kiện trong C – các cấu trúc điều kiện if/else, switch case

Các lệnh rẽ nhánh vô điều kiện trong C – return, goto, break, continue, hàm exit

Giới thiệu

web888.vn là chuyên trang chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với web888

© web888.vn - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.

Your personal data will be used to support your experience throughout this website, to manage access to your account, and for other purposes described in our privacy policy.

Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×