Lập trình C

Con trỏ hằng và Hằng con trỏ trong C/C++

Con trỏ hằng và Hằng con trỏ trong C/C++
Được viết bởi Minh Hoàng

Series lập trình C, ngôn ngữ lập trình hệ thống mạnh mẽ.

Tiếp tục loạt bài trong series về con trỏ, trong bài này chúng ta sẽ tìm hiểu những nội dung sau:

  1. Hằng con trỏ (Constant pointer) là gì?
  2. Con trỏ hằng (Pointer to constant) là gì?
  3. Hằng con trỏ trỏ tới hằng (Constant pointer to constant) là gì?
1. Hằng con trỏ (Constant pointer) là gì?
1. Hằng con trỏ (Constant pointer) là gì?

■ Khai báo:

<Kiểu dữ liệu> * const <Tên con trỏ> = <Địa chỉ khởi tạo>;

■ Đặc điểm:

  • Khi khai báo hằng con trỏ cần khởi tạo giá trị địa chỉ cho nó.
  • Và từ lúc này, địa chỉ khởi tạo đó là cố định, không bao giờ thay đổi. Tức là: khi hằng con trỏ đã trỏ đến 1 địa chỉ, nó sẽ nằm “dính chặt” vào đó, không thể trỏ tới bất kỳ 1 địa chỉ nào khác.
  • Có thể thay đổi được giá trị tại địa chỉ đã khởi gán ban đầu.

Ví dụ 1: Lỗi khi hằng con trỏ p không được khởi tạo địa chỉ khi khai báo.

#include <iostream>

int main()
{
	int* const p; // error

	return 0;
}
Trình biên dịch thông báo lỗi vì hằng con trỏ p không khởi tạo địa chỉ khi khai báo

Trình biên dịch thông báo lỗi vì hằng con trỏ p không khởi tạo địa chỉ khi khai báo

Ví dụ 2: Lỗi khi thay đổi địa chỉ của hằng con trỏ.

#include <iostream>

int main()
{
	int m = 2;
	int* const p = &m;
	p++; // error

	return 0;
}
Trình biên dịch thông báo lỗi vì hằng con trỏ không thể thay đổi địa chỉ trỏ tới

Trình biên dịch thông báo lỗi vì hằng con trỏ không thể thay đổi địa chỉ trỏ tới

Ví dụ 3: Việc thay đổi giá trị là OK.

#include <stdio.h>

int main()
{
	int m = 2;

	int* const p = &m;

	printf("\n*p = %d", *p);

	// Thay đổi giá trị tại biến mà hằng con trỏ trỏ tới
	m++;	// OK

	printf("\n*p = %d", *p);

	// Thay đổi giá trị của hằng con trỏ
	*p = 9;	// OK

	printf("\n*p = %d", *p);

	getchar();
	return 0;
}
Thay đổi giá trị của hằng con trỏ là OK

Thay đổi giá trị của hằng con trỏ là OK

*** Từ đây ta có thể thấy tên mảng 1 chiều chính là một hằng con trỏ. Vì có thể thay đổi giá trị con trỏ arr trỏ tới, nhưng không thể thay đổi giá trị của arr.

int arr[5];
	
arr[0] = 5;		// ok
arr[9] = 1987;	        // ok

arr++;			// lỗi ko thể thay đổi
arr--;			// lỗi ko thể thay đổi
2. Con trỏ hằng (Pointer to constant) là gì?
2. Con trỏ hằng (Pointer to constant) là gì?

■ Khai báo:

const <Kiểu dữ liệu> * <Tên con trỏ>;

■ Đặc điểm:

  • Con trỏ hằng có thể trỏ đến các ô nhớ khác nhau (có thể trỏ đi lung tung trong bộ nhớ, các phép toán tăng giảm địa chỉ của con trỏ hoàn toàn hợp lệ).
  • Nhưng không thể thay đổi giá trị tại ô nhớ mà nó đang trỏ đến.

* Các bạn có thể nhận thấy nó ngược với hằng con trỏ đã nói ở trên Wink

* Ví dụ điển hình là hàm strlen mà chúng ta hay sử dụng để lấy chiều dài của một chuỗi:

size_t strlen ( const char * str );

Ví dụ 1: Con trỏ hằng có thể thay đổi địa chỉ mà nó trỏ tới.

#include <stdio.h>

int main()
{
	int num1 = 2;
	int num2 = 10;
	char *blog = "minhhn.com";

	const int *p;

	p = &num1;
	printf("\nGia tri nhan duoc: %d", *p);	// Output: 2

	p = &num2;
	printf("\nGia tri nhan duoc: %d", *p);	// Output: 10

	p = blog;
	printf("\nGia tri nhan duoc: %s", p);	// Output: minhhn.com

	getchar();
	return 0;
}

Ví dụ 2: Con trỏ hằng không thể thay đổi giá trị của địa chỉ mà nó trỏ tới.

#include <stdio.h>

int main()
{
	int m = 3;

	const int *p;

	p = &m;

	m = 20;		// ok
	m++;		// ok

	*p = 99;	// error
	(*p)++;		// error

	return 0;
}

*** Khi bạn code trong 1 project C lớn một tí hoặc lớn nhiều tí, giả sử bạn có 1 hàm, thao tác với 1 mảng, hàm này chỉ đọc mảng thôi, không làm thay đổi các giá trị trong mảng. Và quan trọng là, khi share code cho các bạn khác trong cùng project, làm sao để họ biết điều này???
Vậy ta sẽ cài đặt hàm của mình như sau:

#include <stdio.h>
/*	
	Đối với trường hợp con trỏ hằng là tham số thì:
	void Xuly(const int *) và void Xuly(int const *) 
	là như nhau, từ const khi đóng góp vào trong tham số hình thức là như nhau.
*/
void Xuly(const int *a, int n)
{
	// Xử lý gì đó
}

int main()
{
	int a[] = { 1,2 };
	int n = 2;

	Xuly(a, n); // Khi sử dụng hàm này tôi hiểu là: nó ko thay đổi các giá trị mảng a của tôi đâu
				// yên tâm xài, nếu có lỗi gì đó thì ko phải sinh ra từ đây.
	return 0;
}
3. Hằng con trỏ trỏ tới hằng (Constant pointer to constant) là gì?
3. Hằng con trỏ trỏ tới hằng (Constant pointer to constant) là gì?

■ Khai báo:

const <Kiểu dữ liệu> * const <Tên con trỏ> = <Địa chỉ khởi tạo>;

■ Đặc điểm:

  • Không thể thay đổi được địa chỉ mà con trỏ trỏ tới.
  • Và cũng không thể thay đổi được giá trị tại địa chỉ mà con trỏ trỏ tới.
#include <stdio.h>

int main()
{
	int m = 44;
	int n = 55;

	const int* const p = &m;

	p = &n;		// error: Không thể thay đổi địa chỉ

	*p = 100;	// error: Không thể thay đổi giá trị

	return 0;
}
Cảm ơn bạn đã theo dõi. Đừng ngần ngại hãy cùng thảo luận với chúng tôi! Minh Hoàng Blog | Nào cùng vui hehe


Giới thiệu

Minh Hoàng

Xin chào, tôi là Hoàng Ngọc Minh, hiện đang làm BrSE, tại công ty Toyota, Nhật Bản. Những gì tôi viết trên blog này là những trải nghiệm thực tế tôi đã đúc rút ra được trong cuộc sống, quá trình học tập và làm việc. Các bài viết được biên tập một cách chi tiết, linh hoạt để giúp người đọc có thể tiếp cận một cách dễ dàng nhất. Hi vọng nó sẽ có ích hoặc mang lại một góc nhìn khác cho bạn[…]

Bình luận của bạn

2 Comments cho bài viết "Con trỏ hằng và Hằng con trỏ trong C/C++"

avatar
Sắp xếp theo:   Mới nhất | Cũ nhất | Thích nhiều nhất
trackback

[…] tương đương với arr). Thật vậy, tên mảng một chiều thực chất là một con trỏ hằng trỏ tới địa chỉ của phần tử đầu tiên trong […]

trackback

[…] – Size = 4 : Sau khi thực hiện hàm ResizeArray thì không làm thay đổi kích thước của mảng, vì mảng một chiều chính là một hằng con trỏ, chỉ có thể thay đổi được giá trị, nhưng không thể thay đổi được (không tăng hay giảm được) kích thước vùng nhớ, xem thêm: Thế nào là hằng con trỏ? […]

wpDiscuz
Chúc bạn có một cuộc sống ngoại hạng!