2009-11-27 46 views
17

Câu hỏi cơ bản.Sự khác biệt giữa việc sử dụng con trỏ ký tự và mảng ký tự

char new_str[]=""; 

char * newstr; 

Nếu tôi phải nối một số dữ liệu vào nó hoặc sử dụng chức năng chuỗi như strcat/substr/strcpy, sự khác biệt giữa hai là gì?

Tôi hiểu rằng tôi phải cấp phát bộ nhớ cho phương pháp char * (Dòng # 2). Tôi không thực sự chắc chắn như thế nào mặc dù.

Và const char * và chuỗi literals là như nhau?

Tôi cần biết thêm về điều này. Ai đó có thể trỏ đến một số nội dung/tài liệu đầy đủ hay không?

+1

Hãy xem hướng dẫn tuyệt vời này http://pw2.netcom.com/~tjensen/ptr/cpoint.htm – jyz

Trả lời

7

Hãy đi qua this article dưới đây:

Cũng xem trong trường hợp mảng của char như trong trường hợp của bạn, char new_str [] thì new_str sẽ luôn trỏ đến cơ sở của mảng. Con trỏ trong chính nó không thể được tăng lên. Có, bạn có thể sử dụng subscripts để truy cập char kế tiếp trong mảng ví dụ: new_str[3];

Nhưng trong trường hợp con trỏ tới char, con trỏ có thể được tăng thêm new_str++ để tìm nạp bạn ký tự tiếp theo trong mảng.

Ngoài ra tôi sẽ đề xuất this article để rõ ràng hơn.

2

Sự khác biệt là một là một con trỏ, cái kia là một mảng. Bạn có thể, ví dụ, mảng sizeof(). Bạn có thể quan tâm đến việc xem trộm here

1

Loại đầu tiên là char [1], thứ hai là char *. Các loại khác nhau.

Phân bổ bộ nhớ cho sau bằng malloc trong C hoặc new bằng C++.

char foo[] = "Bar"; // Allocates 4 bytes and fills them with 
        // 'B', 'a', 'r', '\0'. 

Kích thước ở đây được ngụ ý từ chuỗi khởi tạo.

Nội dung của foo có thể thay đổi. Bạn có thể thay đổi foo[i] ví dụ: i = 0..3.

OTOH nếu bạn làm:

char *foo = "Bar"; 

Trình biên dịch tại phân bổ một chuỗi tĩnh "Bar" trong bộ nhớ chỉ đọc và không thể được sửa đổi.

foo[i] = 'X'; // is now undefined. 
+0

Hmm. Nah. foo không thể thay đổi được. Bạn không thể thay đổi foo. Bạn có thể thay đổi các phần tử của foo, vâng, nhưng bạn không thể thay đổi foo thành bar, ví dụ, nếu thanh cũng là mảng char. –

+0

Đủ công bằng, ông Nitpicker. –

-2

Nếu bạn ở trong C++ tại sao không sử dụng std::string cho tất cả các chuỗi của bạn cần? Đặc biệt là bất cứ điều gì đối phó với nối. Điều này sẽ giúp bạn tiết kiệm từ rất nhiều vấn đề.

1

Nếu bạn đang sử dụng C++ như thẻ của bạn cho biết, bạn thực sự nên sử dụng các chuỗi C++, không phải là C char mảng.

Loại string làm cho thao tác chuỗi trở nên dễ dàng hơn nhiều.

Nếu bạn đang mắc kẹt với char mảng đối với một số lý do, dòng:

char new_str[] = ""; 

phân bổ 1 byte của không gian và đưa một nhân vật terminator rỗng vào nó. Điểm khác biệt của nó khác với:

char *new_str = ""; 

vì điều đó có thể cung cấp cho bạn tham chiếu tới bộ nhớ không thể ghi. Bản sao kê:

char *new_str; 

tự cung cấp cho bạn một con trỏ nhưng không có gì trỏ đến. Nó cũng có thể có một giá trị ngẫu nhiên nếu nó là cục bộ cho một hàm.

Những gì mọi người có xu hướng làm (trong C chứ không phải C++) là để làm một cái gì đó như:

char *new_str = malloc (100); // (remember that this has to be freed) or 
char new_str[100]; 

để có đủ không gian.

Nếu bạn sử dụng các hàm str..., về cơ bản bạn chịu trách nhiệm đảm bảo rằng bạn có đủ không gian trong mảng char, vì sợ rằng bạn sẽ có tất cả các loại thực hành kỳ lạ và tuyệt vời khi gỡ lỗi mã. Nếu bạn sử dụng các chuỗi C++ thực, rất nhiều công việc grunt được thực hiện cho bạn.

5

Đây là một mảng ký tự:

char buf [1000]; 

Vì vậy, ví dụ, điều này làm cho không có ý nghĩa:

buf = &some_other_buf; 

này được vì buf, mặc dù nó có những đặc điểm của kiểu con trỏ, nó đã chỉ đến nơi duy nhất có ý nghĩa đối với nó.

char *ptr; 

Mặt khác, ptr chỉ là con trỏ và có thể trỏ đến đâu đó. Thông thường, đó là một cái gì đó như thế này:

ptr = buf;    // #1: point to the beginning of buf, same as &buf[0] 

hoặc có lẽ đây:

ptr = malloc (1000); // #2: allocate heap and point to it 

hay:

ptr = "abcdefghijklmn"; // #3: string constant 

Đối với tất cả trong số này, * ptr có thể được ghi vào-trừ thứ ba trường hợp một số môi trường biên dịch xác định các hằng số chuỗi để không thể đọc được.

*ptr++ = 'h';   // writes into #1: buf[0], #2: first byte of heap, or 
         //    #3 overwrites "a" 
strcpy (ptr, "ello"); // finishes writing hello and adds a NUL 
8

Nguồn tuyệt vời để làm sáng tỏ sự nhầm lẫn là Peter Van der Linden, Chuyên gia lập trình C, bí mật sâu C - mảng và con trỏ không giống như cách chúng được giải quyết trong bộ nhớ.

Với một mảng,

char new_str[];
trình biên dịch đã cung cấp cho new_str một địa chỉ bộ nhớ được biết ở cả trình biên dịch và thời gian chạy, ví dụ: 0x1234, do đó việc lập chỉ mục của new_str là đơn giản bằng cách sử dụng []. Ví dụ: new_str[4], khi chạy, mã sẽ chọn địa chỉ của nơi new_str nằm trong, ví dụ: 0x1234 (đó là địa chỉ trong bộ nhớ vật lý).bằng cách thêm chỉ số chỉ số [4] vào nó, 0x1234 + 0x4, giá trị có thể được truy lục.

Trong khi đó, với con trỏ, trình biên dịch cung cấp cho biểu tượng

char *newstr
một địa chỉ, ví dụ: 0x9876, nhưng vào thời gian chạy, địa chỉ đó được sử dụng, là một lược đồ địa chỉ gián tiếp. Giả sử rằng newstr là malloc'd
newstr = malloc(10);
, những gì đang xảy ra là, mỗi khi một tham chiếu trong mã được thực hiện để sử dụng newstr, vì địa chỉ của newstr được biết đến bởi trình biên dịch tức là 0x9876, nhưng newstr trỏ đến biến là gì. Khi chạy, mã tìm nạp dữ liệu từ bộ nhớ vật lý 0x9876 (tức là newstr), nhưng tại địa chỉ đó, một địa chỉ bộ nhớ khác (vì chúng ta malloc'd nó), ví dụ 0x8765 nó ở đây, mã lấy dữ liệu từ địa chỉ bộ nhớ đó malloc được gán cho newstr, tức là 0x8765.

Các char new_str[]char *newstr được sử dụng thay thế cho nhau, vì một số yếu tố 0 của mảng phân rã thành một con trỏ và giải thích lý do tại sao bạn có thể newstr[5] hay *(newstr + 5) Thông báo như thế nào biểu hiện con trỏ được sử dụng mặc dù chúng tôi đã tuyên bố char *newstr, do đó

*(new_str + 1) = *newstr;
HOẶC
*(new_str + 1) = newstr[1];

Tóm lại, sự khác biệt thực sự giữa hai cách là cách chúng được truy cập trong bộ nhớ.

Tải sách, đọc và sống và hít thở. Đó là một cuốn sách tuyệt vời! :)

+2

Lưu ý: C được ghi chú có biểu thức giao hoán, ví dụ 4 + 3 giống như 3 + 4. Điều này cũng đúng trong con trỏ, * (new_str + 1) giống như * (1 + new_str) tình cờ là 1 [new_str]. Đó là một trò đùa và được tham chiếu ở nơi khác trên mạng, có lẽ để ném ai đó đi. CNTT hiếm khi được sử dụng trong sản xuất, vẫn chưa thấy nó ở đâu đó! – t0mm13b

0
char new_str[]="abcd"; 

Điều này chỉ định một mảng các ký tự (một chuỗi) có kích thước 5 byte (một byte cho mỗi ký tự cộng một cho dấu ngắt). Vì vậy, nó lưu trữ chuỗi 'abcd' trong bộ nhớ và chúng ta có thể truy cập chuỗi này bằng cách sử dụng biến new_str.

char *new_str="abcd"; 

Điều này chỉ định chuỗi 'abcd' được lưu ở đâu đó trong bộ nhớ và con trỏ new_str trỏ đến ký tự đầu tiên của chuỗi đó.

0

Để phân biệt họ ở phía bên cấp phát bộ nhớ:

// With char array, "hello" is allocated on stack 
char s[] = "hello"; 

// With char pointer, "hello" is stored in the read-only data segment in C++'s memory layout. 
char *s = "hello"; 

// To allocate a string on heap, malloc 6 bytes, due to a NUL byte in the end 
char *s = malloc(6); 
s = "hello"; 
Các vấn đề liên quan