Pages

Con trỏ - Pointer

0

cplusplus imageCon trỏ là biến chứa địa chỉ của 1 biến khác. Con trỏ được sử dụng nhiều trong C, 1 phần do chúng đôi khi là cách duy nhất để biểu diễn tính toán và phần nữa là do chúng thường làm cho chương trình ngắn gọn và hiệu quả hơn các cách khác

Khai báo con trỏ : KDL *TênConTrỏ;

Các phép toán thường dùng với con trỏ :

  • Con trỏ kiểu nào thì lưu địa chỉ của biến kiểu đó (trừ con trỏ void)
  • Phép toán gán 2 con trỏ cùng kiểu dữ liệu
  • Phép toán gán 2 con trỏ khác kiểu dữ liệu : Phải ép kiểu
  • int *pi;
    float *pf;
    ...
    pf = pi;   // ERROR!
    pf = (float *)pi;  // OK
    
  • Phép cộng con trỏ với 1 số nguyên : thường dùng để truy xuất các phần tử trên mảng
  • int a[100], *p;
    p = a;
    ...
    printf("%d",*p); //In a[0]
    printf("%d",*(p+2)); //In a[2]
    
  • Phép toán & : lấy địa chỉ
  • Phép toán * : toán tử tham chiếu (có thể được dịch nôm na là "giá trị được trỏ bởi")

Ví dụ : Hàm hoán vị sử dụng con trỏ

void HoanVi(int *pa, int *pb)
{
  int t;
  t = *pa;
  *pa = *pb;
  *pb = t;
}
void main()
{
  int a = 5, b = 3;
  printf("a = %d, b = %d",a,b);
  HoanVi(&a,&b);
  printf("\na = %d, b = %d",a,b);
}

Nếu hàm Hoán vị ở trên được sửa lại như dưới đây thì liệu nó có tác dụng là hoán vị giá trị 2 biến a, b hay không?

void HoanVi(int *pa, int *pb)
{
  int *t;
  t = pa;
  pa = pb;
  pb = t;
}

Nếu bạn chạy thử thì sẽ có câu trả lời là không. Nguyên nhân là do hàm này chỉ hoán vị giá trị mà 2 con trỏ pa, pb đang lưu (giá trị này là địa chỉ) nhưng lại không thay đổi gì giá trị của 2 biến a, b mà 2 con trỏ này đang trỏ tới. Do đó khi kết thúc hàm hoán vị, 2 biến pa, pb được giải phóng và 2 biến a, b vẫn giữ nguyên giá trị cũ.

Con trỏ void

  • Con trỏ void có thể nhận địa chỉ của bất kỳ vùng nhớ nào.
  • Không thể thực hiện phép toán + với con trỏ void
  • Ví dụ :
  • void *px, *py;
    int x = 1;
    float y = 0.5;
    px = &x;
    py = &y;
    printf("%d %f",*(int*)px,*(float*)py);
    

Con trỏ hàm

  • Mặc dù một hàm không phải là một biến nhưng nó vẫn chiếm vị trí trong bộ nhớ và ta có thể gán vào vị trí của nó cho một loại biến con trỏ. Con trỏ này trỏ đến điểm xâm nhập vào hàm. Ta gọi đây là con trỏ hàm. Con trỏ hàm có thể sử dụng thay cho tên hàm và việc sử dụng con trỏ cho phép các hàm cũng được truyền như là tham số cho các hàm khác.
  • Để hiểu được các con trỏ hàm làm việc như thế nào, ta cần hiểu một chút về cách biên dịch và gọi một hàm. Khi biên dịch hàm, trình biên dịch chuyển chương trình nguồn sang dạng mã máy và thiết lập một điểm xâm nhập vào hàm (chính là vị trí chỉ thị mã máy đầu tiên của hàm). Khi có lời gọi thực hiện hàm, máy tính sẽ thực hiện một chỉ thị call chuyển điều khiển đến điểm xâm nhập này. Trong trường hợp gọi hàm bằng tên hàm thì điểm xâm nhập này là trị tức thời (gần như là một hằng và không chứa biến nào cả), cách gọi hàm này gọi là cách gọi hàm trực tiếp. Trái lại, khi gọi hàm gián tiếp thông qua một biến trỏ thì biến trỏ đó phải trỏ tới chỉ thị mã máy đầu tiên của hàm đó. Cách gọi hàm thông qua biến trỏ hàm gọi là cách gọi hàm gián tiếp.
  • Khai báo : KDL *TênConTrỏ(Danh sách các biến);
  • Ví dụ
  • long giaithua(int n)
    {
      long gt = 1;
      for (int i = 1; i <= n; i++)
        gt *= i;
      return gt;
    }
    void main()
    {
      long *p(int);
      p = giaithua;
      printf(“%ld”,p(5)); //Tương đương câu lệnh printf(“%ld”,giaithua(5));
      printf(“%ld”,(*p)(5)); //Tác dụng giống câu lệnh trên
    }
    

No comments:

Post a Comment

Có thể post link nhaccuatui, youtube, link hình và link mp3

[size="cở chữ"]Chữ[/size], [color="màu chữ"]Chữ[/color]

Chèn Emoticons
:) :)
:( :(
:( :((
:)) :))
=(( =((
=)) =))
;) ;)
:D :D
:X :X
X( X(
~X( ~X(
:-*
[-(
8-x 8-x
I-)

Recent Posts

    Recent Comments

    Back to top