Массивы символов против указателей символов относительно размера - PullRequest
0 голосов
/ 08 июля 2019

Цитата из статьи, которую я прочитал:

* ... Рассмотрим следующие две переменные:

char s6[ ] = "hello", *s7 = "hello";

s6 выделяет место ровно для 6 байтов;s7 выделяет место для 10 (обычно) - 6 для символов плюс еще 4 для переменной указателя. *

Интересно узнать, кому принадлежит адрес s6 (первого символа в массиве)?И как s6 'сохраняет' 4 байта для указателя?

Ответы [ 3 ]

4 голосов
/ 08 июля 2019

Проще говоря, он не хранится нигде в вашей программе. Только компилятор отслеживает это.

Под капотом:

  • s6 означает «адрес XXXXXXXX: блок из шести байтов, содержащий значения 'H', 'e', 'l', 'l', 'o', 0»
  • s7 означает «адрес ГГГГГГГ: блок из четырех байтов, содержащий значения ZZ, ZZ, ZZ, ZZ»
  • *s7 означает «адрес ZZZZZZZZ: блок из одного байта, содержащий значение 'H'»

Программа фактически не должна хранить значение XXXXXXXX где-либо; компилятор просто вставляет значение XXXXXXXX в любое место, где вы используете s6.

Аналогично, программе не нужно нигде хранить YYYYYYYY, но она хранит для сохранения ZZZZZZZZ, потому что вы специально это сказали (вы сказали присвоить значение ZZZZZZZZ переменной s7).

Если вы хотите где-то хранить XXXXXXXX, вы можете легко сделать это:

char my_pointer* = &s6;

Теперь my_pointer означает «адрес WWWWWWWW: блок из четырех байтов, содержащий значения XX, XX, XX, XX».

P.S. Это предполагает, что вы находитесь в системе с четырехбайтовыми указателями; в настоящее время более вероятно, что указатель составляет восемь байтов или 64 бита.

3 голосов
/ 08 июля 2019

s6 выделяет место ровно для 6 байтов;s7 выделяет пространство для 10 (обычно) - 6 для символов плюс еще 4 для переменной указателя.

Нет, это не правильно.

s6 имеет пробелровно для 6 байтов s7 имеет пространство (размер) от указателя (обычно 4 или 8 байтов, в зависимости от вашей архитектуры) и указывает на строку, используемую для его инициализации.

Другими словами

  • размер s6 равен sizeof ("hello").
  • размер s7 равен sizeof (s7), т. Е. sizeof (char *)

Вы можете выполнить следующую программу, чтобы проверить размеры:

#include  <stdio.h>

int main(void)
{
    char s6[ ] = "hello", *s7 = "hello";

    printf("s6 = %zu\n", sizeof (s6));
    printf("s7 = %zu\n", sizeof (s7));

    return 0;
}

В моей системе они дают:

s6 = 6 // sizeof ("hello"), или,sizeof (char [6])

s7 = 8 // sizeof (char *)

2 голосов
/ 08 июля 2019

Интересно, кто владеет адресом s6 (первого символа в массив)? И как s6 «сохраняет» 4 байта для указателя?

Компилятор / компоновщик содержит этот адрес. Он рассматривается как константа, потому что он не может быть изменен во время выполнения. Надеюсь, это поможет.

...