Mình đọc tới đọc lui cả mấy tiếng đồng hồ mà chưa hiểu phải giải thích sao cho hợp lý, thôi mình post lên cho bạn coi những điểm khác biệt, biết đâu bạn có thể rút ra kết luận cho bạn cũng được:
Trong C++, thực chất thằng char và các kiểu còn lại như int, float, double.. là hoàn toàn khác nhau, bây h bạn coi ví dụ sau :
#include <iostream>
int main(){
int x = 0;
int *ptr = &x;
std
::cout << "The address of x is " << ptr
<< '\n' << "the value of x " << *ptr << '\n';
return 0;
}
Output
The address of x is 0x246ff40
the value of x 0
Nhưng đó là kiểu int, nếu bây đổi thành char là nó in ra garbage ngay :
#include <iostream>
int main(){
char x('A');
char *ptr = &x;
std
::cout << "The address of x is : " << ptr
<< '\n' << " and the value of x : " << *ptr << '\n';
return 0;
}
Output
The address of x is : Aê F☻☻D
and the value of x : A
Đó, bạn thấy đó, rõ ràng là do thằng nó ra rác, chỗ này là do thằng cout << của C++, nó được overloaded để in ra dữ liệu của thằng char * như là 1 chuỗi kí tự có NULL ở cuối, cho nên bây h muốn đúng thì ta đổi thành như sau :
SOLUTION
#include <iostream>
int main(){
char x('A');
char *ptr = &x;
std
::cout << "The address of x is : " << static_cast<void*>(ptr
) << '\n' << " and the value of x : " << *ptr << '\n';
return 0;
}
Bây h quay lại thằng int :
int main(){
int array[3] = {1,2,3};
for(int x = 0; x < 3; x++)
std
::cout << &array
[x
] << '\n';
return 0;
Output
0x246ff34
0x246ff38
0x246ff3c
Rõ ràng nó cout ra địa chỉ của từng phần tử. Như bạn đã nêu ra cái mà bạn nói thú vị đó và cũng như huynguyen đã nói : tên của mãng thực chất là con trỏ hằng trỏ tới vị trí đầu tiên của mãng, vậy nếu có khai báo :
thì tương đương với :
Vì vậy bạn cout ra nó có kết quả như nhau.
Nhưng đó là đối với mãng int, còn đối với mãng char trong C++ thì nó khác. Ví dụ :
int main(){
char array[] = "abc";
for(int x = 0; x < 3; x++){
cout << &array
[x
] << '\n'; }
return 0;
Output
Vì các kí tự là những cấu trúc cơ bản 1 chương trình C++. Mỗi chương trình sẽ được là tác phẩm của 1 loạt các kí tự, mà khi các kí tự này được gom lại 1 cách có ý nghĩa thì nó được thông dịch bởi complier nhưng là 1 chuỗi các hướng dẫn dùng để tiến hành 1 nhiệm vụ nào đó. Và một chương trình thì có thể chưa những kí tự hằng (character constant). Mà 1 kí tự hằng thì là 1 giá trị kiểu integer được biễu diễn bởi 2 cái quote ví dụ 'A', 'B'...
Trong khi thằng string lại là 1 chuỗi của các kí tự mà nó được xem như là 1 thể độc lập. Mà chuỗi trong C++ thì được viết với syntax là :
"Iam C++", "This is my cat"...
Đồng thời chuỗi trong C++ là 1 mãng của các kí tự mà kết thúc bởi 1 kí tự null (null character) ('\0'), cái này là cái mà để xác định chuỗi kết thúc trong bộ nhớ máy tính. Mà 1 chuỗi thì được truy xuất thông qua 1 con trỏ tới kí tự đầu của chuỗi đó. Cho nên khai báo :
Code:
char color[] = "blue";
Và khai báo :
Code:
char color[] = {'b','l','u','e','\0'};
Là hoàn toàn giống nhau. Và khai báo như thế nghĩa là các kí tự tạo thành 1 chuỗi tự do, liên tục nhau, và nó được bộ nhớ máy tính lưu tại 1 địa chỉ nào đó trong vùng nhớ.
Cái này tuy hơi lạc đề, nhưng mình nghĩ muốn hiểu cái gì đến tận cùng đầu tiên phải nắm bản chất của nó là gì, vì trong lập trình sai 1 ly thì đi 1 dặm.
Bây giờ vấn đề chính là tại sao nếu khai báo char :
và
lại khác nhau
trong khi khai báo int
lại giống nhau
Cho đến h mình chỉ có 2 giải thiết :
- Thứ nhất là thực chất vì chuỗi là tự do, nằm liên tục cho nên nó chỉ có 1 địa chỉ duy nhất, do đó ta không truy xuất được các địa chỉ tiếp theo của nó, mà tau chỉ có thể truy xuất tới thông qua con trỏ của nó thôi.
- Thứ hai là do nó là string, nên có thể thằng cout << được quá tải để xử lý đối với trường hợp là chuỗi, do đó nó sẽ tự hiểu và in ra giá trị thay vì địa chỉ của nó. Mình thì có lẽ thấy cái trường hợp này đúng hơn, vì bản chất thằng stream cout << nó không có quá tải cho thằng pointer kiểu int, hay float...nên nó output ra thẳng địa chỉ, trong khi đối với những string thì nó lại cho ra giá trị vì nó có quá tải của string trong đó.
Mình chỉ hiểu được tới đó, thôi đành để những tiền bối như anh TQN giải đáp vậy :(. Nhưng cũng cám ơn bạn vì những câu hỏi khó chịu như vậy, haha, tìm hiểu nó mà oải luôn nhưng bù lại biết được cái mình chưa biết- mà cái này giá trị hơn ^^!