Chủ Nhật, 19 tháng 12, 2021

1: Biến Con Trỏ (Phần 2) - Con Trỏ Và Mảng

 

1: Biến Con Trỏ


- Con Trỏ Và Mảng

Trong chương trước chúng ta đã thấy các ví dụ về mảng. Con trỏ thường được dùng khi xử lí mảng . Chúng ta xét chương trình sau:

Chương trình mẫu Dev C:
// Pointer_6
#include <stdio.h>

int main()   
{
    int a[10], * pa, x;
    a[0] = 11;
    a[1] = 22;
    a[2] = 33;
    a[3] = 44;

    pa = & a[0];
    x = * pa;
    pa++;
    x = * pa;
    
    x = * pa + 1;
    x = * (pa + 1);
    x = * ++pa;
    x = ++ * pa;
    x = * pa++;
    
    return 0;
}   




int a[l10],*pa,x; khai báo một bảng gồm 10 phần tử kiểu int, được liệt kê là a[0],a[1]....a[9] , một con trỏ để chỉ đến một biến kiểu int và một biến kiểu int là x.

a[0] = 11...; từ a[4] đến a[9] chưa được khởi gán. Như vậy chúng sẽ chứa trị ngẫu nhiên đã có tại những vị trí bộ nhớ đã phân phối cho chúng .

pa = &a[0]; đặt vào pa địa chỉ của phần tử đầu tiên của mảng. Biểu thức này có thể viết đơn giản là pa = a; vì tên của một mảng luôn luôn được trình biên dịch coi là địa chỉ của phần tử đầu tiên của mảng. Tên của mảng không có chỉ số kèm theo có thể được dùng trong chương trình như một hằng địa chỉ.

x = *pa; đặt nội dung của biến nguyên mà pa trỏ đến vào (tức là a[O]) vào x. Như vậy x = 11

pa++; pa được tăng lên 1 và bây giờ trỏ vào phần tử thứ 2 của mảng tức là chứa địa chỉ của phần tử a[1]

x = *pa; pa trỏ đến phần tử a[1] nên x = 22

x = *pa + 1; x = 23

x = *(pa+1); trước hết pa+1 được thực hiện , nghĩa là pa trỏ vào a[2] , sau đó nội dung của a[2] được gán cho x nên x= 33 .Tuy pa tham gia vào phép toán nhưng trị số của nó không thay đổi .

x = *++pa; ++ được thực hiện trước nên pa trỏ tới a[2] . Sau đó trị của a[2] được gán cho x nên x = 33

x = ++*pa; *pa được thực hiện trước. Do pa chỉ đến a[2] nên *pa = 33 và ++*pa = 34 . Như vậy x = 34 và a[2] = 34

x=*pa++; nội dung của pa (tức 34) được đặt vào x . Sau đó nó được tăng lên 1 nên chỉ vào a[3].

Chương trình mẫu Dev C:
// Pointer_7
#include <stdio.h>

int main()   
{
    static int num[] = {
     92,
     81,
     70,
     69,
     58
    };
    int dex;
    
    for (dex = 0; dex < 5; dex++)
    {
        printf("%d\n", num[dex]);
    }
    
    return 0;
}   




Chương trình mẫu Dev C:
// Pointer_8
#include <stdio.h>

int main()   
{
    static int num[] = {
     92,
     81,
     70,
     69,
     58
    };
    int dex;
    
    for (dex = 0; dex < 5; dex++)
    {
        printf("%d\n", *(num + dex));
    }
    
    return 0;
}   




Hai chương trình chỉ khác nhau ở biểu thức : *(num+dex). Cách viết này tương đương với num[dex] .Nói cách khác truy cập đến phần tử có chỉ số dex trong mảng num.
Chúng ta hiểu *(num+dex) như sau : đầu tiên num là địa chỉ của phần tử đầu tiên của mảng num và ta muốn biết trị số của phần tử có chỉ số dex . Vì vậy num+dex sẽ là địa chỉ của phần tử thứ dex . *(num+dex) xác định nội dung của phần tử (nuưm+dex).

Tóm lại: *(array+index) tương tự array(index)
Có hai cách truy cập mảng là:
- theo kí hiệu mảng &array[index]
- theo kí hiệu con trỏ array+index

Chương trình mẫu Dev C: Tính nhiệt độ trung bình bằng cách dùng con trỏ
// Pointer_9
#include <stdio.h>

int main()   
{
    float temp[3];
    float sum = 0.0;
    int num, day = 0;
    
    do
    {
        printf("Cho nhiet do ngay thu %d: ", day + 1);
        scanf("%f", temp + day);
    }
    while ( * (temp + day++) > 0);
    num = day - 1;
    for (day = 0; day < num; day++)
    {
        sum += * (temp + day);
    }
    printf("Nhiet do trung binh la : %.3f", sum / num);
    
    return 0;
}   




Trong ví dụ trên chúng ta đã dùng biểu thức (temp+day) để truy cập mảng. Tuy nhiên viết while((#temp++)>0) vì temp là hằng con trỏ chứ không phải biến con trỏ. Như vậy chỉ được phép thay đổi trị của biến con trỏ chứ không được thay đổi trị của hằng con trỏ . Chúng ta viết lại chương trình như sau:

Chương trình mẫu Dev C:
// Pointer_10
#include <stdio.h>

int main()   
{
    float temp[3];
    float sum = 0.0;
    int num, day = 0;
    float *p;
    
    p = temp;
    do {
     printf("Cho nhiet do ngay thu %d: ", day + 1);
    
     scanf("%f", p);
     day++;
    } while ( *(p++) > 0);
    p = temp;
    num = day - 1;
    for (day = 0; day < num; day++)
    {
        sum += *(p++);
    }
    printf("Nhiet do trung binh la : %.3f", sum / num);
    
    return 0;
}   




Trong chương trình này địa chỉ của temp được đưa vào biến con trỏ p. Sau đó ta tham khảo tới p giống như temp. Ta dùng p trỏ tới máng và #*p là nội dung của địa chỉ đó. Hơn nữa do p là biến con trỏ nên ta có thể tăng nó bằng phát biểu p++.


0 bình luận:

Đăng nhận xét