chúng ta có thể tạo mảng rồi nhận các giá trị "daksdhasf" vì nó copy từ sang bộ nhớ của mảng kí tự
chúng ta hoàn toàn có thể dùng con trỏ trỏ đến địa chỉ của mảng kí tự. nhưng không thể dùng con trỏ để trỏ đến hằng vì phải dùng const char* mới có thể trỏ đến
Ngoài cách khởi tạo mảng một chiều thông thường, C-style string còn có thể khởi tạo bằng một hằng chuỗi kí tự như sau:
char my_name[] = "Le Tran Dat";
Chuỗi kí tự "Le Tran Dat" được xem như là một chuỗi hằng kí tự, nó có địa chỉ cụ thể trên bộ nhớ ảo, nó được lưu trên bộ nhớ ảo, nhưng không có tên biến để truy xuất đến địa chỉ của chuỗi hằng kí tự này. Nhưng sau khi sử dụng chuỗi hằng kí tự "Le Tran Dat" để khởi tạo cho mảng my_name, mảng my_name không được khai báo là kiểu chuỗi hằng kí tự (const char []) nên các kí tự trong mảng my_name hoàn toàn có thể bị thay đổi.
Điều này chứng tỏ mảng my_name được cấp phát bộ nhớ tại địa chỉ khác chuỗi hằng kí tự "Le Tran Dat", việc khởi tạo mảng kí tự bằng một chuỗi hằng kí tự chỉ đơn giản là copy từng kí tự của chuỗi "Le Tran Dat" và đưa vào mảng.
Do đó, con trỏ kiểu char (char *) trỏ đến mảng my_name và trỏ đến vùng nhớ của chuỗi hằng kí tự "Le Tran Dat" là 2 trường hợp khác nhau.
hãy luôn nhớ rằng khi đưa mảng vào hàm có sẵn hàm của chúng ta thì nó sẽ suy biến thành 1 con trỏ ta có thể nói mảng là con trỏ khi nó được đưa vào hàm
mảng 2 chiều con trỏ
nhìn chung nó sẽ giống mảng 2 chiều nhưng nó được cái tối ưu bộ nhớ mà nó quản lý 
vd chúng cần lưu 12 tháng
january
february 
march 
april
may
june
july
august
september
october
november
december
nếu dùng mảng 2 chiều bình thường thì chúng ta phải cấp phát 12*tháng có độ dài kí tự lớn nhất nhưng nếu dùng con trỏ nó chỉ cấp phát khi chương trình chạy nên chúng ta có thể dựa theo từng tháng mà cấp phát đỡ tốn bộ nhớ
a[0] là 1 con trỏ kiểu char * nó chỉ cần trỏ đến cái chuỗi kia là dc
với lại nếu không cần làm thay đổi vùng nhớ thì cứ dùng con trỏ cho khỏe, vì bạn đã có sẵn vùng nhớ có lưu giá trị thì nó chỉ cần 4 byte là có thể quản lý vùng nhớ đó rồi
sự khác biệt giữa typedef struct và struct
Nếu ở C++ thì struct ~ typedef struct và khỏi cần typedef cũng đc.
Còn C thì giúp nó đỡ phải ghi thêm kw struct mỗi khi khai báo biến.
Như code mẫu C dưới bây bị lỗi
struct a {
int b; };
int main(void) { a c; // báo lỗi ở dòng này
return 0; }
Đúng phải là
struct a c;
Tuy nhiên ghi vậy dài quá, ngta dùng typedef giúp định nghĩa kiểu lại, từ đó ngắn hơn
typedef struct a {
int b; } a; //định nghĩa struct a thành a

int main(void) { a c; // không lỗi nữa
return 0; }
sự khác biệt giữa #define và typedef(# đại diện cho tiền xử lý)
#define là mã thông báo tiền xử lý: trình biên dịch sẽ không bao giờ nhìn thấy nó.
typedef là mã thông báo của trình biên dịch: bộ tiền xử lý không quan tâm đến nó.
typedef tuân theo quy tắc phạm vi giống như các biến, trong khi define vẫn có hiệu lực cho đến khi kết thúc tệp (hoặc cho đến khi khớp undef).
Ngoài ra, một số điều có thể được thực hiện với typedef không thể thực hiện được với define.
#define là tiền sử lý trong ngôn ngữ C/C++ cho phép bạn đặt tên cho một hằng số nguyên hay hằng số thực. Trước khi biên dịch, trình biên dịch sẽ thay thế những tên hằng bạn đang sử dụng bằng chính giá trị của chúng. Quá trình thay thế này được gọi là quá trình tiền biên dịch (pre-compile).
Ngôn ngữ chương trình C/C++ cung cấp một từ khóa typedef, mà bạn có thể sử dụng để cung cấp kiểu cho một tên mới.
  • typedef được giới hạn chỉ cung cấp các tên viết tắt cho các kiểu, trong khi đó #define có thể được sử dụng để định nghĩa tên hiệu cho cả các giá trị, như bạn có thể định nghĩa pi là 3.14, ….
  • Sự phiên dịch typedef được thực hiện bởi bộ biên dịch, trong khi lệnh #define được xử lý bởi bộ tiền xử lý.
  • #define đối với c còn c++ sử dụng const float