Bài giảng Ngôn ngữ lập trình C/C++ - Phạm Hồng Thái - Chương 3: Cấu trúc điều khiển và dữ liệu kiểu mảng
Nói chung việc thực hiện chương trình là hoạt động tuần tự, tức thực hiện từng lệnh một từ câu lệnh bắt đầu của chương trình cho đến câu lệnh cuối cùng. Tuy nhiên, để việc lập trình hiệu quả hơn hầu hết các NNLT bậc cao đều có các câu lệnh rẽ nhánh và các câu lệnh lặp cho phép thực hiện các câu lệnh của chương trình không theo trình tự tuần tự như trong văn bản.
Phần này chúng tôi sẽ trình bày các câu lệnh cho phép rẽ nhánh như vậy. Để thống nhất mỗi câu lệnh được trình bày về cú pháp (tức cách viết câu lệnh), cách sử dụng, đặc điểm, ví dụ minh hoạ và một vài điều cần chú ý khi sử dụng lệnh.
khó lập trình vì vậy trong mục này chúng ta chỉ bàn đến mảng hai chiều. Đối với mảng một chiều m thành phần, nếu mỗi thành phần của nó lại là mảng một chiều n phần tử thì ta gọi mảng là hai chiều với số phần tử (hay kích thước) mỗi chiều là m và n. Ma trận là một minh hoạ cho hình ảnh của mảng hai chiều, nó gồm m dòng và n cột, tức chứa m x n phần tử, và hiển nhiên các phần tử này có cùng kiểu. Tuy nhiên, về mặt bản chất mảng hai chiều không phải là một tập hợp với m x n phần tử cùng kiểu mà là tập hợp với m thành phần, trong đó mỗi thành phần là một mảng một chiều với n phần tử. Điểm nhấn mạnh này sẽ được giải thích cụ thể hơn trong các phần trình bày về con trỏ của chương sau. 0 1 2 3 0 1 2 Hình trên minh hoạ hình thức một mảng hai chiều với 3 dòng, 4 cột. Thực chất trong bộ nhớ tất cả 12 phần tử của mảng được sắp liên tiếp theo từng dòng của mảng như minh hoạ trong hình dưới đây. dòng 0 dòng 1 dòng 2 Khai báo [m][n] ; m, n là số hàng, số cột của mảng. kiểu thành phần là kiểu của m x n phần tử trong mảng. Trong khai báo cũng có thể được khởi tạo bằng dãy các dòng giá trị, các dòng cách nhau bởi dấu phẩy, mỗi dòng được bao bởi cặp ngoặc {} và toàn bộ giá trị khởi tạo nằm trong cặp dấu {}. Sử dụng Tương tự mảng một chiều các chiều trong mảng cũng được đánh số từ 0. Không sử dụng các thao tác trên toàn bộ mảng mà phải thực hiện thông qua từng phần tử của mảng. Để truy nhập phần tử của mảng ta sử dụng tên mảng kèm theo 2 chỉ số chỉ vị trí hàng và cột của phần tử. Các chỉ số này có thể là các biểu thức thực, khi đó C++ sẽ tự chuyển kiểu sang nguyên. Ví dụ: Khai báo 2 ma trận 4 hàng 5 cột A, B chứa các số nguyên: int A[3][4], B[3][4] ; Khai báo có khởi tạo: int A[3][4] = { {1,2,3,4}, {3,2,1,4}, {0,1,1,0} }; với khởi tạo này ta có ma trận: 1 2 3 4 3 2 1 4 0 1 1 0 trong đó: A[0][0] = 1, A[0][1] = 2, A[1][0] = 3, A[2][3] = 0 … Trong khai báo có thể vắng số hàng (không được vắng số cột), số hàng này được xác định thông qua khởi tạo. float A[][3] = { {1,2,3}, {0,1,0} } ; trong khai báo này chương trình tự động xác định số hàng là 2. Phép khai báo và khởi tạo sau đây là cũng hợp lệ: float A[][3] = { {1,2}, {0} } ; chương trình cũng xác định số hàng là 2 và số cột (bắt buộc phải khai báo) là 3 mặc dù trong khởi tạo không thể xác định được số cột. Các phần tử chưa khởi tạo sẽ chưa được xác định cho đến khi nào nó được nhập hoặc gán giá trị cụ thể. Trong ví dụ trên các phần tử A[0][2], A[1][1] và A[1][2] là chưa được xác định. Ví dụ minh hoạ : Nhập, in và tìm phần tử lớn nhất của một ma trận. #include #include #include main() { float a[10][10] ; int m, n ; // số hàng, cột của ma trận int i, j ; // các chỉ số trong vòng lặp int amax, imax, jmax ; // số lớn nhất và chỉ số của nó clrscr(); cout > m >> n ; for (i=0; i<m; i++) for (j=0; j<n; j++) { cout > a[i][j] ; } amax = a[0][0]; imax = 0; jmax = 0; for (i=0; i<m; i++) for (j=0; j<n; j++) if (amax < a[i][j]) { amax = a[i][j]; imax = i; jmax = j; } cout << "Ma trận đã nhập\n" ; cout << setiosflags(ios::showpoint) << setprecision(1) ; for (i=0; i<m; i++) for (j=0; j<n; j++) { if (j==0) cout << endl; cout << setw(6) << a[i][j] ; } cout << "Số lớn nhất là " << setw(6) << amax << endl; cout << "tại vị trí (" << imax << "," << jmax << ")" ; getch(); } Ghi chú: Khi làm việc với mảng (1 chiều, 2 chiều) do thói quen chúng ta thường tính chỉ số từ 1 (thay vì 0), do vậy trong mảng ta có thể bỏ qua hàng 0, cột 0 bằng cách khai báo số hàng và cột tăng lên 1 so với số hàng, cột thực tế của mảng và từ đó có thể làm việc từ hàng 1, cột 1 trở đi. : Nhân 2 ma trận. Cho 2 ma trận A (m x n) và B (n x p). Tính ma trận C = A x B, trong đó C có kích thước là m x p. Ta lập vòng lặp tính từng phần tử của C. Giá trị của phần tử C tại hàng i, cột j chính là tích vô hướng của hàng i ma trận A với cột j ma trận B. Để tránh nhầm lẫn ta qui ước bỏ các hàng, cột 0 của các ma trận A, B, C (tức các chỉ số được tính từ 1 trở đi). #include #include #include main() { float A[10][10], B[10], C[10][10] ; int m, n, p ; // số hàng, cột của ma trận int i, j, k ; // các chỉ số trong vòng lặp clrscr(); cout > m >> n >> p; // Nhập ma trận A for (i=1; i<=m; i++) for (j=1; j<=n; j++) { cout > A[i][j] ; } // Nhập ma trận B for (i=1; i<=n; i++) for (j=1; j<=p; j++) { cout > B[i][j] ; } // Tính ma trận C = A x B for (i=1; i<=m; i++) for (j=1; j<=p; j++) { C[i][j] = 0; for (k=1; k<=n; k++) C[i][j] += A[i][k]*B[k][j] ; } // In kết quả cout << "Ma trận kết quả\n" ; cout << setiosflags(ios::showpoint) << setprecision(2) ; for (i=1; i<m; i++) for (j=1; j<n; j++) { if (j==1) cout << endl; cout << setw(6) << a[i][j] ; } getch(); } bài tẬp Lệnh rẽ nhánh Nhập một kí tự. Cho biết kí tự đó có phải là chữ cái hay không. Nhập vào một số nguyên. Trả lời số nguyên đó: âm hay dương, chẵn hay lẻ ? Cho n = x = y và bằng: a. 1 b. 2 c. 3 d. 4 Hãy cho biết giá trị của x, y sau khi chạy xong câu lệnh: if (n % 2 == 0) if (x > 3) x = 0; else y = 0; Tính giá trị hàm Viết chương trình giải hệ phương trình bậc nhất 2 ẩn: Nhập 2 số a, b. In ra max, min của 2 số đó. Mở rộng với 3 số, 4 số ? Nhập 3 số a, b, c. Hãy cho biết 3 số trên có thể là độ dài 3 cạnh của một tam giác ? Nếu là một tam giác thì đó là tam giác gì: vuông, đều, cân, vuông cân hay tam giác thường ? Nhập vào một số, in ra thứ tương ứng với số đó (qui ước 2 là thứ hai, …, 8 là chủ nhật). Nhập 2 số biểu thị tháng và năm. In ra số ngày của tháng năm đó (có kiểm tra năm nhuận). Lấy ngày tháng hiện tại làm chuẩn. Hãy nhập một ngày bất kỳ trong tháng. Cho biết thứ của ngày vừa nhập ? Lệnh lặp Giá trị của i bằng bao nhiêu sau khi thực hiện cấu trúc for sau: for (i = 0; i < 100; i++); Giá trị của x bằng bao nhiêu sau khi thực hiện cấu trúc for sau: for (x = 2; i < 10; x+=3) ; Bạn bổ sung gì vào lệnh for sau: for ( ; nam < 1997 ; ) ; để khi kết thúc nam có giá trị 2000. Bao nhiêu kí tự ‘X’ được in ra màn hình khi thực hiện đoạn chương trình sau: for (x = 0; x 0; y --) cout << ‘X’; Nhập vào tuổi cha và tuổi con hiện nay sao cho tuổi cha lớn hơn 2 lần tuổi con. Tìm xem bao nhiêu năm nữa tuổi cha sẽ bằng đúng 2 lần tuổi con (ví dụ 30 và 12, sau 6 năm nữa tuổi cha là 36 gấp đôi tuổi con là 18). Nhập số nguyên dương N. Tính: Nhập số nguyên dương n. Tính: n dấu căn n dấu chia Nhập số tự nhiên n. In ra màn hình biểu diễn của n ở dạng nhị phân. In ra màn hình các số có 2 chữ số sao cho tích của 2 chữ số này bằng 2 lần tổng của 2 chữ số đó (ví dụ số 36 có tích 3*6 = 18 gấp 2 lần tổng của nó là 3 + 6 = 9). Số hoàn chỉnh là số bằng tổng mọi ước của nó (không kể chính nó). Ví dụ 6 = 1 + 2 + 3 là một số hoàn chỉnh. Hãy in ra màn hình tất cả các số hoàn chỉnh < 1000. Các số sinh đôi là các số nguyên tố mà khoảng cách giữa chúng là 2. Hãy in tất cả cặp số sinh đôi < 1000. Nhập dãy kí tự đến khi gặp kí tự ‘.’ thì dừng. Thống kê số chữ cái viết hoa, viết thường, số chữ số và tổng số các kí tự khác đã nhập. Loại kí tự nào nhiều nhất ? Tìm số nguyên dương n lớn nhất thoả mãn điều kiện: . . Cho e = 1e-6. Tính gần đúng các số sau: Số pi theo công thức Euler: dừng lặp khi . ex theo công thức: dừng lặp khi . , dừng lặp khi . theo công thức: , dừng khi . In ra mã của phím bất kỳ được nhấn. Chương trình lặp cho đến khi nhấn ESC để thoát. Bằng phương pháp chia đôi, hãy tìm nghiệm xấp xỉ (độ chính xác 10-6) của các phương trình sau: ex - 1.5 = 0, trên đoạn [0, 1]. x2x - 1 = 0, trên đoạn [0, 1]. a0xn + a1xn-1 + ... + an = 0, trên đoạn [a, b]. Các số thực ai, a, b được nhập từ bàn phím sao cho f(a) và f(b) trái dấu. Mảng Nhập vào dãy n số thực. Tính tổng dãy, trung bình dãy, tổng các số âm, dương và tổng các số ở vị trí chẵn, vị trí lẻ trong dãy. Tìm phần tử gần số trung bình nhất của dãy. Tìm và chỉ ra vị trí xuất hiện đầu tiên của phần tử x trong dãy. Nhập vào dãy n số. Hãy in ra số lớn nhất, bé nhất của dãy. Nhập vào dãy số. In ra dãy đã được sắp xếp tăng dần, giảm dần. Cho dãy đã được sắp tăng dần. Chèn thêm vào dãy phần tử x sao cho dãy vẫn sắp xếp tăng dần. Hãy nhập vào 16 số nguyên. In ra thành 4 dòng, 4 cột. Nhập ma trận A và in ra ma trận đối xứng của nó. Cho một ma trận nguyên kích thước m*n. Tính: Tổng tất cả các phần tử của ma trận. Tổng tất cả các phần tử dương của ma trận. Tổng tất cả các phần tử âm của ma trận. Tổng tất cả các phần tử chẵn của ma trận. Tổng tất cả các phần tử lẻ của ma trận. Cho một ma trận thực kích thước m*n. Tìm: Số nhỏ nhất, lớn nhất (kèm chỉ số) của ma trận. Số nhỏ nhất, lớn nhất (kèm chỉ số) của từng hàng của ma trận. Số nhỏ nhất, lớn nhất (kèm chỉ số) của từng cột của ma trận. Số nhỏ nhất, lớn nhất (kèm chỉ số) của đường chéo chính của ma trận. Số nhỏ nhất, lớn nhất (kèm chỉ số) của đường chéo phụ của ma trận. Nhập 2 ma trận vuông cấp n A và B. Tính A + B, A - B, A * B và A2 - B2. Xâu kí tự Hãy nhập một xâu kí tự. In ra màn hình đảo ngược của xâu đó. Nhập xâu. Thống kê số các chữ số '0', số chữ số '1', …, số chữ số '9' trong xâu. In ra vị trí kí tự trắng đầu tiên từ bên trái (phải) một xâu kí tự. Nhập xâu. In ra tất các các vị trí của chữ 'a' trong xâu và tổng số lần xuât hiện của nó. Nhập xâu. Tính số từ có trong xâu. In mỗi dòng một từ. Nhập xâu họ tên, in ra họ, tên dưới dạng viết hoa. Thay kí tự x trong xâu s bởi kí tự y (s, x, y được đọc vào từ bàn phím) Xoá mọi kí tự x có trong xâu s (s, x được đọc vào từ bàn phím). (Gợi ý: nên xoá ngược từ cuối xâu về đầu xâu). Nhập xâu. Không phân biệt viết hoa hay viết thường, hãy in ra các kí tự có mặt trong xâu và số lần xuất hiện của nó (ví dụ xâu “Trach - Van - Doanh” có chữ a xuất hiện 3 lần, c(1), d(1), h(2), n(2), o(1), r(1), t(1), -(2), space(4)).
File đính kèm:
- Bài giảng Ngôn ngữ lập trình CC++ - Phạm Hồng Thái - Chương 3 Cấu trúc điều khiển và dữ liệu kiểu mảng.doc