Đăng ký
Cộng đồng phát triển game Việt - kết nối đam mê !


Phân loại biến 


Có hai cách phân loại biến: theo phạm vi (scope) và theo Storage class specifier (tạm gọi là phương thức lưu trữ)


Theo phạm vi, ta có các loại:


  • Local variable
  • global variable
  • static variable

Theo storage class specifier:


  • auto
  • static
  • register
  • extern

Global và local



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdio.h"
int mGlobalVar;
  
void Foo()
{
   int localVar;
   printf("Foo : localVar = %d mGlobalVar = %d\n",
        localVar, mGlobalVar);
}
  
int main()
{
    int localVar = 1;
    printf("Main: localVar = %d mGlobalVar = %d\n",
        localVar, mGlobalVar);
    mGlobalVar = 1;
    Foo();
    return 1;
}



Trong ví dụ trên, mGlobalVar là biến global, localVar là biến local (có 2 biến localVar khác nhau).


  • Biến global có giá trị và được sử dụng trong toàn chương trình, ở tất cả các file c/cpp (cần dùng extern khi dùng ở file khác - xem extern). Biến global sẽ mang giá trị 0 (zero) ngay khi được khởi tạo
  • Biến local chỉ tồn tại trong phạm vi một block, hàm mà nó được khai báo. Biến local không được thiết lập giá trị mặc định (giá trị ngẫu nhiên)

Kết quả thực thi đạon code trên 



1
2
Main: localVar = 1 mGlobalVar = 0
Foo : localVar = 2673756 mGlobalVar = 1


Ta thấy:


  • Ở hàm main, mGlobalVar có giá trị mặc định là 0, localVar có giá trị 1 do được thiết lập giá trị ở dòng 13
  • Ở hàm Foo:

    • Giá trị mGlobalVar là 1, do được thiếp lập giá trị ở dòng 16
    • localVar: lưu ý localVar của Foo không có mối liên hệ nào với localVar của main. Trong Foo, localvar chỉ được khai báo, mà không có giá trị cụ thể, nên sẽ có giá trị ngẫu nhiên. 

Qui tắt: Khi khai báo biến bất kỳ (global, local), phải thiết lập giá trị cụ thể.

Auto variable


Mặc định, các biến local được khai báo không phải static, register, chính là auto variable.



1
2
3
4
5
6
// auto_keyword.cpp
int main()
{
   auto int i = 0;    // Explicitly declared as auto.
   int j = 0;    // Implicitly auto.
}


Lưu ý: không thể test ở phiên bản VS 2010, test được bởi GNU-GCC 


Static variable


Biến static được khởi tạo khi chương trình thực thi và được hủy khi chương trình kết thúc. Giống với biến global, giá trị mặc định của biến static là 0 (zero). Khác với biến toàn cục, biết static chỉ có thể truy xuất trong phạm vi khai báo của nó:


  • Nếu được khai báo trong block, biết static chỉ được truy xuất trong block
  • Nếu được khai báo toàn cục (không thuộc về hàm /  block nào), biến static chỉ có thể dùng bên trong file c/cpp chưa nó

Một trường hợp đặc biệt của static là static trong class, sẽ được trình bày ở phần OOP



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "stdio.h"
 
static int s_iGlobalStatic;
 
void Foo()
{
    static int s_iLocalStatic;
    printf("Foo: called %d\n",
        s_iLocalStatic++);
}
 
int main()
{
    int localVar = 1;
    printf("Main: %d\n",
        s_iGlobalStatic);
    Foo();
    Foo();
    Foo();
    return 1;
}



Trong ví dụ trên, biến s_iLocalStatic không thể truy xuất được trong hàm main, và s_iGlobalStatic không thể truy xuất được trong file c/cpp khác.

Register variable


Biến register sẽ được lưu trũ trên thanh ghi máy tính (nếu có thể). Xem thêm về register: http://en.wikipedia.org/wiki/Processor_register

 

Biến register thường được dùng cho các vòng lặp for để tăng tốc:



1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    int sum = 0;
    for (register int i = 0;
        i < 100;
        i++)
    {
        sum += i;
    }
    printf("Sum = %d\n", sum);
     
    return 1;
}



Extern variable


Ví dụ:



1
int g_iExternVar = 100;


  • Extern variable dùng để báo cho trình biên dịch biết một biến đã được khai báo và cấp bộ nhớ ở file c/cpp khác. Khi trình biên dịch gặp từ khóa này sẽ không cấp bộ nhớ mới.
  • Extern variable dùng để chia sẽ việc sử dụng các biến local ở các file c/cpp khác nhau

Lưu ý: trình biên dịch không cho phép tồn tại 2 biến global giống tên ở hai file c/cpp khác nhau. Nếu có sẽ báo lỗi lúc link. Ví dụ:



1
2
3
// external.cpp
 
int g_iExternVar = 100;





1
2
3
4
5
6
7
8
9
10
11
12
/// main.cpp
 
#include "stdio.h"
int g_iExternVar;
 
int main()
{
    printf("Value = %d\n",
        m_iExternVar);
 
    return 1;
}



Ta thấy, m_iExternVar được khai báo ở cả hai file. Kết quả lúc build:


  • Visual stduio



1
fatal error LNK1169: one or more multiply defined symbols found



  • GCC



1
2
3
4
5
6
E:\CPP>g++-4 helloWorld.cpp external.cpp -o helloWorld
/cygdrive/c/Users/Ricky/AppData/Local/Temp/ccK0s38j.o:external.cppUnhappy.data+0x0):
multiple definition of `_g_iExternVar'
/cygdrive/c/Users/Ricky/AppData/Local/Temp/ccWLHj9w.o:helloWorld.cppUnhappy.bss+0x0):
 first defined here
collect2: ld returned 1 exit status



Nếu 2 biến g_iExternVar chỉ là một, ta khai báo extern ở một trong 2 file, ví dụ ở file main.cpp



1
2
3
4
5
6
7
8
9
10
#include "stdio.h"
extern int m_iExternVar;
 
int main()
{
    printf("Value = %d\n",
        m_iExternVar);
 
    return 1;
}


Hằng


Hằng có thể hiểu là một biến không thể thay đổi giá trị 



1
2
const int k_Hello = 0;
int const k_Hello2 = 0;


 

Chủ đề: C/C++ for beginner, c++
tam nguyen
"Extern variable dùng để chia sẽ việc sử dụng các biến local ở các file c/cpp khác nhau" -> chỗ này phải là global chứ , đang ôn lại C++, bài này bổ ích quá anh ạ
  • tháng 8 19, 2012
  • ·
  • Thích
  • ·
Dai Van Nguyen
  • tháng 4 15, 2014
  • ·
  • Thích
  • ·
Captcha Challenge