Попытка обернуть мою голову вокруг размеров строки в C - PullRequest
1 голос
/ 15 марта 2011

Мы с другом занимаемся программированием на C для колледжа.

Мы понимаем, что в C нет "строки" как таковой, и вместо этого строка определяется как массив символов.Круто!

Так что при работе со «строками» очевидно, что важно правильно понимать массивы и указатели.

Мы действительно хорошо понимали объявление указателя, когда и когда не нужно разыменовывать указательи поиграл с числом printf, чтобы проверить наши эксперименты.Все с большим успехом.

Однако, когда мы использовали это:

char *myvar = "";
myvar = "dhjfejfdhdkjfhdjkfhdjkfhdjfhdfhdjhdsjfkdhjdfhddskjdkljdklc";
printf("Size is %d\n", sizeof(myvar));

и оно выплевывает Size is 8!

Почему 8?Очевидно, что myvar потребляет более 8 байт (или это так)?

(Я должен быть ясен и указать, что я ОЧЕНЬ осведомлен о strlen. Это не упражнение в получениидлина строки. Это попытка понять, почему sizeof возвращает 8 байтов для переменной myvar.)

Ответы [ 4 ]

8 голосов
/ 15 марта 2011

8 - размер указателя.myvar - указатель на char (следовательно, char *), а в 64-битных системных указателях это 64-битный = 8 байт

Чтобы получить размер строки с нулевым символом в конце, используйте этот код:

#include<string.h>
#include<stdio.h>

int main()
{
char *x="hello there";
printf("%d\n",strlen(x));
return 0;
}
2 голосов
/ 15 марта 2011

Ну, как сказал AbiusX, причина, по которой sizeof возвращает 8, в том, что вы находите размер указателя (и я предполагаю, что вы работаете на 64-битной машине). Например, тот же фрагмент кода на моем компьютере вернул бы 4.

Строки в C хранятся в виде массива символов, за которым следует нулевой терминатор. Поэтому, когда вы делаете это ...

const char *message = "hello, world!"

На самом деле он хранится в памяти как:

'h''e''l''l''o'','' ''w''o''r''l''d''!''\0'...garbage here

Если вы прочтете за нулевым терминатором, вы, скорее всего, просто обнаружите, что в этот момент в памяти был какой-то мусор. Таким образом, чтобы найти длину строки в C, вам нужно начать с начала строки и читать до нулевого терминатора.

size_t count = 0;
const char *message = "hello, world!";
for ( ; message[count] != '\0'; count++ );
printf("size of message %u\n", count);

Теперь это операция O (n) (потому что вам нужно перебрать весь массив, чтобы получить размер). Большинство языков более высокого уровня имеют абстракцию строк верхнего уровня как нечто похожее на ...

struct string {
    char *c_str;
    size_t length;
};

И затем они просто отслеживают, какова длина строки, когда они выполняют над ней операцию. Это значительно ускоряет поиск длины строки, что является очень распространенной операцией.

Теперь есть один способ узнать длину строки, используя sizeof, но я не советую это делать. Использование sizeof в массиве (не указатель!) Вернет размер массива, умноженный на размер типа данных. И C может автоматически определять размер массива, если он может быть вычислен во время компиляции.

const char message[] = "hello, world!";
printf("size of message %u\n", sizeof(message));

Это напечатает правильный размер сообщения. Помните, это НЕ предлагается. Обратите внимание, что при этом будет напечатано число, превышающее количество символов в строке. Это потому, что он также считает нулевой терминатор (так как он должен выделить массив, достаточно большой, чтобы иметь нулевой терминатор). Так что это не совсем реальная длина строки (вы всегда можете просто вычесть одну).

0 голосов
/ 15 марта 2011

Как сказал AbiusX, 8 - это размер указателя.strlen может указать длину строки ( справочная страница ).

0 голосов
/ 15 марта 2011

myvar - указатель.Кажется, вы работаете на 64-битной машине, поэтому sizeof возвращает размер 8 байт.Вместо этого вы, вероятно, ищете strlen () .

...