[Закрыть]
 
popoff.donetsk.ua
Люди молятся Богу лишь для того, чтобы Бог помог сохранить им все объекты своей привязанности. /Путь дурака/
Начало | Новости | Статьи | Форум | Опросы | Карта сайта | Обо мне
popoff.donetsk.ua - Форум - Основы программирования и алгоритмические языки - Язык Си. Моделирование строк с помощью указателей. Инициализация строк. Обращение к их элементам. Функция strtok().

Язык Си. Моделирование строк с помощью указателей. Инициализация строк. Обращение к их элементам. Функция strtok().

форумы popoff.donetsk.ua
Страницы: [1]
<< Новый  |  Старый >>  |  Ответ не возможен

Внимание! Этот топик устарел. Пожалуйста, создайте новый топик, чтобы задать интересующий Вас вопрос.

Автор Сообщение
V-Isa
V-Isa aka Inter
Окт, 2005
Сообщений: 16
V-Isa url://forum.message:757
Язык Си. Моделирование строк с помощью указателей. Инициализация строк. Обращение к их элементам. Функция strtok().

Делал лабу по Си и открыл для себя несколько интересных моментов...

1. Моделирую строки таким способом (без инициализации):
char * cp;
Потом работаю со значениями по адресам (например, cp). Происходят интересные вещи. При изменении значения по одному адресу меняются значения по другим адресам (не всегда).

Моделирую строки таким способом (с инициализацией):
char * cp=;
Снова та же беда.

Моделирую строки таким способом (с инициализацией):
char * cp=«     ;
В этом случае значения по адресам не изменяются сами по себе.
-- -- --
Буквально несколько минут назад (пока писал этот пост) мне объяснили, что при работе с указателями важно резервировать память для них, то есть такое:
int * ip;

  • ip=5;

на самом деле сработает, но может вызвать ошибку, так как для указателя ip не зарезервирована память.
Правильнее было бы так (как мне объяснили):
int i;
int * ip;
pi=i;

  • pi=5;

или так:
int * ip;
ip=malloc(sizeof(int));

  • ip=5;

...
free(ip);

Все-таки, как правильно работать со строками, которые смоделированы с помощью указателей?

2. У меня получалось обращаться к элементам строки (смоделированной с помощью указателя) с помощью оператора вырезки [], хотя по правилам языка Си (со слов уважаемого профессионала) этого делать нельзя.
char * cp=Example;
printf(%c,cp[0]); /*На экране - 'E'*/
/* выяснено случайно; работает даже для имен функций, которые возвращают по имени указатель на символ */

Все-таки, можно ли применять оператор вырезки и почему?

3. Функция strtok() модуля <string.h> работает так (со слов уважаемого профессионала):
char * cp;
char s[]=Example, example, example;
/* первый вызов */
cp=strtok(s,, ); /* в cp адрес первой лексемы */
/* второй и последующие вызова */
cp=strtok(NULL,, ); /* в cp адрес последующих лексем */

Почему именно NULL? А, если будет использоваться несколько вариантов поиска с функцией strtok() для строки s? Ведь, насколько я понимаю, при первом вызове где-то в памяти сохраняется указатель на строку для которой был осуществлен поиск.

Почему нельзя так (для второго и последующих вызовов):
cp=strtok(cp,, »);
?

Очень прошу помочь мне разобраться во всех этих моментах.

P.S. Прошу прощения за возможно допущенные неточности в синтаксисе языка Си.

popoff
Yuri
Июл, 2004
Сообщений: 944
popoff url://forum.message:758

Зачем так много? Вы не можете формулировать вои вопросы более конкретно?

Все-таки, как правильно работать со строками, которые смоделированы с помощью указателей?


Не правильно задавать вопрос «как при помощи X сделать Y?» Нужно спрашивать: «как сделать Y?». Использовать ли для решения Y способ Х или какой-нибудь другой - зависит от Y.

У меня получалось обращаться к элементам строки (смоделированной с помощью указателя) с помощью оператора вырезки [], хотя по правилам языка Си (со слов уважаемого профессионала) этого делать нельзя.


Не правда. Можно. Массив и указатель на первый элемент массива - это одно и то же. Для такого кода:

int a[10],*b;

Можно записать:

b=a;

Это сработает правильно. Следующие варианты обращения эквиваленты:

a[0]==b[0]
a[0]==*b
*a==b[0]
*a==*b
a[1]==b[1]

Почему именно NULL? А, если будет использоваться несколько вариантов поиска с функцией strtok() для строки s? Ведь, насколько я понимаю, при первом вызове где-то в памяти сохраняется указатель на строку для которой был осуществлен поиск.


А подумать? Вообще-то так написано в документации. Вам не приходило в голову, что это могло быть сделано так всего лишь для удобства?

________________________________
Если не будет деревьев — нам нечем будет дышать, если вода загрязнится — нам нечего будет пить.
V-Isa
V-Isa aka Inter
Окт, 2005
Сообщений: 16
V-Isa url://forum.message:759

Зачем так много? Вы не можете формулировать вои вопросы более конкретно?

popoffфорумы popoff.donetsk.ua


Могу. Просто привык подробно расписывать, так как не знаю, насколько хорошо меня понимает собеседник.

>> 1. Нужно ли при работе с указателями резервировать память? Как лучше резервировать память при моделировании строк методом указателей (malloc, free или прямой инициализацией при объявлении)?

>> 2. Спасибо за ответ.

>> 3. При повторном вызове функции strtok первым аргументом необходимо передавать NULL. Можно ли использовать одновременно несколько вариантов поиска в одной и той же строке. Не будет ли конфликтов? Можно ли в повторных вызовах функции strtok первым аргументом передавать не NULL, а указатель на предыдущую лексему? Будет ли это противоречить концепции языка?

А подумать? Вообще-то так написано в документации. Вам не приходило в голову, что это могло быть сделано так всего лишь для удобства?

popoffфорумы popoff.donetsk.ua


Именно после того, как «подумал» и возник вопрос об устройстве работы самой этой функции. После первого вызова она же куда-то помещает указатель на строку, адрес которой ей был передан при первом вызове. Устройство этой функции и поможет мне понять способ и область ее применения.

popoff
Yuri
Июл, 2004
Сообщений: 944
popoff url://forum.message:773

1. Нужно ли при работе с указателями резервировать память? Как лучше резервировать память при моделировании строк методом указателей (malloc, free или прямой инициализацией при объявлении)?

V-Isaфорумы popoff.donetsk.ua


Ответьте на вопрос, в какое место памяти будет производиться запись, если Вы не выделяли память?

free() не выделяет память.

Способ выделения памяти зависит от решаемой Вами задачи.

Ответить на Ваш вопрос в таком виде, как Вы его задали - это все равно, что в общем случае ответить на вопрос: «что лучше одевать: пальто или футболку?»

Можно ли использовать одновременно несколько вариантов поиска в одной и той же строке. Не будет ли конфликтов? Можно ли в повторных вызовах функции strtok первым аргументом передавать не NULL, а указатель на предыдущую лексему?

V-Isaфорумы popoff.donetsk.ua

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

Будет ли это противоречить концепции языка?

V-Isaфорумы popoff.donetsk.ua

Думаю, не будет.

Именно после того, как "подумал" и возник вопрос об устройстве работы самой этой функции. После первого вызова она же куда-то помещает указатель на строку, адрес которой ей был передан при первом вызове. Устройство этой функции и поможет мне понять способ и область ее применения.

Лично мне нравятся только строгие функции (такие, которые принимают все входные данные через аргументы, а результаты возвращают через имя). strtok(), очевидно, не является строгой функцией как раз потому, что она где-то что-то хранит между вызовами. Именно поэтому мне эта функция не нравится и я избегал бы ее использовать.

~~~~~ 10 Ноя 2005, 12:38 ~~~~~

Кстати, Вы, кажется, забыли прочитать самое важное:

это могло быть сделано так всего лишь для удобства

popoffфорумы popoff.donetsk.ua

________________________________
Если не будет деревьев — нам нечем будет дышать, если вода загрязнится — нам нечего будет пить.
V-Isa
V-Isa aka Inter
Окт, 2005
Сообщений: 16
V-Isa url://forum.message:774

Ответьте на вопрос, в какое место памяти будет производиться запись, если Вы не выделяли память?

popoffфорумы popoff.donetsk.ua


Отвечаю: не известно, так как не я писал компилятор . Вывод: память надо выделять. Проверено 3-мя ночами

free() не выделяет память.

popoffфорумы popoff.donetsk.ua


Под резервированием памяти malloc, free я имел в виду, что после выделения памяти под переменную и работы с ней нужно будет очистить занятую память.

Способ выделения памяти зависит от решаемой Вами задачи.

popoffфорумы popoff.donetsk.ua


Виноват, не уточнил. Речь шла о вводе некоторого массива строк с клавиатуры.

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

popoffфорумы popoff.donetsk.ua


В том-то и дело, что не хотелось пробовать наобум. Просто предполагал, что у Вас, возможно, уже был опыт работы с этой функцией, и своим советом Вы смогли бы помочь избежать мне некоторых «подводных камней». А так - уже попробовал.

Лично мне нравятся только строгие функции (такие, которые принимают все входные данные через аргументы, а результаты возвращают через имя). strtok(), очевидно, не является строгой функцией как раз потому, что она где-то что-то хранит между вызовами. Именно поэтому мне эта функция не нравится и я избегал бы ее использовать.

popoffфорумы popoff.donetsk.ua


Мне эта функция поэтому также очень не нравится. А также потому, что она «портит» текст, добавляя после лексем '\0'. Но против задания (с использованием strtok()) преподавателя не попрешь . Поэтому пришлось переделывать свое решение получения результата одним проходом текста на решение с функцией strtok().

popoff
Yuri
Июл, 2004
Сообщений: 944
popoff url://forum.message:776

Отвечаю: не известно, так как не я писал компилятор

V-Isaфорумы popoff.donetsk.ua

Вы ищите причину, по которой Вы можете позволить себе этого не знать. Но смею Вас разочаровать: тот факт, что Вы не принимали участие в разработке компилятора, не является поводом к незнаню.

Речь шла о вводе некоторого массива строк с клавиатуры.

V-Isaфорумы popoff.donetsk.ua

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

В том-то и дело, что не хотелось пробовать наобум. Просто предполагал, что у Вас, возможно, уже был опыт работы с этой функцией, и своим советом Вы смогли бы помочь избежать мне некоторых "подводных камней". А так - уже попробовал.

V-Isaфорумы popoff.donetsk.ua

Я могу тысячу раз объяснить студентам, что «в языке лисп 1) после открывающей круглой скобки записывается имя функции и 2) имя функции записывается после открывающей круглой скобки». Для многих это, однако, не повод, чтобы после открывающей круглой скобки не написать что-нибудь еще, например, имя аргумента (как в языке Си, например) или другую открывающую скобку - часто доходит до смеха. Понимают только после того, как сами наберут программу с ошибками и в долгих мучениях сами найдут свою ошибку.

Не уверен, что Ваш случай чем-то отличается. Если Вы хотите научиться, то Вам следует не избегать трудностей, а наоборот - искать новые. Не советоваться с другими, какие могут быть глюки с функциями, а наоборот - самому все выяснить, дизассемблировать компилятор, посмотреть, как работает эта функция и сделать доклад с раскрытием всех особенностей работы этой функции, даже тех, о которых сами разработчики копилятора не знают. Если Вам эта задача кажется слишком сложной, то задайте себе вопрос: «а хотите ли Вы это знать?» Когда эта задача не будет представлять никакой особенной сложности и Вы будете решать гораздо более сложные задачи, только тогда Вы сможете советоваться с другими по подобным пустякам. Но парадокс в том, что в таком случае Вам не будет нужно советоваться с другими - Вы и сами все сможете выяснить, причем гораздо быстрее, чем Вам напишут ответ на Ваш вопрос.

А также потому, что она "портит" текст, добавляя после лексем '\0'.

V-Isaфорумы popoff.donetsk.ua

Входные, выходные и промежуточные данные хранятся в *разных* переменные. После того, как Вы ввели исходный текст, Вы копируете его в отдельную промежуточную переменную и там что хотите с ним, то и делаете. В том числе изменяеете при помощи стрток().

________________________________
Если не будет деревьев — нам нечем будет дышать, если вода загрязнится — нам нечего будет пить.

Внимание! Этот топик устарел. Пожалуйста, создайте новый топик, чтобы задать интересующий Вас вопрос.

Страницы: [1]
<< Новый  |  Старый >>  |  Ответ не возможен
Вход
Поиск[?]:
Программное обеспечение любой сложности
koins.com.ua