Ответ 1
Из man 1 strings
(внимание мое):
Для каждого указанного файла строки GNU печатают печатный символ последовательности длиной не менее 4 символов (или число, указанное с вариантами ниже), и за ними следует непечатаемый символ. По умолчанию он только печатает строки из инициализированных и загруженные разделы объектных файлов; для других типов файлов он печатает строки из всего файла.
Язык C не определяет строки как первоклассные граждане. Они выражаются как строковые массивы, так и струнные литералы. Например, в такой базовой программе:
#include <stdio.h>
int main(void)
{
char s[] = "my string";
printf("%s\n", s);
return 0;
}
мы можем разумно сказать, что массив s
содержит строку. Обратите внимание, что это выделено в стеке. Он имеет автоматическую продолжительность хранения, в отличие от примера в вашем вопросе, где s
четко определяется вне main
(и любой) функции.
Теперь, опираясь на ваш вопрос, оба основных объекта в ваших двух программах имеют одни и те же характеристики:
- они имеют тип
char[6]
и имеют одинаковое содержимое (C11 §6.2.5/p20), - у них статическая продолжительность хранения, что означает, что они должны быть инициализированы концептуально до выполнения программы (C11 §5.1.2/p1).
Единственное отличие состоит в том, что modyfing строковый литерал вызывает undefined behaviur, поэтому компилятор может захотеть поместить их в отдельную ячейку памяти (например, только для чтения).
C11 §6.2.5/p20 Типы:
Тип массива описывает смежно выделенный непустой набор объекты с определенным типом объекта-члена, называемые типом элемента.
C11 §5.1.2/p1 Условия выполнения:
Все объекты со статическим временем хранения должны быть инициализированы (установлено значение их начальные значения) до запуска программы.
Если смотреть на более практичную точку зрения, помимо этой команды strings
вы также можете анализировать свои программы с помощью отладчика gdb
, более конкретно, используя команду x/s
. Вот основная иллюстрация:
$ gcc -g hello.c -o hello
$ gdb -q hello
Reading symbols from /home/grzegorz/hello...done.
(gdb) disas /m main
Dump of assembler code for function main:
6 {
0x00000000004004c4 <+0>: push %rbp
0x00000000004004c5 <+1>: mov %rsp,%rbp
7 printf("%s\n", s);
0x00000000004004c8 <+4>: mov $0x60086c,%edi
0x00000000004004cd <+9>: callq 0x4003b8 <[email protected]>
8 }
0x00000000004004d2 <+14>: leaveq
0x00000000004004d3 <+15>: retq
End of assembler dump.
(gdb) x/s 0x60086c
0x60086c <s>: "hello"
Вам может потребоваться сравнить результаты команды disas
для ваших программ и посмотреть, есть ли какое-то несоответствие между ними.