Mảng con trỏ trong lập trình C

Trước khi tìm hiểu mảng con trỏ, chúng ta xét vài ví dụ để hiểu được vì sao mảng con trỏ là cần thiết trong ngôn ngữ lập trình C.

Ví dụ 1: sắp xếp chuỗi theo thứ tự alpha, beta,..

#include <stdio.h>
#include <string.h>
#include <conio.h>

#define LENGTH 30

void strsort(char str[][LENGTH], int num);
void strshow(char str[][LENGTH], int num);

void main( void )
{
    char strarr[][LENGTH] = {"C/C++", "Java", "C#", "Python", "PHP", "Java Script"};
    strsort(strarr, 6);
    strshow(strarr, 6);
    getch();
}

void strsort(char str[][LENGTH], int num)
{
    int i, j;
    char temp[LENGTH];
    for (i = 0; i < num; i++) 
    { 
        for (j = num-1; j > i; j--)
        {
            if(strcmp(str[j], str[j-1]) < 0)
            {
                strcpy(temp, str[j]);
                strcpy(str[j], str[j-1]);
                strcpy(str[j-1], temp);
            }
                
        }
    }
}

void strshow(char str[][LENGTH], int num)
{
    int i;
    for (i = 0; i < num; i++)
    {
        printf("\nstr[%d] = %s", i+1, str[i]);
    }
}

Kết quả:

Sắp xếp chuỗi theo thứ tự alpha, beta
Sắp xếp chuỗi theo thứ tự alpha, beta

Qua ví dụ ở trên, chúng ta thấy để sắp xếp 1 mảng các chuỗi yêu cầu swap các chuỗi với nhau ( sử dụng hàm strcpy( ) hoán đổi nội dung giữa các chuỗi với nhau). Khi gặp các bài toán với kích thước dữ liệu lớn (chuỗi, struct,…), việc copy dữ liệu làm giảm performance của chương trình.

→ Dùng con trỏ trỏ tới vùng nhớ của dữ liệu (chuỗi, struct,…), sau đó swap con trỏ.

Ví dụ 2:

void main( void )
{
    int n = 6, m = 8;
    int *p1, *p2, *p;
    p1 = &n;
    p2 = &m;
    //swap p1 and p2
    p = p1;
    p1 = p2;
    p2 = p;

    printf("\nn = %d", *p1);
    printf("\nm = %d", *p2);

    getch();
}

Kết quả:

hoán vị 2 số nguyên
hoán vị 2 số nguyên

Ở đây, chúng ta sử dụng 2 con trỏ p1 và p2 trỏ tới địa chỉ biến n và m. Thay vì hoán vị trực tiếp 2 biến n và m, chúng ta có thể hoán vị con trỏ p1 và p2. Từ ý tưởng này, chúng ta có thể sử dụng con trỏ để hoán vị 2 chuỗi cho nhau. Các bạn xem tiếp ví dụ sau:

Ví dụ 3: hoán vị 2 chuỗi

#include <stdio.h>
#include <conio.h>

void main( void )
{
    char s1[] = "vncoding.net";
    char s2[] = "congdongcviet.com";

    char *p1, *p2, *p;
    p1 = s1;
    p2 = s2;

    printf("\ns1 = %s", p1);
    printf("\ns2 = %s", p2);

    printf("\nswapping.....");

    //swap 2 strings
    p = p1;
    p1 = p2;
    p2 = p;

    printf("\ns1 = %s", p1);
    printf("\ns2 = %s", p2);

    getch();
}

Kết quả:

hoán vị 2 chuỗi
hoán vị 2 chuỗi

Con trỏ p1, p2 trỏ tới chuỗi s1, s2 tương ứng. Để đổi chỗ 2 chuỗi, chúng ta hoán vị 2 con trỏ.

Tổng kết lại, chúng ta có thể sử dụng mảng con trỏ để trỏ tới các phần tử trong mảng dữ liệu (string, struct,…) tương ứng. Việc sắp xếp các phần tử trong mảng dữ liệu (string, struct,…) dựa vào việc hoán vị các con trỏ. Mảng con trỏ sẽ lưu kết quả sắp xếp mảng (các phần tử mảng dữ liệu thực tế không được hoán vị).

Việc hoán vị con trỏ tăng performance của chương trình so với cách truyền thống như ở ví dụ 1

Chúng ta xét ví dụ tiếp theo về cách khai báo và sử dụng mảng con trỏ để sắp xếp mảng chuỗi kí tự.

Ví dụ 4:

#include <stdio.h>
#include <string.h>
#include <conio.h>

#define LENGTH 30
#define SIZE 10

void strsort(char** str, int num);
void strshow(char** str, int num);
void main( void )
{
    char strarr[][LENGTH] = {"C/C++", "Java", "C#", "Python", "PHP", "Java Script"};
    char* pstr[SIZE];
    int i;
    for (i = 0; i < 6; i++)
    {
        pstr[i] = strarr[i];
    }

    strsort(pstr, 6);
    strshow(pstr, 6);
    getch();
}

void strsort(char** str, int num)
{
    int i, j;
    char* temp;
    for (i = 0; i < num; i++) 
    { 
        for (j = num-1; j > i; j--)
        {
            if(strcmp(str[j], str[j-1]) < 0)
            {
                temp = str[j];
                str[j] = str[j-1];
                str[j-1] = temp;
            }
        }
    }
}

void strshow(char** str, int num)
{
    int i;
    for (i = 0; i < num; i++)
    {
        printf("\nstr[%d] = %s", i+1, str[i]);
    }
}

Giải thích:

for (i = 0; i < 6; i++)
{
    pstr[i] = strarr[i];
}

Gán phần tử mảng con trỏ trỏ tới mỗi chuỗi trong mảng chuỗi.

Gán con trỏ cho chuỗi kí tự
Gán con trỏ cho chuỗi kí tự
if(strcmp(str[j], str[j-1]) < 0)
{
    temp = str[j];
    str[j] = str[j-1];
    str[j-1] = temp;
}

Hoán vị con trỏ. Sau khi thực hiện xong hàm strsort(). Giá trị mảng con trỏ như sau:

Mảng con trỏ sau khi sắp xếp
Mảng con trỏ sau khi sắp xếp

Kết quả mảng con trỏ lưu kết quả sắp xếp. Do vậy, mọi thao tác: hiển thị thông tin mảng được sắp xếp ra màn hình, ghi ra file đều được xử lí trên mảng con trỏ.

Sắp xếp chuỗi dùng mảng con trỏ
Sắp xếp chuỗi dùng mảng con trỏ

 

Be the first to comment

Leave a Reply