Tại sao const char * không cần con trỏ đến địa chỉ bộ nhớ?


18

Đây có thể là câu hỏi đơn giản, nhưng tại sao const char * không cần địa chỉ bộ nhớ để trỏ đến?

Thí dụ:

const char* a = "Anthony";

và không:

const char *a = // Address to const char

như bất kỳ loại khác làm gì?


8
Điều gì khiến bạn nghĩ rằng chuỗi ký tự không có địa chỉ bộ nhớ?
dùng207421

2
Đã đồng ý. Tôi sẽ không mong đợi bất cứ ai hỏi câu hỏi này thậm chí biết các loại giá trị tồn tại, chứ đừng nói rằng họ có tên.
dùng4581602

13
Xin đừng đặt câu hỏi được gắn thẻ C và C ++. Như chúng ta có thể quan sát, các câu trả lời hiện là C ++ cụ thể và các bình luận lại trật bánh về sự khác biệt giữa cả hai ngôn ngữ. Hiện tại có rất nhiều sự khác biệt đến nỗi thật khó để đặt một câu hỏi thực sự có cùng một câu trả lời hợp lệ cho cả hai ngôn ngữ. Quyết định ngôn ngữ bạn muốn sử dụng trước khi hỏi, xin vui lòng.
larkey

Câu trả lời:


26

Bạn có thể tưởng tượng tuyên bố này

const char* a = "Anthony";

cách sau

const char string_literal[] = "Anthony";

const char *a = string_literal;

Đó là trình biên dịch tạo ra một mảng các ký tự có thời lượng lưu trữ tĩnh lưu trữ chuỗi "Anthony"và địa chỉ của ký tự đầu tiên của mảng (do chuyển đổi ngầm định của các trình chỉ định mảng thành các con trỏ thành các ký tự đầu tiên của chúng) được gán cho con trỏ a.

Dưới đây là một chương trình trình diễn cho thấy rằng chuỗi ký tự là các mảng ký tự.

#include <iostream>
#include <type_traits>

decltype( auto ) f()
{
    return ( "Anthony" );
}

template <size_t N>
void g( const char ( &s )[N] )
{
    std::cout << s << '\n';
}

int main() 
{
    decltype( auto ) r = f();

    std::cout << "The size of the referenced array is "
              << std::extent<std::remove_reference<decltype( r )>::type>::value
              << '\n';

    g( r );

    return 0;
}

Đầu ra của chương trình là

The size of the referenced array is 8
Anthony

Kích thước của chuỗi ký tự (của mảng lưu trữ chuỗi ký tự) bằng với 8vì chuỗi bao gồm cả ký tự 0 kết thúc ' \0'.

Trong chương trình trình diễn biểu thức

std::extent<std::remove_reference<decltype( r )>::type>::value

có thể được thay thế cho chỉ biểu thức

sizeof( r )

5

Tại sao một const char không cần một địa chỉ bộ nhớ để trỏ đến? *

Nó làm.

Một chuỗi chữ C giống như

"Anthony"

được phân rã đến địa chỉ của ký tự thứ 1 của nó . Thích, BTW; bất kỳ mảng nào trong C không.


Cụ thể hơn, nó thuộc loại const char[8](trong C ++, có thể char [8]bằng C, không chắc chắn) và giống như tất cả các mảng tích hợp, khi sử dụng nó làm giá trị, nó phân rã thành một con trỏ đến phần tử đầu tiên của nó.
Nikos C.

@NikosC.: Cảm ơn đã nhắc nhở tôi về động từ ma thuật quan trọng nhất trong bối cảnh này! ;)
kiềm

Cảm ơn câu trả lời! Tôi đã tự hỏi nó lấy bộ nhớ từ đâu.
Weidelix

1
Không thể nói cho C, nhưng tôi khá chắc chắn rằng C ++ không chỉ định nơi lưu trữ nghĩa đen. Vừa đi đào. Nếu có một quy tắc, nó sẽ bị chôn vùi ở một nơi nào đó kỳ lạ và cách xa bất kỳ đề cập nào về "chuỗi ký tự".
dùng4581602

2
@NikosC. char [8]trong C: c-faq.com/ansi/strlitnotconst.html
David Ranieri

1

Nó cần một địa chỉ bộ nhớ và nó có một địa chỉ bộ nhớ. Trong ví dụ của bạn, nó chỉ đơn giản là địa chỉ bộ nhớ ở đầu chuỗi. Nó giống với bất kỳ biến mảng nào khác được khởi tạo tại thời gian biên dịch, ví dụ "int mảng [] = {0, 1, 2, 3};".

Nếu bạn đã sử dụng trình soạn thảo nhị phân để xem tệp thực thi, bạn sẽ thấy chuỗi "Anthony" trong đó. Nếu bạn đặt dòng "printf (" a ở mức% p \ n ", (void *) a);" trong chương trình của bạn, sau đó biên dịch và chạy nó, bạn sẽ thấy địa chỉ.


0

"Tại sao const char*không cần một con trỏ đến một địa chỉ bộ nhớ?"

Trong thực tế, nó không cần một địa chỉ bộ nhớ để trỏ đến.

const char* acó nghĩa alà một con trỏ đến một chuỗi ký tự hoặc hằng ký tự.

Một con trỏ luôn yêu cầu một địa chỉ để trỏ tới vì đó là bản chất của một con trỏ để trỏ đến một đối tượng cụ thể trong bộ nhớ. Vì vậy, avà bất kỳ con trỏ khác để const charlàm quá.

Một chuỗi ký tự giống như "Hi My Name is Alfred!"bởi một bài tập như:

const char* a;
a = "Hi My Name is Alfred!";

phân rã thành một con trỏ tới địa chỉ của phần tử đầu tiên của chuỗi ký tự.

Có nghĩa là lần lượt, ađược gán bởi địa chỉ của phần tử đầu tiên của chuỗi ký tự "Hi My Name is Alfred!"có thể được lưu trữ ở bất cứ đâu trong bộ nhớ phụ thuộc vào môi trường thực thi.

Nó không nằm trong khả năng của một lập trình viên nơi một chuỗi ký tự được lưu trữ chính xác. Nhiệm vụ của bạn chỉ là gán và xử lý con trỏ tương ứng một cách thích hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.