cái này chắc phải nói dài lắm, rất dễ, nhưng dài
<--------------<>-<< 1 >>-<>-------------->
con trỏ trong c nếu kết hợp với từ khóa const thì có 2 cách kết hợp
1/const nằm bên trái dấu * gọi là con trỏ hằng: không cho phép thay đổi dữ liệu thông qua con trỏ đó
2/const nằm bên phải dấu * gọi là hằng con trỏ: không cho phép con trỏ đó trỏ qua nơi khác
con trỏ hằng có thể trỏ tới biến hằng hoặc biến thường, nhưng con trỏ thường chỉ có thể trỏ tới biến thường mà thôi
nói 1 cách hình tượng thì cũng giống như cái nồi lớn có thể nấu được 1 con gà hoặc 1 con chim cút, nhưng cái nồi nhỏ thì chỉ có thể nấu được cút mà thôi, lý do có cái quy tắc này đơn giản là để ngăn không cho thay đổi giá trị của biến hằng thông qua con trỏ bình thường
<--------------<>-<< 2 >>-<>-------------->
giờ nói về mảng trong c, giả sử cho 1 mảng a
int a[100];
thì khi làm việc với biến a, thực chất là bạn đang làm việc với địa chỉ của phần tử đầu tiên trong mảng a, chẳng hạn
int *p = a;
tương đương với
int *p = &a[0];
khi truyền cho hàm cũng vậy
strlen(a);
tương đương với
strlen(&a[0]);
như vậy 3 dòng sau đây tất cả đều là 1
strlen(a);
strlen(p);
strlen(&a[0]);
<--------------<>-<< 3 >>-<>-------------->
giờ nói về chuỗi, chuỗi kí tự trong c thực chất chỉ là 1 mảng char, với kí tự cuối cùng phải là NULL hoặc 0 hoặc '\0'
các chuỗi nằm trong cặp ngoặc kép như
char *p =
"dammage";
printf(
"this is sparta");
gọi là các chuỗi hằng, nó có kiểu ngầm định là const char [] nên bạn không thể lấy con trỏ thường mà trỏ tới nó được (như giải thích ở < 1 >)
const char *p =
"dammage";
nhưng viết như thế này thì được
char a[100] = "dammage";
char a[] = "dammage";
đối tượng cout của lớp ostream đã có quá tải toán tử <<, mà về hình thức thì quá tải toán tử cũng giống như hàm thôi, mà như hàm thì đã giải thích ở < 2 >, bởi vậy 3 cái dưới đây là như nhau
cout << str << p_str << &str[0];