Це може бути простим питанням, але чому для const char * не потрібна адреса пам'яті, на яку слід вказувати?
Приклад:
const char* a = "Anthony";
і ні:
const char *a = // Address to const char
як і будь-які інші типи?
Це може бути простим питанням, але чому для const char * не потрібна адреса пам'яті, на яку слід вказувати?
Приклад:
const char* a = "Anthony";
і ні:
const char *a = // Address to const char
як і будь-які інші типи?
Відповіді:
Ви можете уявити цю декларацію
const char* a = "Anthony";
наступним чином
const char string_literal[] = "Anthony";
const char *a = string_literal;
Тобто компілятор створює масив символів зі статичною тривалістю зберігання, який зберігає рядок, "Anthony"
а адреса першого символу масиву (через неявне перетворення позначень масивів у вказівники до їх перших символів) присвоюється покажчику a
.
Ось демонстративна програма, яка показує, що рядкові літерали - це масиви символів.
#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;
}
Вихід програми є
The size of the referenced array is 8
Anthony
Розмір рядкового літералу (масиву, який зберігає літеральний рядок), дорівнює 8
тому, що рядок містить також символ завершення нульового символу ' \0'
.
У демонстративній програмі вираз
std::extent<std::remove_reference<decltype( r )>::type>::value
може бути заміщений лише виразом
sizeof( r )
Чому символу const не потрібна адреса пам'яті, на яку слід вказувати? *
Це робить.
Буквал типу C-string
"Anthony"
загасає на адресу його 1 - го символу. Мовляв, BTW; будь-який масив в C робить.
const char[8]
(в C ++, може бути char [8]
в C, не впевнений) і, як і всі вбудовані масиви, коли він використовує його як значення, воно схиляється до вказівника на його перший елемент.
char [8]
в C: c-faq.com/ansi/strlitnotconst.html
Для цього потрібна адреса пам'яті, і вона має адресу пам'яті. У вашому прикладі це просто адреса пам'яті початку рядка. Це те ж саме з будь-якою іншою змінною масиву, ініціалізованою під час компіляції, наприклад, "int array [] = {0, 1, 2, 3};".
Якщо ви використовували двійковий редактор для перегляду виконуваного файлу, ви побачите рядок "Ентоні" там. Якщо ви помістите рядок "printf (" a знаходиться у% p \ n ", (void *) a);" у вашій програмі, потім компілюйте та запустіть її, ви побачите адресу.
"Чому
const char*
не потрібен вказівник на адресу пам'яті?"
Насправді, йому потрібна адреса пам'яті, на яку слід вказати.
const char* a
означає a
- вказівник на рядкову літеральну чи константу символів.
Вказівник завжди вимагає адреси, на яку слід вказувати, тому що це природа вказівника, щоб вказати на певний об'єкт у пам'яті. Отже, a
і будь-який інший покажчик наconst char
робить.
Рядок з літерами "Hi My Name is Alfred!"
на зразок:
const char* a;
a = "Hi My Name is Alfred!";
розпадається на покажчик на адресу першого елемента літерального рядка.
Значить, в свою чергу, a
присвоюється адресою першого елемента літерального рядка, "Hi My Name is Alfred!"
який може зберігатися в будь-якому місці пам'яті, залежно від середовища виконання.
Це не в силах програміста, де точно зберігається літеральний рядок. Ваше завдання полягає лише в призначенні та обробці відповідного вказівника відповідним чином.