Truyền con trỏ vào hàm trong C | Laptrinhcanban.com

HOME › >>

Truyền con trỏ vào hàm trong C

Cùng tìm hiểu về cách truyền con trỏ vào hàm trong c. Bạn sẽ biết cách truyền con trỏ vào hàm trong c để thay đổi các đối tượng mà con trỏ chỉ đến như biến, mảng và đối tượng sau bài học này.

Truyền con trỏ vào hàm trong C

Về cơ bản thì khi gọi hàm trong C, chúng ta sẽ truyền một giá trị nào đó cho hàm.

Thông thường, chúng ta có thể truyền giá trị của một biến, một mảng hay một chuỗi vào hàm.

Tuy nhiên thay vì truyền trực tiếp một giá trị và xử lý giá trị đó trong hàm thì chúng ta sẽ truyền con trỏ chỉ tới nó, và xử lý gián tiếp nó thông qua con trỏ.

Ví dụ, hãy cùng so sánh hai hàm sau đây, với một hàm dùng để truyền trực tiếp giá trị của biến, và hàm còn lại thay vì truyền biến thì sẽ truyền con trỏ chỉ đến địa chỉ của nó vào hàm:

#include <stdio.h>

//Khai báo hàm dùng biến làm đối số
void funcA(int i){
i = 7;
}

//Khai báo hàm dùng con trỏ của biến làm đối số
void funcB(int *i){
(*i) = 222;
}

int main(void){
int a = 1;

printf("a=%d\n", a);

//Truyền biến vàm hàm
funcA(a);
printf("after funcA() : a=%d\n", a);

//Truyền địa chỉ (con trỏ) của biến vào hàm
funcB(&a); //&a dùng để lấy địa chỉ của biến a
printf("after funcB() : a=%d\n", a);

return 0;
}

Kết quả:

a=1
after funcA() : a=1
after funcB() : a=222

Chúng ta có thể thấy giá trị biến a không thay đổi sau khi được xử lý trực tiếp trong hàm funcA(), tuy nhiên lại thay đổi sau khi được xử lý gián tiếp thông qua con trỏ trong hàm funcB().

Hai hàm funcA() và funcB() ở trên khác nhau ở chỗ, funcA() truyền giá trị của biến a vào hàm, trong khi đó funcB() lại truyền con trỏ của biến a vào hàm.

Với cách truyền giá trị của biến của funcA(), khi đó một bản sao giá trị của biến a sẽ được copy, rồi truyền vào biến i và xử lý trong hàm. Do đó, mặc dù giá trị của i thay đổi trong hàm, nhưng kết quả giá trị của biến a ngoài hàm không hề bị thay đổi.

Tuy nhiên với các truyền con trỏ của biến a vào hàm funcB() thì lại khác. Khi đó, biến i trong hàm sẽ chỉ đến địa chỉ thực của biến a trên bộ nhớ, và do đó khi biến i thay đổi thì kết quả là biến a cũng thay đổi theo.

Chúng ta có thể thấy rõ việc truyền một giá trị, và việc truyền một con trỏ chỉ đến giá trị đó vào hàm, sẽ cho ra các kết quả hoàn toàn khác nhau.

Bằng cách truyền con trỏ vào hàm trong c, chúng ta có thể thay đổi gián tiếp các đối tượng như biến, mảng, chuỗi hoặc cấu trúc trong chương trình.

Truyền con trỏ biến vào hàm trong c

Ví dụ cụ thể, trong bài Return trong C, chúng ta đã truyền các con trỏ đến biến vào hàm, và hoán đối giá trị các biến đó một cách gián tiếp thông qua con trỏ như sau:

#include <stdio.h>

void swap(int *x, int *y) {
int tmp;

tmp = *x;
*x = *y;
*y = tmp;
}

int main(void) {
int num1 = 123;
int num2 = 456;

printf("Truoc khi hoan doi:num1 = %d, num2 = %d\n", num1, num2);
swap(&num1, &num2); //Truyền con trỏ của các biến vào hàm
printf("Sau khi hoan doi:num1 = %d, num2 = %d\n", num1, num2);

return 0;
}

Kết quả:

Truoc khi hoan doi:num1 = 123, num2 = 456
Sau khi hoan doi:num1 = 456, num2 = 123

Do chúng ta không truyền giá trị biến, mà truyền địa chỉ của biến (con trỏ biến), nên khi gọi hàm swap(), chúng ta cần thêm toán tử & để lấy địa chỉ của các biến khi truyền vào hàm.

Truyền con trỏ mảng vào hàm trong c

Ví dụ cụ thể, trong bài Đảo ngược mảng trong C, chúng ta đã truyền con trỏ mảng vào hàm, và tiến hành đảo ngược một mảng gián tiếp trong hàm thông qua con trỏ như sau:

#include <stdio.h>

//Tạo hàm đảo ngược mảng
void reverse(int* array, int size)
{
/*Tạo vòng lặp để hoán đổi số đầu với số cuối trong mảng
và thu dần khoảng cách về giữa mảng*/
for (int i = 0; i < size / 2; ++i) {
//Thực hiện phép hoán đổi
int temp = array[i];
array[i] = array[size - i - 1];
array[size - i - 1] = temp;
}
}

/*Tạo hàm in phần tử trong mảng*/
void show_array(int array[], int length){
for(short i = 0; i < length; i++) printf("%d ", array[i]);
printf("\n");
}

int main(void)
{
int array1[] = {11, 22, 33, 44,};
int array2[] = {0, 1, 2, 3, 4, 5};

//Lấy độ dài mảng ban đầu
int size1 = sizeof array1 / sizeof(int);
int size2 = sizeof array2 / sizeof(int);

reverse(array1, size1);
reverse(array2, size2);

//in mảng kết quả
show_array(array1,size1);
show_array(array2,size2);

return 0;
}

Kết quả:

44 33 22 11 
5 4 3 2 1 0

Lưu ý, mặc dù trong hàm reverse() chúng ta nhận con trỏ của mảng bằng cách ghi reverse(int* array, int size), tuy nhiên khi gọi hàm, chúng ta không cần thêm toán tử & để lấy địa chỉ của mảng, mà truyền trực tiếp tên mảng vào hàm.

Lý do là bởi vì như Kiyoshi đã trình bày trong bài Con trỏ mảng trong C thì khi khai báo một mảng, tên biến dùng để khai báo mảng sẽ biểu thị địa chỉ của điểm bắt đầu của vùng lưu mảng trong bộ nhớ.

Bởi vậy, vốn tên mảng đã trỏ tới địa chỉ của mảng đó trong bộ nhớ, nên việc viết tên biến đã gán mảng vào cũng có ý nghĩa tương đương với địa chỉ (con trỏ) của mảng đó, và chúng ta không cần thêm toán tử & nữa trong trường hợp này.

Truyền con trỏ chuỗi vào hàm trong c

Ví dụ cụ thể, trong bài Đảo ngược mảng trong C, chúng ta đã truyền con trỏ chuỗi vào hàm, và tiến hành gán giá một chuỗi ký tự ngẫu nhiên vào chuỗi đó trong hàm thông qua con trỏ như sau:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

void rand_text(int length, char *result) {
int i, rand_int;
char char_set[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&quot";

for (i = 0; i <length; i++) {
result[i] = char_set[rand() % sizeof(char_set)];
}
result[length] = 0;
}

int main(void){
printf("Nhap đo dai chuoi: ");
int length;
scanf("%d",&length);

char result[length + 1];
srand(time(NULL));

rand_text(length, result);
printf("%s", result);
}

Kết quả:

Nhap đo dai chuoi: 5
XtoI

Chuỗi cũng là một loại mảng trong C, do đó tương tự như mảng thì chúng ta không cần thêm toán tử & để lấy địa chỉ của chuỗi, mà truyền trực tiếp tên chuỗi vào hàm. Khi đó thì tên chuỗi cũng biểu thị địa chỉ của chuỗi đó trong bộ nhớ, cũng có ý nghĩa là con trỏ của chuỗi đó rồi.

Tổng kết

Trên đây Kiyoshi đã hướng dẫn các bạn về cách truyền con trỏ vào hàm trong c rồi. Để nắm rõ nội dung bài học hơn, bạn hãy thực hành viết lại các ví dụ của ngày hôm nay nhé.

Và hãy cùng tìm hiểu những kiến thức sâu hơn về C trong các bài học tiếp theo.

URL Link

https://laptrinhcanban.com/c/lap-trinh-c-co-ban/ham-trong-c/truyen-con-tro-vao-ham-trong-c/

Hãy chia sẻ và cùng lan tỏa kiến thức lập trình Nhật Bản tại Việt Nam!

HOME  › >>

Profile
きよしです!笑

Tác giả : Kiyoshi (Chis Thanh)

Kiyoshi là một cựu du học sinh tại Nhật Bản. Sau khi tốt nghiệp đại học Toyama năm 2017, Kiyoshi hiện đang làm BrSE tại Tokyo, Nhật Bản.