Hướng dẫn lập trình C cho người mới bắt đầu
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- Giới thiệu

Tài liệu được viết dựa trên:
  • Eclipse 4.5 (MARS)

History:
  • 03-03-2015: Eclipse 4.4 (LUNA)
  • 23-01-2016: Update to Eclilpse 4.5 (MARS).

2- Bắt đầu với C/C++ cần những gì

Các tài liệu hướng dẫn C/C++ trên website o7planning chúng tôi sử dụng Eclipse IDE. Bạn cần cài đặt và cấu hình Eclipse và môi trường C/C++ trước khi bắt đầu. Bạn có thể xem chỉ dẫn tại:

3- Phân biệt C và C++

Bạn cần có cái nhìn tổng quát để phân biệt C và C++.

C là ngôn ngữ ra đời trước, và là ngôn ngữ hướng thủ tục, nó dễ dàng được triển khai và chạy trên các hệ điều hành. C++ ra đời sau mở rộng từ C nó mang vào khái niệm lập trình hướng đối tượng, C là nền tảng của C++, và C++ không ra đời để thay thế C, các thư viện của nó được mở rộng lên rất nhiều.

Lập trình hướng thủ tục ở đây có nghĩa là: Các file nguồn (Chứa code của bạn) sẽ chứa các hàm. Trong khi đó hướng đối tượng file nguồn chứa một class (lớp) và trong class có chứa các phương thức. Để gọi một phương thức trong một class bạn cần tạo ra một đối tượng của class và sau đó gọi hàm thông qua đối tượng này, trong khi đó với hướng thủ tục bạn có thể gọi trực tiếp.

Trong tài liệu hướng dẫn này tôi sẽ hương dẫn bạn làm việc trên C. Còn C++ sẽ được đề cập tới trong một tài liệu khác.

4- Tạo Project bắt đầu với C

Nếu bạn làm việc với: Windows 64bit + Eclipse 64bit + Java64bit, bạn cần phải mở Eclipse với quyền Administrator, có một rắc rối là Eclipse không in các message ra màn hình Console trong trường hợp chạy ở chế độ thông thường.
  • File/New/Other..
Trong tài liệu này tôi sẽ hướng dẫn bạn lập trình C ( C++ sẽ hướng dẫn trong tài liệu khác). Tuy nhiên project mà chúng ta tạo ra tại đây là C++, nhưng chúng ta chỉ sử dụng những thư viện của C.
Nhập vào tên Project:
  • CBasicTutorial
Project đã được tạo ra, thực tế code của ví dụ HelloWorld này có code C++. Tuy nhiên chưa cần phải quan tâm tới nó.
Biên dịch project
Project đã được biên dịch thành công.
Tiếp theo bạn cần phải cấu hình để có thể chạy được project trực tiếp trên Eclipse, việc này rất quan trọng.
Chạy thử ví dụ HelloWorld
Hoặc:
Kết quả chạy ví dụ:
OK! Mọi thứ hoạt động tốt.

5- Đặc điểm của C và chú ý trong thực hành

Khi một chương trình C được chạy nó sẽ tìm hàm main() để thực thi, ví dụ như thực thi hàm main() của ví dụ HelloWorld nói trên.

Một chương trình C có thể có nhiều file nguồn, mỗi file nguồn có thể nhiều hàm. Tuy nhiên chỉ cho phép duy nhất một hàm main() trên toàn bộ Project của bạn.
Trên kia bạn vừa tạo ra một file CBasicTutorial.cpp nó có một hàm main(), giờ bạn tạo ra một file khác để thực hành chẳng hạn PrimitiveExample.cpp và có hàm main() bạn cần đổi tên hàm main() của CBasicTutorial.cpp thành một tên khác để nó không xung đột và bạn có thể biên dịch được, sau đó có thể thực hành những gì viết trong PrimitiveExample.cpp.

Theo tôi trong quá trình thực hành bạn nên chọn cách đổi tên như sau:
  • CBasicTutorial.cpp
    • main()  ==> mainCBasicTutorial()

 

6- Cấu trúc của một chương trình C

Tôi sẽ tạo ra một file cpp mới để minh họa và giải thích về cấu trúc của một chương trình C.
Trên Eclipse chọn:
  • File/New/Other...
Nhập vào:
  • Source file: MyFirstExample.cpp
  • Template: Default C source temple
File nguồn đã được tạo ra, nó chẳng có gì cả.
Chúng ta sẽ viết code cho file nguồn này:

Chú ý: Hãy đổi tên hàm main của file nguồn CBasicTutorial.cpp thành mainCBasicTutorial vì một Project C chỉ cho phép một hàm main trên toàn bộ Project.

MyFirstExample.cpp
// Khai báo sử dụng thư viện stdio.h.
#include<stdio.h>


int main() {

  // printf là một hàm của thư viện stdio.h
  // Đây là một hàm in ra màn hình Console một dòng chữ.
  // \n là ký tự xuống dòng
  printf("Hello!, This is your first C example.\n");


  // In ra dòng thông báo ứng dụng sẽ kết thúc.
  printf("Exit!");

  // Hàm trả về 0.
  return 0;
}
Chạy ví dụ:
Kết quả chạy ví dụ:

Có một vài chú ý: Có một số hàm trong thư viện conio.h của C đã không được hỗ trợ trong C++. Chẳng hạn như getch() - Vốn là một hàm tạm dừng chương trình chờ cho tới khi người dùng gõ một ký tự bất kỳ mới tiếp tục chạy tiếp. Vì vậy trong hướng dẫn này tôi cố gắng không sử dụng các hàm như vậy trong các ví dụ.

#include<conio.h>

int main()  {
 
    // Làm gì đó tại đây ....

    // Dừng chương trình tại đây, chờ cho tới khi người dùng gõ một ký tự
    // bất kỳ mới tiếp tục chạy.
    // (Hàm này không được hỗ trợ đầy đủ)
    getch();


   // Làm gì đó tiếp tại đây.
 
}

7- Kiểu dữ liệu trong C

7.1- Kiểu số nguyên

Type Storage size Value range Format
char 1 byte -128 to 127 or 0 to 255 %c
unsigned char 1 byte 0 to 255 %c
signed char 1 byte -128 to 127 %s
int 2 or 4 bytes -32,768 to 32,767 or -2,147,483,648 to 2,147,483,647 %d
unsigned int 2 or 4 bytes 0 to 65,535 or 0 to 4,294,967,295 %u
short 2 bytes -32,768 to 32,767  
unsigned short 2 bytes 0 to 65,535  
long 4 bytes -2,147,483,648 to 2,147,483,647 %ld
unsigned long 4 bytes 0 to 4,294,967,295  

7.2- Kiểu số chấm động (Floating point type)

Kiểu dữ liệu Kích thước lưu trữ Tập giá trị Phần thập phân
float 4 byte 1.2E-38 to 3.4E+38 6 vị  trí sau thật phân
double 8 byte 2.3E-308 to 1.7E+308 15 vị  trí sau thật phân
long double 10 byte 3.4E-4932 to 1.1E+4932 19 vị  trí sau thật phân

7.3- Ví dụ

PrimitiveExample.cpp
// Khai báo sử dụng thư viện vào ra chuẩn stdio.h
// (Standard IO)
#include <stdio.h>
// Khai báo sử dụng thư viện float.h
#include <float.h>


int main() {

   // Hàm sizeof(type) trả về số byte lưu trữ kiểu dữ liệu
   printf("Storage size for float : %d \n", sizeof(float));

   // FLT_MIN là hằng số giá trị nhỏ nhất của kiểu float
   // Hằng số này được định nghĩa trong thư viện float.h
   printf("Minimum float positive value: %E\n", FLT_MIN);

   // FLT_MAX là hằng số giá trị lớn nhất của kiểu dữ liệu float.
   // Hằng số này được định nghĩa trong thư viện float.h
   printf("Maximum float positive value: %E\n", FLT_MAX);

   // FLT_DIG là hằng số, số số tối đa của phần thập pha
   // Hằng số này được định nghĩa trong thư viện float.h
   printf("Precision value: %d\n", FLT_DIG);

   return 0;
}
Kết quả chạy ví dụ:

8- Câu lệnh rẽ nhánh trong C (if - else if - else)

if là một câu lệnh kiểm tra một điều kiện gì đó trong C. Chẳng hạn: Nếu a > b thì làm gì đó ....
Các toán tử so sánh thông dụng:
Toán tử Ý nghĩa Ví dụ
> Lớn hơn 5 > 4 là đúng (true)
< Nhỏ hơn 4 < 5 là đúng (true)
>= Lớn hơn hoặc bằng 4 >= 4 là đúng (true)
<= Nhỏ hơn hoặc bằng 3 <= 4 là đúng (true)
== Bằng nhau 1 == 1 là đúng (true)
!= Không bằng nhau  1 != 2 là đúng (true)
&&  a > 4 && a < 10
|| Hoặc  a == 1 || a == 4
// Cú pháp

if ( điều kiện)   {
   // Làm gì đó tại đây.
}
Ví dụ:
// Ví dụ 1:
if ( 5 < 10 )  {
  printf( "Five is now less than ten");
}

// Ví dụ 2:
if ( true ) {
  printf( "Do something here");
}
 
Cấu trúc đầy đủ của If-Else if-Else:
// Chú ý rằng sẽ chỉ có nhiều nhất một khối được chạy
// Chương trình kiểm tra điều kiện từ trên xuống dưới khi bắt gặp một điều
// kiện đúng khối lệnh tại đó sẽ được chạy, và chương trình không kiểm tra tiếp các điều kiện
// còn lại trong cấu trúc rẽ nhánh.


// Nếu điều kiện 1 đúng thì  ...
if (điều kiện 1)   {
    // ... làm gì đó khi điều kiện một đúng.
}
// Ngược lại nếu điều kiện 2 đúng thì ....
else if(điều kiện 2 )   {
   // ... làm gì đó khi điều kiện 2 đúng (điều kiện 1 sai).
}
// Ngược lại nếu điều kiện N đúng thì ...
else if(điều kiện N)   {
    // .. làm gì đó khi điều kiện N đúng (các điều kiện ở trên sai)
}
// Ngược lại nếu các điều kiện ở trên đều sai thì
else   {
    // ... làm gì đó tại đây khi mọi điều kiện trên đều sai.
}
Ví dụ:
IfElseExample.cpp
// Khai báo sử dụng thư viện vào ra chuẩn stdio.h
// (Standard IO)
#include <stdio.h>

int main() {

   // Khai báo một số mô tả tuổi của bạn.
   int age;

   printf("Please enter your age: \n");

   // Đôi khi sử dụng printf không in ra ngay lập tức thông báo của bạn.
   // Sử dụng fflush(stdout) đẩy dữ liệu xuống.
   // Chú ý: stdout là một biến của luồng ghi ra màn hình Console
   // (Định nghĩa trong thư viện stdio.h)
   fflush(stdout);

   // Hàm scanf sẽ đợi bạn gõ vào một đoạn text từ bàn phím
   // (Và nhấn enter để hoàn thành).
   // Nó sẽ quét lấy một dẫy số (Chỉ định bởi tham số %d)
   // Chuyển thành số tự nhiên và gán vào biến age.
   scanf("%d", &age);

   // Kiểm tra nếu age nhỏ hơn 80 thì ...
   if (age < 80) {
       printf("You are pretty young");
   }

   // Ngược lại nếu tuổi nằm trong khoảng 80, 100 thì
   else if (age >= 80 && age <= 100) {
       printf("You are old");
   }

   // Ngược lại (Các trường hợp còn lại)
   else {
       printf("You are verry old");
   }

   return 0;
}
Chạy ví dụ:
Chương trình in ra dòng chữ "mời bạn nhập một số", nhập vào 70 và nhấn Enter.
Kết quả:
Bạn có thể chạy lại ví dụ và nhập vào các con số khác và xem kết quả.

9- Câu lệnh rẽ nhánh Switch

Cú pháp câu lệnh rẽ nhánh switch:
// Sử dụng switch để kiểm tra một giá trị của một biến
switch ( <variable> ) {
case value1:
// Làm gì đó nếu giá trị của biến == value1
break;
case value2:
// Làm gì đó nếu giá trị của biến == value2
break;
...
default:
// Làm điều gì đó tại đây nếu giá trị của biến không thuộc các giá trị
// liệt kê ở trên.
break;
}
SwitchExample.cpp
#include <stdio.h>

int main() {

   // Đề nghị người dùng chọn 1 lựa chọn.
   printf("Please select one option:\n");

   printf("1 - Play a game \n");
   printf("2 - Play music \n");
   printf("3 - Shutdown computer \n");

   fflush(stdout);

   // Khai báo một biến option
   int option;

   // Hàm scanf sẽ đợi bạn gõ vào một đoạn text từ bàn phím
   // (Và nhấn enter để hoàn thành).
   // Nó sẽ quét lấy một dẫy số (Chỉ định bởi tham số %d)
   // Chuyển thành số tự nhiên và gán vào biến option.
   scanf("%d", &option);

   // Kiểm tra giá trị của option
   switch (option) {

   case 1:
       printf("You choose to play the game \n");
       break;
   case 2:
       printf("You choose to play the music \n");
       break;
   case 3:
       printf("You choose to shutdown the computer \n");
       break;
   default:
       printf("Nothing to do...\n");
       break;
   }

   fflush(stdout);

   return 0;

}
Kết quả chạy ví dụ (Trong trường hợp nhập vào số 2 và nhấn Enter).

Chú ý:

Có một vấn đề bạn đặt ra câu lệnh break trong trường hợp này có ý nghĩa gì?.

break trong trường hợp này nói với chương trình rằng thoát ra khỏi switch. Trong trường hợp bạn không sử dụng break câu chương trình sẽ tiếp tục thực hiện các khối lệnh trong 'case' ở phía dưới (hoặc cả default) cho tới khi nó bắt gặp break, kể cả giá trị của biến trong trường hợp đó khác với giá trị trong 'case'.

Hãy xem một ví dụ minh họa:
SwitchExample2.cpp
#include <stdio.h>

int main() {

   // Khai báo biến option và gán giá trị 3.
   int option = 3;

   printf("Option = %d \n", option);

   // Kiểm tra giá trị của option
   switch (option) {

   case 1:
       printf("Case 1 \n");
       break;
   case 2:
       printf("Case 2 \n");
       // Không có break tại đây.
   case 3:
       printf("Case 3 \n");
       // Không có break tại đây.
   case 4:
       printf("Case 4 \n");
       // Không có break tại đây.
   case 5:
       printf("Case 5!!! \n");
       break;
   default:
       printf("Nothing to do...\n");
       break;
   }

   fflush(stdout);

   return 0;

}
Kết quả chạy ví dụ:

10- Vòng lặp trong C

Vòng lặp được sử dụng để chạy lặp lại một khối lệnh. Nó làm chương trình của bạn thực thi lặp đi lặp lại một khối lệnh nhiều lần, đây là một trong các nhiệm vụ cơ bản trong lập trình.
C hỗ trợ 3 loại vòng lặp khác nhau:
  • FOR
  • WHILE
  • DO WHILE

10.1- Vòng lặp FOR

Cấu trúc của vòng lặp FOR:
for ( khởi tạo biến; điều kiện; cập nhập giá trị mới cho biến ) {
   // Thực thi khối lệnh khi điều kiện còn đúng
}
Ví dụ:
// Ví dụ 1:
// Tạo một biến x và gán giá trị ban đầu của nó là 0
// Điều kiện kiểm tra là x < 5
// Nếu x < 5 đúng thì khối lệnh được chạy
// Mỗi lần chạy xong khối lệnh giá trị x lại được cập nhập mới tại đây là tăng x lên 1.
for (int  x = 0;  x < 5 ; x = x + 1)  {
    // Làm gì đó tại đây khi x < 5 đúng.
}


// Ví dụ 2:
// Tạo một biến x và gán giá trị ban đầu của nó là 2
// Điều kiện kiểm tra là x < 15
// Nếu x < 15 đúng thì khối lệnh được chạy
// Mỗi lần chạy xong khối lệnh giá trị x lại được cập nhập mới tại đây là tăng x lên 3.
for (int  x = 2;  x < 15 ; x = x + 3)  {
    // Làm gì đó tại đây khi x < 15 đúng.
}
 
ForLoopExample.cpp
// Khai báo sử dụng thư viện vào ra chuẩn stdio.h
// (Standard IO)
#include <stdio.h>

int main() {

   printf("For loop example\n");

   // Đôi khi sử dụng printf không in ra ngay lập tức thông báo của bạn.
   // Sử dụng fflush(stdout) đẩy dữ liệu xuống.
   // Chú ý: stdout là một biến của luồng ghi ra màn hình Console
   // (Định nghĩa trong thư viện stdio.h)
   fflush(stdout);

   // Tạo một biến x và gán giá trị ban đầu của nó là 2
   // Điều kiện kiểm tra là x < 15
   // Nếu x < 15 đúng thì khối lệnh được chạy
   // Mỗi lần chạy xong khối lệnh giá trị x lại được cập nhập mới tại đây là tăng x lên 3.
   for (int x = 2; x < 15; x = x + 3) {
       printf("\n");
       printf("Value of x = %d \n", x);
       fflush(stdout);
   }
   return 0;
}
Kết quả chạy ví dụ:

10.2- Vòng lặp WHILE

Cú pháp WHILE:
while (điều kiên)   {
   // Trong khi điều kiện đúng thì thực thi khối lệnh.
}
Ví dụ:
// Ví dụ 1:
// Khai báo một biến x
int x = 2;

while ( x < 10)  {
   // Làm gì đó tại đây khi x < 10 còn đúng.
   // ....
   // Cập nhập giá trị mới cho biến x.
   x = x + 3;
}
WhileLoopExample.cpp
#include <stdio.h>

int main() {

   printf("While loop example\n");

   // Đôi khi sử dụng printf không in ra ngay lập tức thông báo của bạn.
   // Sử dụng fflush(stdout) đẩy dữ liệu xuống.
   // Chú ý: stdout là một biến của luồng ghi ra màn hình Console
   // (Định nghĩa trong thư viện stdio.h)
   fflush(stdout);

   // Tạo một biến x và gán giá trị ban đầu của nó là 2
   int x = 2;

   // Điều kiện kiểm tra là x < 10
   // Nếu x < 10 đúng thì khối lệnh được chạy.
   while (x < 10) {
       printf("Value of x = %d \n", x);

       x = x + 3;
       fflush(stdout);
   }
   return 0;
}
Kết quả chạy ví dụ:

10.3- Vòng lặp DO WHILE

Cú pháp của vòng lặp DO-WHILE
// Đặc điểm của vòng lặp DO-WHILE là nó sẽ thực khi khối lệnh ít nhất 1 lần.
// Mỗi lần chạy xong khối lệnh nó lại kiểm tra điều kiện xem có thực thi tiếp không.
do {
    // Làm gì đó tại đây
    // Sau đó mới kiểm tra tiếp điều kiện xem có tiếp tục chạy khối lệnh này nữa hay không.
} while ( điều kiện);  // Chú ý: cần có dấu chấm phẩy tại đây.
DoWhileLoopExample.cpp
#include <stdio.h>

int main() {

  printf("Do-While loop example\n");

  fflush(stdout);

  // Tạo một biến x và gán giá trị ban đầu của nó là 2
  int x = 2;

  // Thực hiện khối lệnh.
  // Sau đó kiểm tra điều kiện xem có thực hiện khối lệnh nữa không.
  do {
      printf("Value of x = %d \n", x);

      x = x + 3;
      fflush(stdout);
  } while (x < 10) ; // Chú ý: Cần có dấu chấm phẩy tại đây.

  return 0;
}
Kết quả chạy ví dụ:

10.4- Lệnh break trong vòng lặp

break là một lệnh nó có thể nằm trong một khối lệnh của một vòng lặp. Đây là lệnh kết thúc vòng lặp vô điều kiện.
BreakExample.cpp
#include <stdio.h>

int main() {

  printf("Break example\n");

  fflush(stdout);

  // Tạo một biến x và gán giá trị ban đầu của nó là 2
  int x = 2;

  while (x < 15) {

      printf("----------------------\n");
      printf("x = %d \n", x);

      // Kiểm tra nếu x = 5 thì thoát ra khỏi vòng lặp.
      if (x == 5) {
          break;
      }
      // Tăng  x lên 1 (Viết ngắn gọn cho x = x + 1;).
      x++;
      printf("x after ++ = %d \n", x);

  }
  return 0;

}
Kết quả chạy ví dụ:

10.5- Lệnh continue trong vòng lặp

continue là một lệnh, nó có thể nằm trong một vòng lặp, khi bắt gặp lệnh continue chương trình sẽ bỏ qua các dòng lệnh trong cùng vòng lặp và ở phía dưới của continue và bắt đầu một vòng lặp mới.
ContinueExample.cpp
#include <stdio.h>

int main() {

 printf("Continue example\n");

 fflush(stdout);

 // Tạo một biến x và gán giá trị ban đầu của nó là 2
 int x = 2;

 while (x < 7) {

     printf("----------------------\n");
     printf("x = %d \n", x);

     // % là phép chia lấy số dư
     // Nếu x chẵn, thì bỏ qua các dòng lệnh phía dưới
     // của continue, tiếp tục vòng lặp mới (nếu có).
     if (x % 2 == 0) {
         // Tăng  x lên 1 (Viết ngắn gọn cho x = x + 1;).
         x++;
         continue;
     } else {
         // Tăng  x lên 1 (Viết ngắn gọn cho x = x + 1;).
         x++;
     }
     printf("x after ++ = %d \n", x);

 }
 return 0;

}
Kết quả chạy ví dụ:

11- Mảng trong C

11.1- Mảng một chiều

Đây là hình minh họa về mảng một chiều có 5 phần tử, các phần tử được đánh chỉ số từ 0 tới 4.
Cú pháp khai báo mảng một chiều:
// Cách 1:
// Khai báo một mảng các số int, chỉ rõ các phần tử.
int years[] = { 2001, 2003, 2005, 1980, 2003 };

// Khai báo một mảng có 5 phần từ, chỉ định giá trị cho 3 phần tử đầu tiên.
int age[5] = {20, 10, 50};

// Cách 3:
// Khai báo một mảng các số float, chỉ rõ số phần tử.
// (3 phần tử).
float salaries[3];
ArrayExample1.cpp
#include <stdio.h>

int main() {

  // Cách 1:
  // Khai báo một mảng, gán luôn các giá trị.
  int years[] = { 2001, 2003, 2005, 1980, 2003 };

  // Ghi ra số byte lưu trữ kiểu int
  printf("Sizeof(int) = %d \n", sizeof(int));

  // Số byte để lưu trữ mảng.
  printf("Sizeof(years) = %d \n", sizeof(years));

  int arrayLength = sizeof(years) / sizeof(int);

  printf("Element count of array years = %d \n\n", arrayLength);

  // Sử dụng vòng lặp for để in ra các phần tử của mảng.
  for (int i = 0; i < arrayLength; i++) {
      printf("Element at %d = %d \n", i, years[i]);
  }

  fflush(stdout);

  // Cách 2:
  // Khai báo một mảng chỉ khai báo số phần tử.
  // Khai báo một mảng có 3 phần tử.
  float salaries[3];

  // Gán các giá trị cho các phần tử.
  salaries[0] = 1000;
  salaries[1] = 1200;
  salaries[2] = 1100;

  return 0;

}
Kết quả chạy ví dụ:

11.2- Mảng hai chiều

Đây là hình minh họa một mảng 2 chiều
Cú pháp khai báo một mảng 2 chiều:
// Khai báo mảng 2 chiều chỉ định các phần tử.
// 3 hàng & 5 cột
int a[3][5] =     {
    {1 , 2 , 3,  4,   5} ,
    {0,  3,  4,  5,   7},
    {0,  3,  4,  0,   0}
};

// Khai báo một mảng, chưa gán các giá trị gì.
int a[3][5];
ArrayExample2.cpp
#include <stdio.h>

int main() {

  // Khai báo một mảng 2 chiều (3 hàng, 5 cột)
  int a[3][5] = { { 1, 2, 3, 4, 5 }, { 0, 3, 4, 5, 7 }, { 0, 3, 4, 0, 0 } };

  // Sử dụng vòng lặp for để in ra các phần tử của mảng.
  for (int row = 0; row < 3; row++) {
      for (int col = 0; col < 5; col++) {
          printf("Element at [%d,%d] = %d \n", row, col, a[row][col]);
      }
  }

  fflush(stdout);

  return 0;
}
Kết quả chạy ví dụ:

12- Con trỏ (Pointer)

Một con trỏ (Pointer) là một biến có giá trị là địa chỉ của một biến khác, ví dụ, địa chỉ trực tiếp của vị trí bộ nhớ. Giống như bất kỳ biến hoặc hằng số, bạn phải khai báo một con trỏ trước khi bạn có thể sử dụng nó để lưu trữ bất kỳ địa chỉ biến nào. Cú pháp khai báo biến con trỏ là:
type *variable-name;
Ví dụ:
// Khai báo một biến int
int var = 120;

// Khai báo một con trỏ (trỏ tới các kiểu int).
int *ip;

// Gán giá trị cho ip (Trỏ tới vị trí một biến)
ip = &var;

// Sử dụng * để truy cập vào giá trị của biến mà con trỏ trỏ tới.
int var2 = *ip;
PointerExample.cpp
#include <stdio.h>

int main() {
  // Khai báo một biến
  int var = 120;

  // Khai báo một con trỏ.
  int *ip;

  // Gán địa chỉ của biến 'var' cho con trỏ.
  ip = &var;

  // Ghi ra địa chỉ của biến 'var'.
  printf("Address of var variable: %x \n", &var);

  // Ghi ra địa chỉ được lưu trữ trong biến 'ip'.
  printf("Address stored in ip variable: %x \n", ip);

  // Truy cập vào giá của biến mà con trỏ đang trỏ tới.
  printf("Value of *ip variable: %d\n", *ip);

  fflush(stdout);

  int var2= *ip;

  return 0;
}

12.1- NULL Pointer

NULL là một hằng số được định nghĩa trước trong một vài thư viện của C. Khi bạn khai báo một con trỏ mà không gán giá trị cụ thể cho con trỏ, nó sẽ trỏ vào một vùng bộ nhớ ngẫu nhiên. Trong một số tình huống bạn có thể khai báo con trỏ và gán trực tiếp giá trị NULL cho nó. Hãy xem một ví dụ:
NULLPointerExample.cpp
#include <stdio.h>

int main() {

  // Khai báo một con trỏ
  // Không gán giá trị nào cho con trỏ này.
  // (Nó trỏ đi ngẫu nhiên vào vùng bộ nhớ nào đó).
  int *pointer1;

  // Ghi ra địa chỉ vị trí của pointer1
  printf("Address of pointer1 is %x \n", pointer1);

  // Kiểm tra xem pointer1 có NULL không
  if (pointer1) {
      // In ra giá trị vùng bộ nhớ mà pointer1 đang trỏ tới.
      printf("Value of *pointer1 is %d \n", *pointer1);
  }

  // Khai báo một biến con trỏ
  // Trỏ tới vị trí NULL (Không trỏ tới đâu).
  int *pointer2 = NULL;

  // Ghi ra địa chỉ vị trí của pointer2
  printf("Address of pointer2 is %x \n", pointer2);

  // Nếu pointer2 là NULL ghi ra thông báo.
  if (!pointer2) {
      printf("pointer2 is NULL");
  } else {
      // CHÚ Ý:
      // Nếu pointer2 NULL truy cập vào giá trị của *pointer2
      // sẽ bị lỗi ngừng chương trình.
      printf("Value of *pointer2 is %d \n", *pointer2);
  }

  fflush(stdout);

  return 0;
}
Kết quả chạy ví dụ:

13- Hàm (Function)

  • TODO