2012-04-10 45 views
17

Tôi muốn biết lý do tại sao các báo cáo công trình đầu tiên và tại sao không thứ hai trong C++Gán một chuỗi ký tự cho một mảng char

char a[10]="iqbal"; // it works 

a="iqbal"; // does not work 
+0

Đây có phải là C hoặc C++ không? Xin hãy chỉ ra cụ thể. –

+2

điều này xuất hiện dưới dạng ước lượng trực tiếp bởi giao diện SO. Vui lòng tìm kiếm trước khi đăng: có thể trùng lặp [Gán chuỗi thành các mảng ký tự] (http://stackoverflow.com/questions/579734/assigning-strings-to-arrays-of-characters) –

Trả lời

18

Nói đúng ra, một mảng không phải là một con trỏ! Và một mảng (địa chỉ cơ sở của mảng) không thể là một lvalue có thể sửa đổi được. tức là nó không thể xuất hiện ở phía bên tay trái của toán tử gán. Ngược lại, nó chỉ phân rã thành con trỏ trong một số trường hợp nhất định. Đọc bài này SO post để tìm hiểu khi nào mảng phân rã thành con trỏ. Dưới đây là một trong nhiều nice article điều này giải thích sự khác biệt giữa mảng và con trỏ

Cũng đọc về lvalues ​​và rvalues ​​here để bạn có được một ý tưởng về những thứ mà không thể xuất hiện trên LHS của =

char a [10 ] = "iqbal"; // nó hoạt động

Trong trường hợp này, trong nội bộ những gì xảy ra là

a[0] = 'i'; 
a[1] = 'q'; 
. 
. 
a[5] = '\0'; 

Vì vậy, mọi thứ đều tốt như array[i] là một giá trị trái sửa đổi.

a = "iqbal"; // không làm việc

Bên trong, đây là tương đương với

0x60000(Address of a, but is a simple number here) = Address of "iqbal" 

Đây là sai khi chúng ta không thể gán một cái gì đó cho một số.

+2

Thực ra, 'a' là một sửa đổi lvalue, nhưng không thể xuất hiện ở phía bên tay trái của toán tử gán. Ý nghĩa của l và r trong lvalue và rvalue đã bị mất từ ​​lâu. – avakar

+0

'a' có thể là một lvalue nhưng không phải là một _modifiable_ lvalue và _hence_ không thể xuất hiện trên LHS của' = '? Bạn có thể chỉ cho tôi một số tài liệu nếu tôi sai? Tôi sẽ theo [this] (http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc05lvalue.htm) –

+0

@PavanManjunath: Hãy xem xét truyền 'a' làm đối số thực tế cho một hàm có tham chiếu đến đối số chính thức mảng. Rõ ràng 'a' là một lvalue trong trường hợp này, và có thể sửa đổi được. Và lvalue hoặc rvalue-ness của một biểu thức không phụ thuộc vào ngữ cảnh, do đó 'a' là một giá trị có thể sửa đổi được. –

3

Dòng đầu tiên không phải là tuyên bố mà là khai báo có khởi tạo. Dòng thứ hai là một câu lệnh biểu thức với toán tử gán.

Bạn không thể gán mảng trong C.

Nhưng bạn có thể khởi tạo mảng bằng các thành phần của chuỗi ký tự.

4

Mảng char sẽ là tĩnh và không thể thay đổi nếu bạn khởi tạo nó như thế này. Dù sao bạn không bao giờ có thể gán một chuỗi ký tự a = "iqbal" trong c. Bạn phải sử dụng strncpy hoặc memcpy cho điều đó. Nếu không, bạn sẽ cố gắng ghi đè con trỏ vào chuỗi và đó không phải là thứ bạn muốn.

Vì vậy, các mã chính xác sẽ làm điều gì đó như:

char a[10]; 
strncpy(a, "iqbal", sizeof(a) - 1); 
a[sizeof(a) - 1] = 0; 

Các -1 là để dự trữ một byte cho chấm dứt zero. Lưu ý, bạn sẽ phải tự kiểm tra xem chuỗi có bị hủy hay không. Bad api. Có một cuộc gọi strlcpy() thực hiện điều này cho bạn nhưng nó không được bao gồm trong glibc.

0

Khi viết char a [10] = "iqbal" Bạn đang khởi tạo các phần tử của mảng nhân vật một với các nhân vật. Chúng tôi có thể làm tương tự với int loại (lưu ý rằng các loại char được điều trị hơi khác): int a [10] = {1,2, ...};

Nhưng việc viết phần sau đây sau khi khai báo sẽ không hợp lệ vì a sẽ được xử lý giống như con trỏ. Vì vậy, viết một cái gì đó như a = {1,2, ...}; hoặc a = "iqbal" sẽ không có ý nghĩa gì cả!

1

lý do tại sao các báo cáo đầu tiên hoạt động và lý do tại sao không phải là một thứ hai trong C++

Bởi vì họ là các câu lệnh khác nhau, gần như hoàn toàn không liên quan. Đừng nhầm lẫn với thực tế là cả hai đều sử dụng biểu tượng =. Trong một trường hợp, nó đại diện cho khởi tạo đối tượng. Trong trường hợp khác, toán tử gán.

Dòng đầu tiên của bạn là hợp pháp vì pháp lý là khởi tạo các tập hợp tổng hợp, bao gồm cả mảng ký tự.

Dòng thứ hai của bạn không hợp pháp bởi vì nó không hợp pháp để gán cho một mảng.

Vì đây là C++, tôi có thể đề nghị bạn tránh các mảng trần không? Đối với chuỗi ký tự, hãy sử dụng std::string. Đối với các mảng khác, hãy sử dụng std::vector. Nếu bạn làm thế, bạn dụ trở thành:

std::string a = "iqbal"; // it works 
a="iqbal"; // so does this 
0

thử:

char a[10]="iqbal"; 
char *my_a = a; 

và làm việc với my_a.

Các vấn đề liên quan