Так много ответов уже сказал вам использовать char str1[25];
вместо int str1[25]
, но никто не объяснил, почему. Так вот:
A char
имеет длину одного байта (по определению в стандарте C). Но int
использует больше байтов (сколько зависит от архитектуры и компилятора, давайте предположим здесь 4). Так, если доступ индекса 2 в char
массива, вы получаете 1 байт в памяти смещения 2, но если доступ к индексу 2 из int
массива, вы получаете 4 байта в памяти смещения 8.
При вызове gets
(который следует избегать, поскольку он неограничен и, следовательно, может переполнить ваш массив), строка копируется по адресу str1
. Эта строка действительно представляет собой массив из char
. Таким образом, для отображения строки будет 123
плюс завершение нулевого символа. Память будет выглядеть следующим образом:
Adress: 0 1 2 3
Content: 0x31 0x32 0x33 0x00
Когда вы читаете str1[0]
вы получаете 4 байта на один раз, так str1[0]
не возвращается 0x31, вы получите либо 0x00333231 (прямой порядок байт) или 0x31323300 (большие обратный порядок байт).
Доступ к str1[1]
уже за пределами строки.
Теперь, почему вы получаете длину строки 33? Это на самом деле случайное, и вам «повезло», что программа не сработала. На начальном адресе str1
вы получаете значения int
, пока не получите, наконец, четыре байта в строке. В вашей памяти есть какой-то случайный мусор, и по чистой случайности вы столкнулись с четырьмя 0 байтами после чтения 33 * 4 = 132 байта.
Здесь вы уже можете видеть, что оценки границ очень важны: ваш массив должен содержать 25 символов. Но gets
уже может писать дальше (решение: вместо этого используйте fgets
). Затем вы сканируете без ограничений и, таким образом, можете также получать доступ к памяти намного дальше вашего массива и, возможно, в конечном итоге можете работать в несуществующие области памяти (что приведет к сбою вашей программы). Решение для этого: делают проверки границ, например:
// "sizeof(str1)" only works correctly on real arrays here,
// not on "char *" or something!
int l;
for (l = 0; l < sizeof(str1); ++l) {
if (str1[l] == '\0') {
// End of string
break;
}
}
if (l == sizeof(str1)) {
// Did not find a null byte in array!
} else {
// l contains valid string length.
}
'main()' возвращает 'int', вы странно иметь' return 0; ', но объявляете его как' void'. – unwind
Здесь нет рекурсии, только итерация. – DarkDust