Bài Tập Về Con Trỏ C++ – Bài Tập Về Con Trỏ Trong C

reset1010.com đã có khóa học Lập trình C qua videoXem chi tiết

Nếu bạn chưa có kiến thức về con trỏ, xin mời xem bài viết Con trỏ (Pointer).

Bạn đang xem: Bài tập về con trỏ c++

Con trỏ giúp dễ hàng hơn trong việc làm việc thao tác với địa chỉcác biến.

Ta có thể khẳng địnhrằng địa chỉ được gán cho một con trỏ phải cùng loại với quy định trong khai báo con trỏ.Ví dụ, nếu ta khai báo con trỏ int, thì con trỏ int này không thể trỏ đến biến float hoặc một số loại biến khác, nghĩa là nó chỉ có thể trỏ đến biến kiểu int.Để khắc phục vấn đề này, ta sử dụng con trỏ void.Một con trỏ đến void có nghĩa là một con trỏ chung có thể trỏ đến bất kỳ loại dữ liệu nào.Chúng ta có thể gán địa chỉ của bất kỳ loại dữ liệu nào cho con trỏ void và con trỏ void có thể được gán cho bất kỳ loại con trỏ nào mà không thực hiện bất kỳ kiểu chữ rõ ràng nào.

Cú pháp của con trỏ void

void *tên_con_trỏ;

Ví dụ:

void*p;

Ta xét một số ví dụ sau:

int i=9; // integer variable initialization.

int *p; // integer pointer declaration.

float *fp; // floating pointer declaration.

void *ptr; // void pointer declaration.

p=fp; // incorrect.

fp=&i; // incorrect

ptr=p; // correct

ptr=fp; // correct

ptr=&i; // correct

Kích thước của con trỏ void trong C

Kích thước của con trỏ void trong C giống với kích thước của con trỏ kiểu ký tự.Theo nhận thức của C, việc thể hiện một con trỏ thành void giống như con trỏ của kiểu ký tự.Kích thước của con trỏ sẽ thay đổi tùy thuộc vào nền tảng mà bạn đang sử dụng.

Hãy xem ví dụ dưới đây:

#includemain(){void*ptr=NULL;//voidpointerint*p=NULL;//integerpointerchar*cp=NULL;//characterpointerfloat*fp=NULL;//floatpointer//sizeofvoidpointerprintf(“sizeofvoidpointer=%d\n\n”,sizeof(ptr));//sizeofintegerpointerprintf(“sizeofintegerpointer=%d\n\n”,sizeof(p));//sizeofcharacterpointerprintf(“sizeofcharacterpointer=%d\n\n”,sizeof(cp));//sizeoffloatpointerprintf(“sizeoffloatpointer=%d\n\n”,sizeof(fp));return0;}

#includemain(){*ptr=NULL;//voidpointer*p=NULL;//integerpointer*cp=NULL;//characterpointer*fp=NULL;//floatpointer//sizeofvoidpointerprintf(“sizeofvoidpointer=%d\n\n”,(ptr));//sizeofintegerpointerprintf(“sizeofintegerpointer=%d\n\n”,(p));//sizeofcharacterpointerprintf(“sizeofcharacterpointer=%d\n\n”,(cp));//sizeoffloatpointerprintf(“sizeoffloatpointer=%d\n\n”,(fp));0;}

Kết quả:

Ưu điểm của con trỏ void

Sau đây là những lợi thế của một con trỏ void:

Hàm malloc () và calloc () trả về con trỏ void, vì vậy các hàm này có thể được sử dụng để phân bổ bộ nhớ của bất kỳ loại dữ liệu nào.#include#includeintmain(){inta=90;int*x=(int*)malloc(sizeof(int));x=&a;printf(“Valuewhichispointedbyxpointer:%d”,*x);return0;}

Hàm malloc () và calloc () trả về con trỏ void, vì vậy các hàm này có thể được sử dụng để phân bổ bộ nhớ của bất kỳ loại dữ liệu nào.#include#includemain(){a=90;*x=(*)malloc());x=&a;printf(“Valuewhichispointedbyxpointer:%d”,*x);0;}

Kết quả:

Con trỏ void trong C cũng có thể được sử dụng để thực hiện các hàm chung trong C.

Con trỏ void trong C cũng có thể được sử dụng để thực hiện các hàm chung trong C.

Một số điểm quan trọng liên quan đến con trỏ void là:

Hủy bỏ một con trỏ trống trong C

Con trỏ void trong C không thể được hủy đăng ký trực tiếp.Hãy xem ví dụ dưới đây:

#includeintmain(){inta=90;void*ptr;ptr=&a;printf(“Valuewhichispointedbyptrpointer:%d”,*ptr);return0;}

#includemain(){a=90;*ptr;ptr=&a;printf(“Valuewhichispointedbyptrpointer:%d”,*ptr);0;}

Trong đoạn mã trên, * ptr là một con trỏ void đang trỏ đến biến số nguyên ‘a’.Như chúng ta đã biết rằng con trỏ void không thể bị hủy đăng ký, do đó đoạn mã trên sẽ đưa ra lỗi thời gian biên dịch vì chúng ta đang in trực tiếp giá trị của biến được trỏ bởi con trỏ ‘ptr’.

Kết quả:

Bây giờ, chúng tôi viết lại mã trên để loại bỏ lỗi:

#includeintmain(){inta=90;void*ptr;ptr=&a;printf(“Valuewhichispointedbyptrpointer:%d”,*(int*)ptr);return0;}

#includemain(){a=90;*ptr;ptr=&a;printf(“Valuewhichispointedbyptrpointer:%d”,*(*)ptr);0;}

Trong đoạn mã trên, chúng tôi đánh máy con trỏ void sang con trỏ nguyên bằng cách sử dụng câu lệnh được đưa ra dưới đây:

(int *) ptr;

Sau đó, chúng tôi in giá trị của biến được chỉ ra bởi con trỏ void ‘ptr’ bằng cách sử dụng câu lệnh được đưa ra dưới đây:

* (int *) ptr;

Kết quả:

Phép toán số học trên con trỏ void

Chúng ta không thể áp dụng các phép toán số học trên các con trỏ void trong C trực tiếp.Chúng ta cần áp dụng kiểu chữ phù hợp để có thể thực hiện các phép toán số học trên các con trỏ void.

Hãy xem ví dụ dưới đây:

#includeintmain(){floata<4>={6.1,2.3,7.8,9.0};void*ptr;ptr=a;for(inti=0;i{printf(“%f,”,*ptr);ptr=ptr+1;//Incorrect.}}

#includemain(){a<4>={6.1,2.3,7.8,9.0};*ptr;ptr=a;i=0;i{printf(“%f,”,*ptr);ptr=ptr+1;//Incorrect.}}

Đoạn mã trên cho thấy lỗi thời gian biên dịch “sử dụng biểu thức voidkhông hợp lệvì chúng ta không thể áp dụng trực tiếp các phép toán số học trên con trỏ void, tức là ptr = ptr + 1.

Hãy viết lại mã trên để loại bỏ lỗi:

#includeintmain(){floata<4>={6.1,2.3,7.8,9.0};void*ptr;ptr=a;for(inti=0;i{printf(“%f,”,*((float*)ptr+i));}}

#includemain(){a<4>={6.1,2.3,7.8,9.0};*ptr;ptr=a;i=0;i{printf(“%f,”,*((*)ptr+i));}}

​Đoạn mã trên chạy thành công khi chúng ta áp dụng việc truyền đúng cho con trỏ void, nghĩa là (float *) ptr và sau đó chúng ta áp dụng phép toán số học, tức là * ((float *) ptr + i).

Kết quả:

Tại sao chúng ta sử dụng con trỏ void?

Chúng tôi sử dụng con trỏ void vì khả năng tái sử dụng của nó.Con trỏ trống có thể lưu trữ đối tượng thuộc bất kỳ loại nào và chúng ta có thể truy xuất đối tượng thuộc bất kỳ loại nào bằng cách sử dụng toán tử gián tiếp với kiểu chữ phù hợp.

Hãy hiểu qua một ví dụ như sau:

#includeintmain(){inta=56;//initializationofaintegervariable’a’.floatb=4.5;//initializationofafloatvariable’b’.

Xem thêm:

charc=’k’;//initializationofacharvariable’c’.void*ptr;//declarationofvoidpointer.//assigningtheaddressofvariable’a’.ptr=&a;printf(“valueof’a’is:%d”,*((int*)ptr));//assigningtheaddressofvariable’b’.ptr=&b;printf(“\nvalueof’b’is:%f”,*((float*)ptr));//assigningtheaddressofvariable’c’.ptr=&c;printf(“\nvalueof’c’is:%c”,*((char*)ptr));return0;}

#includemain(){a=56;//initializationofaintegervariable’a’.b=4.5;//initializationofafloatvariable’b’.Xem thêm: 8+ Bài Tập Enough Có Đáp Án, Bài Tập Về Cấu Trúc Enough Kèm Đáp Án Chi Tiết c=’k’;//initializationofacharvariable’c’.*ptr;//declarationofvoidpointer.//assigningtheaddressofvariable’a’.ptr=&a;printf(“valueof’a’is:%d”,*((*)ptr));//assigningtheaddressofvariable’b’.ptr=&b;printf(“\nvalueof’b’is:%f”,*((*)ptr));//assigningtheaddressofvariable’c’.ptr=&c;printf(“\nvalueof’c’is:%c”,*((*)ptr));0;}

Kết quả:

reset1010.com đã có khóa học Lập trình C qua videoXem chi tiết« Prev: Lập trình C: Các hàm xử lý tập tin

reset1010.com đã có khóa học Lập trình C qua videoXem chi tiết« Prev: Lập trình C: Các hàm xử lý tập tin