2013-04-10 38 views
5

Tại sao tôi không thể trỏ char ** vào mảng chuỗi C?char ** vs char * c [] để truy cập mảng chuỗi

int main(int argc, char *argv[]) { 

    char* c1[] = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //works fine 

vs

int main(int argc, char *argv[]) { 

    char** c1 = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //error 
+6

Con trỏ không phải là mảng. –

Trả lời

6

Tôi nghĩ sự nhầm lẫn ở đây xuất phát từ niềm tin rằng {"Hey","Hello"} là một mảng. Nó không phải. Nó không phải là một vật thể chút nào. Nó chỉ là một cú pháp khởi tạo đặc biệt có thể được sử dụng để khởi tạo một mảng. Bạn không thể sử dụng nó để khởi tạo một số char** vì một số char** là một con trỏ chứ không phải một mảng. Nó không tự động tạo một đối tượng mảng mà bạn có thể chuyển đổi thành một con trỏ.

Có lẽ bạn đang nghĩ về nó như một danh sách [...] bằng Python hoặc một đối tượng { ... } trong JavaScript. Nó không giống như tất cả. Những biểu thức này thực sự tạo ra các đối tượng thuộc loại đó và có thể được sử dụng ở bất kỳ đâu trong một biểu thức có thể lấy các đối tượng đó.Cú pháp mà chúng tôi đang sử dụng trong C++ là chỉ cú pháp khởi tạo.

Ví dụ, bạn thể làm điều này:

const char* array[] = {"Hey","Hello"}; 
const char** p = array; 

Bạn, tuy nhiên, không thể làm điều gì đó ngớ ngẩn như thế này:

std::cout << {"Hey", "Hello"}[1]; 

Ở đây chúng ta đã thực sự tạo ra các đối tượng mảng trong đó con trỏ sẽ được lưu trữ. Chỉ khi đó chúng ta mới có thể chuyển đổi mảng đó thành const char**.

+0

Rất rõ ràng..thanxxx – tez

1

Tại sao tôi không thể chỉ một char** đến mảng các chuỗi C?

Như bạn đã nói, c1 là một mảng. Vì vậy, bạn phải khai báo nó như là một mảng con trỏ đến char.

Kể từ "Hey""Hello"chuỗi litterals, mỗi c1[i] chuỗi là chỉ đến một chuỗi vô danh. Đó là lý do tại sao bạn có thể sử dụng con trỏ đến char thay vì mảng char.

Để tạo một mảng con trỏ đến char, tuy nhiên, bạn không thể sử dụng char **.

2

thay đổi

char** c1 = (char *[]){"Hey","Hello"};

0

"char ** c1", nói với trình biên dịch rằng nó là một con trỏ đến một con trỏ cho loại char, là loại vô hướng (một giá trị).

Việc khởi tạo với danh sách giá trị chỉ hoạt động cho các loại tổng hợp.

+0

Không có sự mơ hồ trong 'char ** c1'. Nó là một con trỏ trỏ đến một 'char'. (Tất nhiên, cả hai con trỏ ở trên có thể là phần tử đầu tiên của một mảng.) –

+0

@James Kanze, vâng, sai lầm của tôi. Xoá nó. – Arun

0
int main(int argc, char *argv[]) { 

    char** c1 = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //error 

Trong mã trên, bạn đang cố gắng đặt con trỏ trỏ đến một bộ gồm hai chuỗi. Nơi lưu trữ cho hai con trỏ có chứa địa chỉ của "Hey" và "Hello" tương ứng? Hư không.

Bạn có thể làm:

char *a = "Hey"; 
char *b = "Hello"; 
char *c[] = { a, b };  // This MAY not compile due to a and b not being compile time constants. 
char **c1 = c; 

(Tôi đã tách nó ra thành các biến cá nhân hơn nó thực sự cần, nhưng tôi nghĩ rằng nó giải thích những gì là "sai" với mã của bạn khá rõ ràng).

Một ví dụ khác là nếu chúng ta thay đổi char * để int:

const int a = 1; 
const int b = 2; 

int c[] = { a, b }; 

int *c = { a, b }; // Doesn't work, there is nowhere to store a copy of a and b. 

Đó là điều tương tự, ngoại trừ với số nguyên.