XtGem Forum catalog
GamesCapNhat.Wap.Sh
HOME - Lập Trình đồng hồ gỗ ĐỨC PHỔ WAP LẬP TRÌNH
Xem Thêm >>
Lập Trình C

Mảng 2 Chiều Ở Ngôn Ngữ Lập trình C

V.3 - Mảng 2 chiều

V.3.1 - Định nghĩa mảng hai chiều

Mảng hai chiều có thể hiểu như bảng gồm các dòng các cột, các phần tử thuộc cùng một kiểu dữ liệu nào đó. Mảng hai chiều được  định nghĩa như sau.

 Cú pháp    Ki ểu_mảng   tên_mảng  [sd][sc];

Trong đó:

 - Kiểu_mảng:  đây là kiểu của mảng, là tên một kiểu dữ liệu đã tồn tại, có thể là kiểu chuẩn hoặc kiểu dữ liệu do người lập trình định nghĩa.

 - tên_mảng :  là tên của mảng, do người lập trình đặt, theo quy tắc về tên của C. 

- sd, sc  : là  hằng (hoặc biểu thức hằng) nguyên, dương  tương ứng là số dòng và số cột mảng, số phần tử của mảng sẽ là sd*sc.

 Ví dụ:  

 int  a[2][5];   // a là mảng số nguyên có 2 dòng, 5 cột (có 10 phần tử)  

 float D[3][10]; // D là mảng số thực có 3 dòng, 10 cột (có 30 phần tử)  

 char DS[5][30];  // DS là mảng kí tự có 5 dòng, 30 cột 

  Khi gặp một định nghĩa mảng,  chương trình dịch sẽ cấp phát một vùng nhớ liên tiếp có kích thước là sd*sc*sizeof (Kiểu_mảng) cho mảng.  Có thể coi mảng 2 chiều n dòng, m cột là mảng 1 chiểu có n phần tử, mỗi phần tử lại là 1 mảng một chiều có m phần tử (mảng của mảng).

 Ví dụ với float D[3][10]  có thể xem D là mảng có 3 phần tử D[0], D[1], D[2], mỗi phần tử này là mảng có 10 phần tử. 

V.3.2 – Truy xuất các phần tử mảng hai chiều

Một phần tử của mảng 2 chiều được xác định qua tên (tên của mảng) và chỉ số dòng, chỉ số cột của nó trong mảng theo cú pháp sau:

 tên_mảng [csd][csc] 

Với csd là số nguyên xác định chỉ số dòng và csc là số hiệu cột cũng như trong mảng 1 chiều các chỉ số  được  tính từ 0. Tức là  0 ≤ csd ≤ sd-1 và 0 ≤ csc ≤ sc-1.  

Lưu ý: Các phần tử của mảng 2 chiều cũng được dùng như các biến đơn, trừ trường hợp khi nhập giá trị cho các phần tử mảng kiểu float bằng hàm scanf thì bạn nên sử dụng biến (đơn) trung gian, sau đó gán giá trị của biến đó vào phần tử mảng chứ  không nên sử dụng toán tử & để nhập trực tiếp phần tử của mảng. 

 V.3.3 – Khởi đầu giá trị các phần tử mảng hai chiều

Các phần tử mảng hai chiều cũng có thể được khởi đầu giá trị theo cú pháp (4 dạng sau):   

1.  Kiểu_mảng  tên_mảng  [sd][sc] = {{kđ_dòng_1},{ kđ_dòng_2},..,{ kđ_dòng_k}};  

 2.  Kiểu_mảng  tên_mảng  [ ][sc] = {{kđ_dòng_1},{ kđ_dòng_2},..,{ kđ_dòng_k}};  

 3.  Kiểu_mảng  tên_mảng  [sd][sc] = { gt_1, gt_2,...,gt_n };  

 4.  Kiểu_mảng  tên_mảng  [ ][sc] = { gt_1, gt_2,...,gt_n }; Cú pháp trên có thể giải thích như sau:

 • dạng 1: có k bộ giá trị sẽ được gán cho k dòng đầu tiên của mảng (k ≤ sd ), với mỗi dòng (được coi như mảng một chiều) được khởi tạo giá trị như mảng một chiều: dòng thứ nhất được khởi đầu bởi {kđ_dòng_1}, dòng thứ hai được khởi đầu bởi {kđ_dòng_1},.., dòng thứ k được khởi đầu bởi {kđ_dòng_k}. Yêu cầu k ≤ sd, ngược lại chương trình sẽ báo lỗi. Các dòng cuối của mảng nếu không có bộ khởi đầu tương ứng thì sẽ được tự động gán giá trị 0 (hoặc NULL nếu là con trỏ).

 • dạng 2: (không xác định số dòng) chương trình dịch sẽ tự động ấn định số dòng của mảng  bằng số bộ khởi đầu (  = k), sau đó thực hiện khởi đầu như dạng 1.

 • dạng 3: n  giá trị trong bộ khởi đầu được gán cho các phần tử mảng theo cách: sc giá trị đầu tiên trong các giá trị khởi đầu (gt_1,..,gt_sc) được gán tuần tự cho các phần tử của dòng thứ nhất trong mảng, sc  phần tử kế tiếp sẽ gán cho các phần tử ở dòng thứ 2,... nếu phần tử nào của mảng không có giá trị khởi đầu sẽ được gán 0 (con trỏ  là NULL) - với điều kiện  n ≤ sd*sc, ngược lại là lỗi.

 • dạng 4: số dòng của mảng sẽ được chương trình tự tính theo số giá  trị trong bộ khởi đầu theo công thức  sd = n +1, và khởi đầu như dạng 3.

 Ví dụ:   

 int a[3][2] = {{1,2},{3},{4,5}}; thì các phần tử của a như sau:           

  a[0][0]=1, a[0][1]=2,   a[1][0]=3, a[1][1]= 0, a[2][0]=4,a[2][1]=5; à int b[ ][2] = {{1,2},{3},{4,5}};  thì là mảng 3 dòng, 2 cột các phần tử của a như sau: 

            b[0][0]=1, b[0][1]=2,   b[1][0]=3,b[1][1]= 0, b[2][0]=4,b[2][1]=5; à int c[ ][2] = {1,2,3,4,5};  thì  số dòng của c là mảng 5/2 +1 =3 dòng, các phần tử của a như sau:

             c[0][0]=1, c[0][1]=2,   c[1][0]=3,c[1][1]= 4, b[2][0]=5,b[2][1]=0; V.3.3 

- Một số ví dụ về mảng hai chiều 

Ví dụ V.5: Chương trình nhập mảng A(n,m), 1≤ n,m ≤ 5, các số nguyên từ bàn phím, in mảng ra màn hình theo yêu cầu các phần tử cùng một hàng  được in trên một dòng của màn hình, các phần tử cách nhau một dấu trống.  

#include <stdio.h>

 #include <conio.h>

 void main){ <; //xóa màn hình

 const int max =5; // kích thước tối đa 

 int A[max][max];

 int n,m,i,j;

 do{

printf("\nNhap so dong cua mang  = ");

 scanf"; printf("\nNhap so cot cua mang  = ");

scanf"; 

  } while(n<1 || n>max|| m<1 || m>max); 

printf"\nNhapmangco;

 for0

 for0 

 { 

printf"A[;

 scanf";  

} printf("\nCac phan tu mang la  \n"); 

for0  

{

  printf("\n");  

   for0   

  printf";  

  } getch);<, B(n,m), 1≤ n,m ≤ 5, các số thực từ bàn phím, tính in  ra màn hình ma trận C = A+B. Giải: Trước khi viết chương trình chúng ta lưu ý đến mấy vấn đề:  à C = A+B có nghĩa là các phần của C được  tính C[i][j] = A[i][j] + B[i][j] à chỉ có thể cộng hai ma trận A,B cùng kích thước và C cũng cùng kích thước với A,B à do các phần tử mảng có kiểu là float vì vậy khi nhập ta nên dùng biến phụ.  

#include <stdio.h>

 #include <conio.h>

 void main){<; 

const int max =5; //số dòng, cột tối đa 

float A[max][max],B[max][max],C[max][max]; int n,m,i,j; 

float x; 

do{ 

printf("\nNhap so dong cua ma tran  = "); 

scanf";

 printf("\nNhap so cot cua ma tran  = ");

 scanf";  

 } while(n<1 || n>max|| m<1 || m>max);

for0 for0  

 { printf"A[;

 scanf";A[i][j]=x; 

  } 

printf"\nNhapBco;

 for0 for0 

   { printf"B[; 

scanf";B[i][j]=x; 

}

 for0

 for0    

 C[i][j]=A[i][j]+B[i][j];  

printf("\nCac phan tu ma tran C la  \n");

 for0   { printf("\n"); 

    for0    

 printf0;  

  }

 getch0, 1≤ n,n ≤ 5, các số nguyên từ bàn phím, sau đó kiểm tra và thông báo ma trận đó có đối xứng hay không . 

Giải: Một ma trận  A là đối xứng trước hết nó phải là ma trận  vuông và các phần tử của nó đối xứng nhau qua đường chéo chính, tức là A[i][j] =A[j][i]. Vậy chúng ta kiểm tra một ma trận  đối xứng theo cách sau:  V ới mỗi i,j -1 nếu tồn tại  i,j mà A[i][j] != A[j][i] thì ta kết luận A không đối xứng, ngược lại A là đối xứng.  Tất nhiên chúng ta không cần phải xét mọi cặp (i,j)  có thể, vì nếu như vậy thì: - cặp (A[i][j] A[j][i]), và  (A[j][i], A[i][j]) thực chất là một nhưng lại hai lần so sánh - phần tử trên đường chéo chính A[i][i] được so sánh với chính nó. Vì thế chúng ta chỉ xét các chỉ số (i,j) mà phần tử A[i][j] nằm thực sự phía trên của đường chéo chính. tức là chỉ cần xét các cặp phần tử  (A[i][j], A[j][i]) với i  chạy từ 0 tới n-1 và với j chạy từ i+1 tới n-1 là đủ. Hơn nữa chúng ta chỉ duyệt các cặp (A[i][j], A[j][i]) nếu chưa phát hiện được cặp nào khác nhau.    V ậy ta có thể mô tả như sau:  d=0; // d là biến để đánh dấu ghi nhận có gặp một cặp (A[i][j]!= A[j][i])  thì d=1  for(i=0; (i<n) && (d= =0); i++)  for1 && (d= =0); j++)  if(A[i][j]!=A[j][i]) d=1;  Kết thúc đoạn lệnh lặp trên chỉ có hai khả năng - nếu d=1 tức là có cặp (A[i][j]!=A[j][i]) tức là ma trận  không đối xứng. - ngược lại,(d=0) thì ma trận  là đối xứng.  

#include <stdio.h>

 #include <conio.h>

 void main){<; 

const int max =5;

 int A[max][max];

 int n,d,i,j;

 do{

 printf("\nNhap so dong, so cot cua ma tran = ");

 scanf";

 }  while(n<1 || n>max); 

printf"\nNhapmatranvuongcap;

 for0

 for0  

  { printf"A[;

 scanf"; 

  } 

for(i=0,d=0; (i<n)&&(d==0); i++)

 for(j=0; (j<n)&&(d==0); j++)

 if(A[i][j]!=A[j][i]) d=1; 

if(d) printf("\nMa tran khong doi xung");

else printf("\nMa tran doi xung");

 getch(); 

}  

<< Bài Viết Khác
Danh mục
Game Mobile
Phần Mềm - Ứng Dụng
Hình Nền Đẹp
Kinh Nghiệm Thủ Thuật
Giải Trí Thư Giản
Phim Tổng Hợp
Hổ Trợ Học Tập
Tiện Ích Wap Online
Điện Thoại Bạn Có Chưa?
game online - kinh nghiem thu thuat - app android - game android - phim hanh dong - lap trinh c - lap trinh pascal - giai tri
U-ON