TỪ PASCAL ĐẾN C
Mở đầu
Hầu hết chúng ta đều biết và sử dụng ngôn ngữ lập trình Pascal. Đó là ngôn ngữ được sử dụng nhiều nhất trong các kì thi tin học ở nước ta hiện nay. Tuy nhiên, C cũng là một ngôn ngữ được sử dụng rộng rãi để giải các bài toán tin học; đôi khi nó cung cấp một số thuận lợi nhất định so với Pascal.
Bài viết này sẽ giúp các bạn nắm được các khái niệm cơ bản của C, thông qua đối chiếu với ngôn ngữ Pascal, từ đó áp dụng vào việc giải các bài toán tin học. Sau khi đọc xong bài viết này, bạn cũng có thể chuyển đổi một chương trình giải toán bằng Pascal sang ngôn ngữ C.
Nếu bạn đã thông thạo ngôn ngữ Pascal, thì bài viết này sẽ giúp bạn hiểu C nhanh chóng hơn việc đọc toàn bộ một quyển giáo trình dạy C.
Giới thiệu sơ lược
Đều là những ngôn ngữ lập trình có cấu trúc nên mỗi khái niệm trong Pascal có một khái niệm tương ứng , hoặc tương tự, trong C; chỉ có cú pháp, câu lệnh là khác nhau. C tương đối khó hơn vì cú pháp của nó tự do hơn, dẫn đến những lỗi khó phát hiện trong khi viết chương trình.
Trong bài viết này, bạn cũng gặp một số khái niệm của ngôn ngữ C mà Pascal không có. Phần lớn những khái niệm này liên quan đến con trỏ (pointer).
Một số lưu ý cơ bản:
- C không cho phép các thủ tục lồng nhau, vì vậy bạn phải loại bỏ các thủ tục lồng nhau trong chương trình Pascal trước khi chuyển nó sang ngôn ngữ C
- Ngôn ngữ C phân biệt ký tự thường và ký tự hoa: AAA, aaa và Aaa là 3 tên gọi khác nhau. Để tiện lợi, người ta thường ký hiệu các hằng bằng ký tự hoa, các biến bằng ký tự thường. Các từ khóa của C luôn luôn được kí hiệu bằng các chữ cái thường.
Một chương trình đơn giản
Dưới đây là một chương trình C rất đơn giản tính giai thừa của 6. Bạn nên gõ lại chứ đừng copy đoạn mã; như thế sẽ giúp bạn thuộc cú pháp của C nhanh hơn.
#include <stdio.h>
#define VALUE 6
int i,j;
void main()
{
j=1;
for (i=1; i<=VALUE; i++)
j=j*i;
printf("Giai thừa của %d là %d\n",VALUE,j);
}
#define VALUE 6
int i,j;
void main()
{
j=1;
for (i=1; i<=VALUE; i++)
j=j*i;
printf("Giai thừa của %d là %d\n",VALUE,j);
}
Và đây là đoạn chương trình Pascal tương ứng:
program samp;
const value=6;
var i,j:integer;
begin
j:=1;
for i:=1 to value do
j:=j*i;
writeln('Giai thừa của ',value,' là ',j);
end.
const value=6;
var i,j:integer;
begin
j:=1;
for i:=1 to value do
j:=j*i;
writeln('Giai thừa của ',value,' là ',j);
end.
Bạn có thể thấy tương ứng 1-1 giữa những câu lệnh. Khác biệt duy nhất là đoạn chương trình C bắt đầu bằng #include <stdio.h>. Dòng này đưa thư viện I/O chuẩn vào chương trình để bạn có thể đọc/viết các giá trị, xử lý file văn bản, v.v… C có rất nhiều các thư viện chuẩn như stdio, string, time, math, v.v…
Dòng #define định nghĩa một hằng. Lệnh int i,j; khai báo 2 biến toàn cục kiểu số nguyên Các kiểu dữ liệu thông dụng khác là float (số thực), char (ký tự), cả hai đều có thể định nghĩa theo cùng cú pháp như trên.
Dòng main() khai báo thủ tục chính. Mọi chương trình C đều phải có một thủ tục có tên “main”. Trong C, { và } thay thế cho begin và end củaPascal, = thay thế cho :=. Vòng lặp for và lệnh printf hơi lạ một chút, nhưng chúng có cùng chung chức năng như các dòng lệnh tương ứng trong chương trình Pascal. Lưu ý C sử dụng dấu ngoặc kép thay vì dấu nháy đơn (‘ ‘) đối với chuỗi ký tự.
Khi bạn quen, lệnh printf của C sẽ dễ sử dụng hơn lệnh write trong Pascal. Phần trong dấu ngoặc kép được gọi là chuỗi định dạng (format string); nó mô tả dữ liệu được định dạng thế nào khi viết ra. Chuỗi định dạng chứa những chữ như Giai thừa của , \n (kí tự xuống dòng), và các toán tử xác định vị trí của các biến. Hai toán tử trong chuỗi định dạng trên (%d %d) cho biết các giá trị nguyên trong chuỗi tham số phía sau sẽ được in ra tại vị trí này. Có những toán tử khác dành cho số thực, kí tự, chuỗi, v.v… Bạn có thể dùng phần hướng dẫn của Turbo C chẳng hạn để xem danh sách các toán tử này. Một điều quan trọng là các tham số đi đằng sau phải có kiểu đúng như các toán tử trong chuỗi định dạng. Ví dụ bạn không thể viết %d nhưng tham số tương ứng đằng sau lại là một biến kiểu float.
Chương trình trên chạy tốt, nhưng có thể được cải tiến bằng cách đọc thẳng giá trị thay vì sử dụng hằng số. Bạn hãy sửa lại chương trình, loại bỏ hằng VALUE, thay vào đó khai báo value như một biến toàn cục. Sau đó thêm hai dòng sau vào đầu thủ tục main:
printf("Nhập giá trị:");
scanf("%d",&value);
scanf("%d",&value);
Đoạn mã tương ứng trong Pascal như sau:
write('Nhập giá trị:');
readln(value);
readln(value);
Lệnh scanf cùng sử dụng một kiểu chuỗi định dạng như printf (bạn hãy xem phần help để biết thêm chi tiết). Bạn cũng cần lưu ý dấu & trước biếnvalue. Đây là toán tử địa chỉ (address operator) của C: nó trả về địa chỉ của biến; nhưng chúng ta sẽ bàn điều này sau khi đề cập đến kiểu con trỏ. Bạn phải sử dụng dấu & trong lệnh scanf trước bất kỳ biến nào kiểu char, int, float, hoặc kiểu những kiểu record (chúng ta sẽ để cập kiểu record sau). Nếu bạn gõ thiếu dấu &, bạn sẽ gặp lỗi “segmentation fault” khi chạy chương trình.
Những lỗi cần tránh:
- Quên dấu & trong lệnh scanf
- Quên dấu */ ở cuối của dòng chú thích
Cấu trúc rẽ nhánh và vòng lặp
Các câu lệnh điều kiện if và vòng lặp while trong C cũng dựa trên ý tưởng về các biểu thức Boolean như trong Pascal. Tuy nhiên trong C không có kiểu Boolean một cách tường minh – bạn phải sử dụng kiểu số nguyên để thay thế. Trong C, số 0 được hiểu là false và các số nguyên còn lại được hiểu là true.
Dưới đây là một đoạn chương trình đơn giản được dịch từ Pascal sang C.
Đoạn mã Pascal:
if (x=y) and (j>k) then
z:=1
else
q:=10;
z:=1
else
q:=10;
Đoạn mã C trông rất giống, nhưng có một số điểm khác biệt quan trọng:
if ((x==y) && (j>k))
z=1;
else
q=10;
z=1;
else
q=10;
Lưu ý dấu = trong Pascal trở thành dấu = = trong C. Đây là một khác biệt rất quan trọng, bởi vì C vẫn chấp nhận dấu = thông thường ở vị trí này khi bạn biên dịch chương trình, nhưng nó sẽ thực thi rất khác khi chạy. Toán tử and trong Pascal trở thành && trong C. Bạn cũng cần lưu ý rằng trong C có một dấu chấm phẩy sau câu lệnh z=1, không có từ khóa then, và biểu thức Boolean phải được đặt hoàn toàn trong những dấu ngoặc.
Bảng sau cho thấy những cặp toán tử tương ứng trong Pascal và C:
Pascal | C |
= | == |
< | < |
> | > |
<= | <= |
>= | >= |
<> | != |
AND | && |
OR | || |
NOT | ! |
Có một vấn đề là bạn có thể quên mà đánh dấu = thay vì = = . Bởi vì số nguyên thay thế cho kiểu Boolean, nên câu lệnh sau hợp lệ trong C:
void main()
{
int a;
printf("Nhập một số:");
scanf("%d", &a);
if (a)
{
...
}
}
{
int a;
printf("Nhập một số:");
scanf("%d", &a);
if (a)
{
...
}
}
Nếu a là một số khác 0, đoạn code trong cặp dấu { } thứ hai sẽ được thực thi. Giả sử bạn có câu lệnh sau trong Pascal:
if a=b then
và bạn dịch sang C thành:
if (a=b) /* câu lệnh đúng là "if (a==b)" */
Trong C, câu lệnh này có nghĩa là: “Gán b cho a, rồi kiểm tra giá trị Boolean của a”. Nếu a bằng 0 thì câu lệnh if là false; còn ngược lại thì nó là true. Đây là một thực thi không mong đợi của chương trình; vì vậy tốt hơn hết bạn nên cẩn thận với dấu = và = =.
Câu lệnh while cũng dễ chuyển đổi. Chẳng hạn, đoạn mã Pascal sau:
while a < b do
begin
...
end;
begin
...
end;
Ta có đoạn chương trình C tương ứng
while (a < b)
{
...
}
{
...
}
C cũng cung cấp một cấu trúc “do-while” để thay thể cho cấu trúc “repeat-until” của Pascal:
do
{
...
}
while (a < b);
{
...
}
while (a < b);
Vòng lặp for trong C hơi khác một chút so với Pascal, bởi vì nó chỉ là một cách viết gọn của câu lệnh while. Ví dụ như chúng ta có đoạn mã C sau:
x=1;
while (x<10)
{
...
x++; /* x++ tương đương với x=x+1 */
}
while (x<10)
{
...
x++; /* x++ tương đương với x=x+1 */
}
Bạn có thể chuyển đoạn chương trình trên thành một vòng lặp for như sau:
for(x=1; x<10; x++)
{
...
}
{
...
}
Lưu ý rằng vòng lặp while gồm 3 bước, bước khởi tạo (x=1), bước kiểm tra (x<10), và bước gia/giảm (x++). Câu lệnh for cho phép bạn đưa cả ba bước vào một dòng lệnh; thế nhưng ngoài ra bạn có thể đặt bất kỳ thứ gì vào ba phần này. Chẳng hạn bạn có vòng lặp sau:
a=1;
b=6;
while (a < b)
{
a++;
printf("%d\n",a);
}
b=6;
while (a < b)
{
a++;
printf("%d\n",a);
}
Bạn có thể đưa tất cả vào một câu lệnh for:
for (a=1,b=6; a < b; a++,printf("%d\n",a));
Những lệnh như thế này thường gây rắc rối trong việc đọc và hiệu chỉnh chương trình; có lẽ bạn nên tránh sử dụng chúng.
Những lỗi cần tránh:
- Viết nhầm dấu = thay vì muốn viết = = trong câu lệnh if hoặc while
- Vô tình đặt dấu ; ở cuối câu lệnh for hoặc if, dẫn đến câu lệnh mất tác dụng. Ví dụ đoạn chương trình:
for (x=1; x<10; x++);
printf("%d\n",x);
printf("%d\n",x);
sẽ không in ra một giá trị nào bởi vì có dấu ; đằng sau lệnh for.
0 nhận xét