Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Строки в C  (Прочитано 1718 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Olej

  • Забанен
  • Активист
  • *
  • Сообщений: 884
    • Просмотр профиля
Re: Строки в C
« Ответ #15 : 11 Апреля 2012, 12:11:51 »
Какая проблема с логикой? Ведь если объявить массивы без указания размера
char s1[] = "abcdefghijklmnopqrstuvwxyz";
char s2[] = "rs";
то все работает. Простой перебор. Ошибка именно с типами данных.

Ошибка к типам данных отношения никак не имеет, но ошибка - лихая ;), и она типа:
- ваши массивы - локальные, им для размещения выделяется место в стеке функции...
- порядок размещения по адресам - обратный порядку объявления в коде...
- вы ошибаетесь в размерностях ([2],[26]), и массив [26] своим началом ('a') затирает завершающий '\0' массива [2]...
- поэтому при выводе строки [2] вы выводите её, а потом безостановочно переходите на [26] и его прихватываете тоже.

Вот, очень примерно, так.
« Последнее редактирование: 11 Апреля 2012, 12:13:22 от Olej »

Оффлайн Jack Sparrow

  • Автор темы
  • Активист
  • *
  • Сообщений: 630
    • Просмотр профиля
Re: Строки в C
« Ответ #16 : 11 Апреля 2012, 12:44:46 »
Цитировать
При определении массива - число в квадратных скобочках - его размерность. А при использовании - индекс. Они на единицу отличаются.
Ну вот теперь на шаг ближе к пониманию.
А что я говорю, что ошибка не в логике программы, а в типах данных, так я и имею в виду, что ошибка с самими массивами, а не с тем, как они перебираются.
Просто я, при объявлении, ожидал, что они будут заканчиваться оба на '\0', на этом логика программы и построена, а оказывается не так. Ну и ошибка индекс/размер - разные вещи.
Linux is only free if your time has no value (c) Jamie Zawinski

Оффлайн Vovaldo

  • Любитель
  • *
  • Сообщений: 82
  • Ху Тин Пуй
    • Просмотр профиля
    • Путин забрал у Медведева инновационный орган
Re: Строки в C
« Ответ #17 : 11 Апреля 2012, 13:02:23 »
Просто я, при объявлении, ожидал, что они будут заканчиваться оба на '\0', на этом логика программы и построена, а оказывается не так.
А это так и есть, они бы оба на '\0' заканчивались, если бы размерность массивов была правильно указана. Кстати, наверняка вам компилятор насчёт размерности предупреждение выдавал при компиляции вашего примера.

Пользователь решил продолжить мысль 11 Апреля 2012, 13:05:20:
Ну и ошибка индекс/размер - разные вещи.
А это уже традиции американских математиков - вести отсчёт с нуля, а не с единицы. :) Ну и принцип организации массивов в С тоже сказывается. :)
« Последнее редактирование: 11 Апреля 2012, 13:23:29 от Vovaldo »

Оффлайн qupl

  • Активист
  • *
  • Сообщений: 286
  • и тебя забанят, и меня забанят
    • Просмотр профиля
Re: Строки в C
« Ответ #18 : 11 Апреля 2012, 13:31:41 »
Ну вот теперь на шаг ближе к пониманию.
А что я говорю, что ошибка не в логике программы, а в типах данных, так я и имею в виду, что ошибка с самими массивами, а не с тем, как они перебираются.
Просто я, при объявлении, ожидал, что они будут заканчиваться оба на '\0', на этом логика программы и построена, а оказывается не так. Ну и ошибка индекс/размер - разные вещи.
Ошибка и в том как перебираются тоже.
Код
char s1[26] = "abcdefghijklmnopqrstuvwxyz";
char s2[2] = "rs";
сам по себе, как объявление, верный.
А перебор с ожиданием '\0' в конце строки в этом случае неверен.
for (i = 0; s1[i] != '\0'; i++)Просто при таком объявлении массивов нужно перемещаться только по корректным индексам массива, никаких автоматических '\0' в конце массива не появится. Либо в инициализации указать последним символом '\0', например так :
char s1[27] = "abcdefghijklmnopqrstuvwxyz\0";
char s2[3] = "rs\0";


Пользователь решил продолжить мысль 11 Апреля 2012, 13:35:04:
Вообще, ожидать какие-то определенные данные в еще нераспределенной куче - верх наивности. Там могут быть нули, а может быть мусор.
« Последнее редактирование: 11 Апреля 2012, 13:35:04 от qupl »
Муха (ё).
Муха - это насекомое. А "ё" - это буква, кому не хватает ее на клавиатуре.

Оффлайн Vovaldo

  • Любитель
  • *
  • Сообщений: 82
  • Ху Тин Пуй
    • Просмотр профиля
    • Путин забрал у Медведева инновационный орган
Re: Строки в C
« Ответ #19 : 11 Апреля 2012, 14:21:21 »
Просто при таком объявлении массивов нужно перемещаться только по корректным индексам массива, никаких автоматических '\0' в конце массива не появится.
Да ладно сочинять-то. ;D
Даже у топикстартера в первом посте появились, когда он правильно размерность задал. ;-)
Цитировать
Либо в инициализации указать последним символом '\0', например так :
char s1[27] = "abcdefghijklmnopqrstuvwxyz\0";
char s2[3] = "rs\0";
Посмотри в документации или в учебнике по С раздел про строковые константы - '\0' в конце добавляется автоматически.
« Последнее редактирование: 11 Апреля 2012, 14:48:43 от Vovaldo »

Оффлайн Olej

  • Забанен
  • Активист
  • *
  • Сообщений: 884
    • Просмотр профиля
Re: Строки в C
« Ответ #20 : 11 Апреля 2012, 14:55:57 »
Посмотри в документации или в учебнике по С раздел про строковые константы - '\0' в конце добавляется автоматически.
- только если явно указанная размерность массива соответствует длине или больше длины инициализиующей строки.

(Никто никуда никакой '\0', конечно, не "добавляет" - просто этот '\0' в конце уже записан в вашей инициализирующей строке - константе.) 

Разговор то выеденного яйца не стоит ... но вы можете всё сами проверить и убедиться, наберите вот так, скомпилируйте и выполните (не сильно вникайте в то, что написано):
#include <stdio.h>

char s1[] = "abcdefghijklmnopqrstuvwxyz";
char s2[10] = "abcdefghijklmnopqrstuvwxyz";
char s3[40] = "abcdefghijklmnopqrstuvwxyz";

#define show(x) \
printf( "%d : ", sizeof( x ) ); \
{ int i; for( i = 0; i < sizeof( x ); i++ ) printf( " %d", (int)x[ i ] ); } \
printf( "\n" );

int main( void ) {
   show( s1 );
   show( s2 );
   show( s3 );
   return 0;
}
Я для вас даже проверил:
[olej@notebook _TEMP]$ ./ascii2
27 :  97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 0
10 :  97 98 99 100 101 102 103 104 105 106
40 :  97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Что ж может быть понятнее и проще?

Оффлайн Vovaldo

  • Любитель
  • *
  • Сообщений: 82
  • Ху Тин Пуй
    • Просмотр профиля
    • Путин забрал у Медведева инновационный орган
Re: Строки в C
« Ответ #21 : 11 Апреля 2012, 21:40:11 »
Посмотри в документации или в учебнике по С раздел про строковые константы - '\0' в конце добавляется автоматически.
- только если явно указанная размерность массива соответствует длине или больше длины инициализиующей строки.
Уважаемый "прохвессор", вы вообще о чём? Какие массивы? Перечитайте внимательно то, что вы процитировали.

Цитировать
(Никто никуда никакой '\0', конечно, не "добавляет" - просто этот '\0' в конце уже записан в вашей инициализирующей строке - константе.)
Ну и кто же "записал" этот самый '\0' в конце инициализирующей строки-константы? Если некоторые товарищи в конце каждой константной строки самостоятельно всегда дописывает '\0' - это исключительно их проблемы.

Цитировать
Разговор то выеденного яйца не стоит ... но вы можете всё сами проверить и убедиться, наберите вот так, скомпилируйте и выполните (не сильно вникайте в то, что написано):
А вот вникать-то иногда бы надо, особенно, в выдаваемые предупреждения. Об этом, собственно, несколькими сообщениями раньше уже говорилось.

Цитировать
Что ж может быть понятнее и проще?
Да вот так и оказывается, что на самом деле не так уж понятно и просто. :P

Оффлайн Olej

  • Забанен
  • Активист
  • *
  • Сообщений: 884
    • Просмотр профиля
Re: Строки в C
« Ответ #22 : 11 Апреля 2012, 22:50:52 »
Посмотри в документации или в учебнике по С раздел про строковые константы - '\0' в конце добавляется автоматически.
- только если явно указанная размерность массива соответствует длине или больше длины инициализиующей строки.
Уважаемый "прохвессор", вы вообще о чём? Какие массивы? Перечитайте внимательно то, что вы процитировали.

А может вы сначала дочитаете до конца Букварь K&R?
... а потом станете рассуждать? ;)


Пользователь решил продолжить мысль 11 Апреля 2012, 23:02:56:
Цитировать
(Никто никуда никакой '\0', конечно, не "добавляет" - просто этот '\0' в конце уже записан в вашей инициализирующей строке - константе.)
Ну и кто же "записал" этот самый '\0' в конце инициализирующей строки-константы? Если некоторые товарищи в конце каждой константной строки самостоятельно всегда дописывает '\0' - это исключительно их проблемы.

Толкую для ... "самых-самых из танка":

- когда в любом месте программного кода С (это может быть инициализация, как у вас, параметром в printf(), в любых функциях вида str*() - в любом контексте) появляется запись вида: "abcdefghijklmnopqrstuvwxyz" - то она представляет собой литеральную константу длины 27, с '\0' записанным последним 27-м байтом, хотя вы в записи и указали 26 знаков...

- и вот это представление того, что нужно занести (в инициализируемую переменную), вместе со своим завершающим '\0', и является значением, которое копируется в вашу переменную включая и завершающий '\0';

- и как бы вы не записывали литеральные константы, и что бы вы туда внутрь не записывали, у вас нет никакого способа предотвратить дополнение записанного вами литеральным нулём: как только вы записали где-то "XYZ", вы записали массив с элементами 'X', 'Y', 'Z', '\0'.

Вот так я внятно излагаю? ;)


Пользователь решил продолжить мысль 11 Апреля 2012, 23:10:40:
Посмотри в документации или в учебнике по С раздел про строковые константы - '\0' в конце добавляется автоматически.
- только если явно указанная размерность массива соответствует длине или больше длины инициализиующей строки.
Уважаемый "прохвессор", вы вообще о чём? Какие массивы? Перечитайте внимательно то, что вы процитировали.

О-ба-на ;)
Я вообще то предполагал, что ... к окончанию среднеобразовательной школы все её выпускники (кто датянул до окончания) знают, что в С существует единственный способ представления символьных строк: это массив, массив байт если это старое char представление, массив многобайтных символов, если это mbchar (UTF-8) или wchar (UTF-32) ... но это всегда - массив.

Мне по простоте душевной как-то не представлялось, что в раздел "Программирование" заходят индивидуумы, которые ещё до этого места не дочитали K&R.
Прошу прощения за напряг.
 

Пользователь решил продолжить мысль 11 Апреля 2012, 23:29:00:
Толкую для ... "самых-самых из танка":

Я тут в помощь "танкистам" написал иллюстрирующую программку - сильно просветляет: чем размер массива, содержащего литеральную строку, отличается от длины строки (а отличается он ровно на 1). Впишите для значения STROKA любую приятную вам строку:
#include <stdio.h>
#include <string.h>

#define STROKA "1234"

int main( void ) {
   printf( "%d - %d\n", sizeof( STROKA ), strlen( STROKA ) );
   return 0;
}
... и наслаждайтесь:
$ gcc ascii3.c -o ascii3
$ ./ascii3
5 - 4
« Последнее редактирование: 11 Апреля 2012, 23:29:00 от Olej »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Строки в C
« Ответ #23 : 12 Апреля 2012, 05:58:27 »
Свой устав сам напрашивается, т.к. тема С строк подробно не разжёвана, или ещё не дошёл до неё.
Уже в нескольких упражнениях была подобная ошибка, когда что-то не работает, разбираешься, а оказывается, что это проблема не в логике программы, а в типах данных.
Все разжёвано на каждом углу. Включи мозги. Прекрати фантазировать и начинай вчитываться в учебник. Не понимаешь свой прочитай это http://www.rsdn.ru/article/cpp/cstr.xml
Хочешь писать на Си придётся иметь дело с памятью. Очень плотно. и Необходимо себе чётко представлять что где и как лежит и что с этим будет делать процессор.

Оффлайн Vovaldo

  • Любитель
  • *
  • Сообщений: 82
  • Ху Тин Пуй
    • Просмотр профиля
    • Путин забрал у Медведева инновационный орган
Re: Строки в C
« Ответ #24 : 12 Апреля 2012, 07:07:48 »
А может вы сначала дочитаете до конца Букварь K&R?
... а потом станете рассуждать? ;)
Слышь, [удалено модератором], ещё раз тебя спрошу всё-таки - ты в каком месте моей фразы:
"Посмотри в документации или в учебнике по С раздел про строковые константы - '\0' в конце добавляется автоматически." - видишь хотя бы намёк на то, что речь идёт об инициализации или определении массива??? [удалено модератором]

Цитировать
- когда в любом месте программного кода С (это может быть инициализация, как у вас, параметром в printf(), в любых функциях вида str*() - в любом контексте) появляется запись вида: "abcdefghijklmnopqrstuvwxyz" - то она представляет собой литеральную константу длины 27, с '\0' записанным последним 27-м байтом, хотя вы в записи и указали 26 знаков...
Серьёзно??? :o
 :2funny:
Чувак, ты сделал для меня великое открытие!!! :2funny:
Если ты не заметил, то я толкую об этом на протяжении всего топика, но поскольку читаешь ты по диагонали, то нас ждёт ещё много твоих бессмысленных открытий-толкований. :coolsmiley:

Цитировать
Вот так я внятно излагаю? ;)
Ну я не знаю, это тебя надо спросить. Похоже, ты поступаешь по принципу: "Пять раз объясню, может на шестой раз и сам пойму."
 :2funny:

Цитировать
О-ба-на ;)
Я вообще то предполагал, что ... к окончанию среднеобразовательной школы все её выпускники (кто датянул до окончания) знают, что в С существует единственный способ представления символьных строк: это массив, массив байт если это старое char представление, массив многобайтных символов, если это mbchar (UTF-8) или wchar (UTF-32) ... но это всегда - массив.
Ага, и, судя по твоим предыдущим сообщениям, каждый раз когда у тебя в тексте программы встречаются строковые константы, то ты производишь ЯВНОЕ ОПРЕДЕЛЕНИЕ этих самых массивов? Так ведь тебя следует понимать? :D

Цитировать
Мне по простоте душевной как-то не представлялось, что в раздел "Программирование" заходят индивидуумы, которые ещё до этого места не дочитали K&R.
Прошу прощения за напряг.
Во-первых, читать и ПОНИМАТЬ - это разные вещи. :P
Во-вторых, не вижу в этом ничего страшного - если бы все всегда всё правильно понимали, то никаких форумов, техподдержек и прочих разъяснительно-обсудительных вещей не существовало бы.
 
Цитировать
Я тут в помощь "танкистам" написал иллюстрирующую программку - сильно просветляет: чем размер массива, содержащего литеральную строку, отличается от длины строки (а отличается он ровно на 1).
А теперь ткни меня носом в сообщение, где я когда-то утверждал что-то противоположное.

На форуме ЗАПРЕЩЕНО
2.2. Оскорблять кого-либо из участников форума или принижать его личные качества. Будьте вежливы и культурны!

Не стоит об этом забывать.


--andrew_bye
« Последнее редактирование: 12 Апреля 2012, 11:00:58 от andrew_bye »

Оффлайн qupl

  • Активист
  • *
  • Сообщений: 286
  • и тебя забанят, и меня забанят
    • Просмотр профиля
Re: Строки в C
« Ответ #25 : 12 Апреля 2012, 07:52:23 »
Ну и когда Vovaldo вдоволь нагрубил всем, что, впрочем, для него типично, теперь никто не будет спорить что за массивом
s[26]="abc....xyz"; ...далее еще много переменных...
не будет никакого завершающего нуля хоть ты тресни?
Муха (ё).
Муха - это насекомое. А "ё" - это буква, кому не хватает ее на клавиатуре.

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Строки в C
« Ответ #26 : 12 Апреля 2012, 09:18:05 »
qupl,
Были обратные утверждения? (фантазии Джека Воробья не в счёт)

Оффлайн Vovaldo

  • Любитель
  • *
  • Сообщений: 82
  • Ху Тин Пуй
    • Просмотр профиля
    • Путин забрал у Медведева инновационный орган
Re: Строки в C
« Ответ #27 : 12 Апреля 2012, 12:10:44 »
Ну и когда Vovaldo вдоволь нагрубил всем, что, впрочем, для него типично, теперь никто не будет спорить что за массивом
s[26]="abc....xyz"; ...далее еще много переменных...
не будет никакого завершающего нуля хоть ты тресни?
Неужели ты будешь утверждать, что за ВТОРЫМ массивом(согласно терминам Olej), или за инициализирующей константной строкой (согласно общепринятому её названию), НЕ БУДЕТ завершающего нуля? :o
 ;D

Оффлайн Olej

  • Забанен
  • Активист
  • *
  • Сообщений: 884
    • Просмотр профиля
Re: Строки в C
« Ответ #28 : 12 Апреля 2012, 12:54:25 »
Неужели ты будешь утверждать, что за ВТОРЫМ массивом(согласно терминам Olej), или за инициализирующей константной строкой (согласно общепринятому её названию), НЕ БУДЕТ завершающего нуля? :o
 ;D

вот так
char s[] = "123"
или вот так
char s[4] = "123"
или вот так
char s[100] = "123"- обязательно будет.

А вот если извратиться вот так:
char s[3] = "123"
или даже так
char s[2] = "123"
- то не будет
;)

 

Оффлайн Vovaldo

  • Любитель
  • *
  • Сообщений: 82
  • Ху Тин Пуй
    • Просмотр профиля
    • Путин забрал у Медведева инновационный орган
Re: Строки в C
« Ответ #29 : 12 Апреля 2012, 13:10:32 »
А вот если извратиться вот так:
char s[3] = "123"
или даже так
char s[2] = "123"
- то не будет
;)
Всё ясно. Пациента - в морг.

 

Страница сгенерирована за 0.113 секунд. Запросов: 25.