Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Олимпиада программистов
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
Буратино
am1808, если открыть реализацию realloc, то там похоже есть проверка аргументов. Еще мне не очень, что вы несколько раз strlen вызываете, наверняка можно обойтись и одним разом на функцию.
Буратино
Вот так еще можжно:
Код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

    
void str_cpy (char **a,   char *b) {  
   *a = b;
}


void str_cat (char **a,  char *b){
   int _size1 = strlen(b);  
   int _size2 = strlen(*a);  
   char * tmp = NULL;
  
   tmp = realloc(tmp, _size1 + _size2 + 2);
   memmove(tmp , *a, _size2);
   memmove(tmp + _size2, b, _size1);
  
   *a = tmp;
}

int main() {
   char *s = NULL;
  
   str_cpy(&s, "Hola Mola");    
   str_cpy(&s, s+5);    
   str_cat(&s," World");  
      
   return 0;
}


проверку аргументов пока вынесем за скобкиsm.gif
Огурцов
Цитата(demiurg_spb @ Mar 20 2013, 11:39) *
Верно сказать что sizeof(char)==1 байт всегда и везде, ну а байт может быть любой размерности.

А у нас в char`е два байта, при том, что в байте восемь бит. Двоичных, на всякий случай, а то мало ли у кого как.
demiurg_spb
Цитата(Огурцов @ Mar 21 2013, 15:58) *
А у нас в char`е два байта, при том, что в байте восемь бит. Двоичных, на всякий случай, а то мало ли у кого как.
У вас это где, в компиляторе для TI dsp'шок?. Стандарт однозначно говорит, что sizeof(char)=1. А у вас сколько sizeof(char) выдаёт?

Цитата(Буратино @ Mar 21 2013, 15:54) *
Код
void str_cpy (char** a, char* b) {*a = b;}
А как насчёт того, что в ТЗ сказано, что каждая функция должна быть порядка 7 строк? А тут всё в 1 влезло...wink.gif
Буратино
Цитата(demiurg_spb @ Mar 21 2013, 16:20) *
А как насчёт того, что в ТЗ сказано, что каждая функция должна быть порядка 7 строк? А тут всё в 1 влезло...wink.gif


"не более чем 7 строк кода на функцию"
igorle
Цитата(Буратино @ Mar 21 2013, 17:37) *
"не более чем 7 строк кода на функцию"

Проблема общения в виртуале - никогда не уверен - человек шутит, или серьезно. Ваш вариант выглядит как троллинг.
Вы действительно хотите комментариев к этому коду?
Буратино
Цитата(igorle @ Mar 21 2013, 17:44) *
Проблема общения в виртуале - никогда не уверен - человек шутит, или серьезно. Ваш вариант выглядит как троллинг.
Вы действительно хотите комментариев к этому коду?


А какой смысл размещать его тут кроме как получить каменты? Конечно хочу! Кстати данный код работает и выполняет функции. Почему так нельзя сделать!?
igorle
Цитата(Буратино @ Mar 21 2013, 18:10) *
А какой смысл размещать его тут кроме как получить каменты? Конечно хочу! Кстати данный код работает и выполняет функции. Почему так нельзя сделать!?

Ну, некоторые пишут, чтобы получать лулзы, глядя как люди рвут на себе волосы
"Код работает" - это совсем не аргумент. Надо не код, который один раз сработает с данным примером, а код, который будет работать в библиотеке. Он будет вызываться миллионы раз как с короткими, так и мегабайтными строками.
Код
void str_cpy (char **a,   char *b) {  
   *a = b;
}
Кто сказал что сорс будет существовать после вызова функции? Может быть я работаю с буфером, потом копирую строку и снова пишу в буфер. Или освобождаю буфер. Что будет с сохраненным значением?
Код
void str_cat (char **a,  char *b){
   int _size1 = strlen(b);  
   int _size2 = strlen(*a);

Функция может быть вызвана для неинициализированного дестинейшена. strlen для NULL - крэш
Код
   char * tmp = NULL;
  
   tmp = realloc(tmp, _size1 + _size2 + 2);
Зачем вызывать реаллок для NULL? Зачем двойка добавлена?
Код
   memmove(tmp , *a, _size2);
   memmove(tmp + _size2, b, _size1);
  
   *a = tmp;
}
Старое значение *a перетерто. Память, на которую указывала *a - потеряна. Результирующая строка не ограничена нулем.
msalov
Цитата(gerber @ Mar 20 2013, 13:28) *
Код
strlen(from_str)*sizeof(char)

Хотя в приведённом коде, по-моему, это явный перебор. И свидетельствует, скорее, о формальном подходе к программированию и непониманию происходящего.
В таком виде - да. Идея хорошая, но реализация чуть подкачала. Для данного случая то же самое по сути
Код
strlen(from_str)*sizeof(*from_str)
, но если char станет wchar отработает нормально.
am1808
нее, не прокатит, множитель в виде sizeof(char) лишний, но ничего плохого в нем нет.

Типы параметров функции точно определены, поэтому sizeof(*from_str) строго определено.
Перегрузки тут нет никакой, это в плюсах можно так сделать.
Буратино
igorle, замечания обдумываю, но вот например не ясно почему "покрошится" strlen от NULL? Это же просто 0 что собственно эквивалентно "\0"
realloc можно вызывать с NULL, но у меня оно конечно не к селу ни к городу, однако realloc и NULL вполне себе ничего и есть причины так делать.

Вот еще вариант ,но єто практически максимум того на что способен мой "мозг". Проверки и исключения пока не прикручивал ,важно понять это правильная идея или нет!?
Код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

    
void str_cpy (char **a,   const char *  b) {
   char * tmp = NULL;
   int size_str = strlen(b)+1;
  
   tmp = realloc(tmp, size_str);
   memmove (tmp, b, size_str);
   free (*a);
   *a = tmp;
}


void str_cat (char **a,  const char *b){
   int size_str_1 = strlen(b);
   int size_str_2 = strlen(*a);
  
   *a = realloc(*a, size_str_1 + size_str_2 + 1);
   memmove (*a + size_str_2, b, size_str_1 + 1);
}

int main() {
   char *s = NULL;

   str_cpy(&s, "Hola Mola");    
   str_cpy(&s, s+5);    
   str_cat(&s," World");
      
   return 0;
}
igorle
Цитата(Буратино @ Mar 22 2013, 11:30) *
...не ясно почему "покрошится" strlen от NULL? Это же просто 0 что собственно эквивалентно "\0"

Чтобы почуствовать разницу, забегите вот этот код:
Код
static void foo(char *str)
{
    printf("%p\n", str);
}

int main(void)
{
    foo(NULL);
    foo("\0");
    return 0;
}
После этого попытайтесь объяснить, почему ваше утверждение неверно.

По поводу всего остального. Я подписал обязательство, согласно которому, если станет известно что я консультирую участников конкурса Холы, то я должен буду вернуть полученую от них приемию. А я премию уже потратил на детальки. Так что дальше - самостоятельно. Адью sm.gif
Буратино
Если бы я мог как-то обезапасить строку от изменений на ее текущем месте, то получилось бы интереснее, но я так понимаю, что кроме как выделить память под строку и перелить в это мето данные не получится гарантировать ее сохранность! Создать в памяти резервирование под существующую строку (то есть под то место где она текущая лежит) так же не получится ибо наверное на архитектуре завязано много.
Склеивать строки нельзя на пустом месте, нужно быть уверенным в том что это склейка разместится в свободном и безопасном пространстве.
Что касается strlen, то мне нужно посмотреть как она, функция, сделана.
federal
Буратино, какой же ты деревянный все таки lol.gif
Буратино
Цитата(federal @ Mar 22 2013, 15:29) *
Буратино, какой же ты деревянный все таки lol.gif


Я лично был свидетелем того, как тигр в зоопарке сожрал резинового утенка, как вор и бандит становится президентом страны и как можно штуку баксов потратить на туфельки. А уж Дуремаров разного сорта и помола, я столько раз встречал, что Вы даже просто статистически ничего для меня не значите.
bb-offtopic.gif
Буратино
igorle, Вы наверное хотели написать
Код
'\0'

а не
Код
"\0"


Вот код который печатает трижды NULL
Код
void foo(char *str) {
    printf("%s \n", str );
}

int main(void) {
    foo(NULL);
    foo('\0');
    foo(0);
    
    return 0;
}

Код
stdout:
(null)
(null)
(null)


Вот некая реализация strlen
Код
/*
* Copyright (C) 2002     Manuel Novoa III
* Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/

#include "_string.h"

#ifdef WANT_WIDE
# define Wstrlen wcslen
#else
# define Wstrlen strlen
#endif

size_t Wstrlen(const Wchar *s)
{
    register const Wchar *p;

    for (p=s; *p; p++);

    return p - s;
}
libc_hidden_weak(Wstrlen)


На первый взгляд ничего криминального в передаче NULL в функцию нет, но те не менее strlen c NULL компилится с ошибкой.
igorle
Я Вас теряю.
Вы пишите
Цитата
не ясно почему "покрошится" strlen от NULL? Это же просто 0 что собственно эквивалентно "\0"

Когда я объясняю, в чем разница между 0 и "\0", вы говорите
Цитата
igorle, Вы наверное хотели написать '\0' а не "\0"

Нет. Вы написали "\0", поэтому я говорил об "\0", а не об '\0'. Логично, да?

После этого я даю вам пример, где распечатываю поинтер (%p), и показываю в чем разница между 0 и "\0", а вы печатаете совсем другой пример, где распечатываете строку (%s) и даете совсем другие аргументы. Я не улавливаю ход Вашей мысли.
Буратино
Сори, но я имел в виду именно '\0', не строковой литерал.
Кое-что почитал и думаю что нулевой указатель нельзя использовать с strlen, потому что нельзя разименовывать нулевой указатель.
ARV
Цитата(Буратино @ Mar 25 2013, 20:41) *
Кое-что почитал и думаю что нулевой указатель нельзя использовать с strlen, потому что нельзя разименовывать нулевой указатель.

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

strlen(NULL) у вас вряд ли компилируется с ошибкой, скорее с предупреждением. а вот в процессе выполнения этого кода результат будет непредсказуем. точнее, если платформа вам хорошо знакома - результат можно предсказать, но он будет явно бессмысленным, т.к. по адресу памяти 0x0000 у вас наверняка никакой строки нет.


igorle
Цитата(Буратино @ Mar 25 2013, 19:41) *
Сори, но я имел в виду именно '\0', не строковой литерал.
Кое-что почитал и думаю что нулевой указатель нельзя использовать с strlen, потому что нельзя разименовывать нулевой указатель.

Абсолютно верно. NULL означает, что объект находится по адресу ноль. Обычно - защищенная область. Как поется в песне "Ай-ай-ай туда нельзя"
ar__systems
отправил им решение, посмотрим что ответят. Сделал поиск на str_free, нашел еще одну страницу этого соревнования с другой датой и уже с решением.

https://compilr.com/timaner/test/HelloWorld.c
Буратино
Жаль что больше нет времени. 28го все закончится(
Вот моя последняя реализация. Прокачал защиту от NULL, оптимизировал некоторые участки и обдумал траблу с перекрытием данных в строках.

Код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

    
void str_cpy ( char **a, const char * b ) {

   int size_src;
   char overlap;
  
   if ( b ) size_src = strlen( b ) + 1; else return;
   overlap = (*a <= b && *a + size_src >= b) || (b <= *a && b + size_src >= *a);
   *a = realloc( *a, size_src );
   if ( overlap )  
      for (*a += size_src, b += size_src; size_src--; *--*a = *--b);
   else
       memcpy( *a, b, size_src );
}


void str_cat ( char **a,  const char *b ){
   int size_src, size_des;
      
   if ( *a ) size_des = strlen( *a ); else size_des = 0;
   if ( b )  size_src = strlen( b ); else return;
  
   *a = realloc( *a, size_src + size_des + 1 );
   memmove ( *a + size_des, b, size_src + 1 );
}

int main() {
   char *s = NULL;
  
   str_cpy( &s, "Hola Mola" );    
   str_cpy( &s, s+5 );      
   str_cat( &s," World" );  
  
   return 0;
}


Очень интересно как правильно, ждем ответ ответ на этот вопрос от организаторов! sm.gif

(EDIT: Утром немного допилил и исправил ошибки)
demiurg_spb
Цитата(Буратино @ Mar 28 2013, 00:33) *
обдумал траблу с перекрытием данных в строках.
А чего её обдумывать?
Посмотрите реализацию memmove. В ней всё уже обдумано: если нет перекрытия то вызывается memcpy. Оптимальнее вряд ли напишете.
Я тоже отправил свой вариант в день размещения этой темы, но никакого ответа пока так и не получил. Завтра могу показать.
igorle
Цитата(demiurg_spb @ Mar 28 2013, 09:19) *
Я тоже отправил свой вариант в день размещения этой темы, но никакого ответа пока так и не получил.

Это странно. Они всегда отвечают если не в тот же день, то на следующий. Скажите, пожалуйста, свой емэйл. Можно частично. Я им прямо сейчас позвоню и спрошу как так получилось, что не ответили.
demiurg_spb
Цитата(igorle @ Mar 28 2013, 10:01) *
Это странно. Они всегда отвечают если не в тот же день, то на следующий. Скажите, пожалуйста, свой емэйл. Можно частично. Я им прямо сейчас позвоню и спрошу как так получилось, что не ответили.
Отправлял и с
demiurg_spb @ _ _ _.ru
и с
___ @ kipspb.ru
igorle
Цитата(demiurg_spb @ Mar 28 2013, 10:05) *
Отправлял и с ... и с ...

Я позвонил человеку, который просил меня сделать перевод. Он сегодня не работает (в Израиле сейчас неделя праздников), поэтому сгодня проверить как так получилось не может. Вернется на работу во вторник.
Сопроводительное письмо было? На английском?
demiurg_spb
Цитата(igorle @ Mar 28 2013, 10:16) *
Сопроводительное письмо было? На английском?
Нет. Только код. А надо?
Буратино
Скажите, а как можно переписать покрасивше вот это:
Код
if ( b )  size_src = strlen( b ); else return;


В Libc вместо char используют Wchar. Приблизительно я понимаю о чем речь, но вот конкретно для данной задачи оно нужно?
Спасбио!

Цитата(demiurg_spb @ Mar 28 2013, 08:19) *
А чего её обдумывать?
Посмотрите реализацию memmove. В ней всё уже обдумано: если нет перекрытия то вызывается memcpy. Оптимальнее вряд ли напишете.
Я тоже отправил свой вариант в день размещения этой темы, но никакого ответа пока так и не получил. Завтра могу показать.



Вот такая реализация мне доступна. Если я не ошибаюсь, здесь несколько упрощена проверка перекрытия.
Код
/*
* Copyright (C) 2002     Manuel Novoa III
* Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/

#include "_string.h"

#ifdef WANT_WIDE
# define Wmemmove wmemmove
#else
# define Wmemmove memmove
#endif

Wvoid *Wmemmove(Wvoid *s1, const Wvoid *s2, size_t n)
{
    register Wchar *s = (Wchar *) s1;
    register const Wchar *p = (const Wchar *) s2;

    if (p >= s) {
        while (n) {
            *s++ = *p++;
            --n;
        }
    } else {
        while (n) {
            --n;
            s[n] = p[n];
        }
    }

    return s1;
}

#ifndef WANT_WIDE
libc_hidden_def(memmove)
#endif
demiurg_spb
Код
char* p;
size_t n = (p)? strlen(p) : 0;
Буратино
Цитата(demiurg_spb @ Mar 28 2013, 09:40) *
Код
char* p;
size_t n = (p)? strlen(p) : 0;


Нет, в случае если указатель нулевой то выход из функции осуществить! Зачем ноль присваивать если это уже не имеет смысла в нашем контексте например!?

А зачем Вы используетет size_t, чем например int не подходит? (я понимаю, что это связано с важными моментами, но не ясно с какими)
demiurg_spb
Цитата(Буратино @ Mar 28 2013, 10:45) *
А можно и не делать выход а дальше выполнять алгоритм со значением 0...
Всё от задачи зависит.
igorle
Цитата(demiurg_spb @ Mar 28 2013, 09:23) *
Нет. Только код. А надо?

Нет, не надо.
Просто подумал, что если пришло письмо на русском, это могло их сбить с толку.
Я их буду трясти во вторник.
demiurg_spb
Цитата(Буратино @ Mar 28 2013, 10:45) *
А зачем Вы используетет size_t, чем например int не подходит?

Самодокументирование кода.
Тем что int знаковый.
sizeof() возвращает size_t.
+
Посмотрите как написана libc.
Например посмотрите прототип memcpy. Видите какой тип у третьего аргумента?
Или что возвращает strlen. Ну и т.д. и т.п.
Вообщем если измеряется кол-во или размер самое место для size_t.
Буратино
Да, нужно почитать что-то на эту тему. Спс.
ar__systems
Цитата(Буратино @ Mar 28 2013, 01:40) *
Скажите, а как можно переписать покрасивше вот это:
Код
if ( b )  size_src = strlen( b ); else return;


Код
if ( !b )  return;
size_src = strlen( b );

igorle
Цитата(demiurg_spb @ Mar 28 2013, 09:05) *
Отправлял и с
demiurg_spb @ _ _ _.ru
и с
___ @ kipspb.ru

Посмотрели. Говорят, что с @kipspb.ru был один участник. Давно. Ответили ему в тот же день.
От demiurg_spb получили письмо только 28 марта. Были праздники, но скоро ответят (может быть уже ответили)
Очень удивлялись, что люди обсуждают на форуме и выкладывают решения конкурсных задач. Считают что это нелогичным. тем более, что конкурс продолжается.
Буратино
Цитата(igorle @ Apr 2 2013, 19:08) *
Посмотрели. Говорят, что с @kipspb.ru был один участник. Давно. Ответили ему в тот же день.
От demiurg_spb получили письмо только 28 марта. Были праздники, но скоро ответят (может быть уже ответили)
Очень удивлялись, что люди обсуждают на форуме и выкладывают решения конкурсных задач. Считают что это нелогичным. тем более, что конкурс продолжается.


Как так продолжается? А когда заканчивается?
igorle
Цитата(Буратино @ Apr 2 2013, 20:55) *
Как так продолжается? А когда заканчивается?

Они этот процесс уже год как ведут. Можете посмотреть список "победителей". Там есть даты. Я не знаю, зачем он конечную дату публикуют, а потом корректируют. Хозяин - барин.
Ну и, как помните, конкурс индивидуальный, а не коллективный. Так что лучше свои решения не публиковать.
demiurg_spb
Цитата(igorle @ Apr 2 2013, 20:08) *
Посмотрели. Говорят, что с @kipspb.ru был один участник. Давно. Ответили ему в тот же день.
Ничего не получил.
Цитата
От demiurg_spb получили письмо только 28 марта. Были праздники, но скоро ответят (может быть уже ответили)
Вчера прислали оповещение, что получили моё решение и извинились за задержку. Но пока никаких результатов и комментариев...

Цитата(igorle @ Apr 2 2013, 23:33) *
Так что лучше свои решения не публиковать.
ок.
demiurg_spb
Получил таки ответ от них:
Цитата
Thanks for taking the Hola Challenge! Our engineer has reviewed your solution, and I'd like to speak with you about the results. Please call me at ...

Хотелось бы спросить... C ними только на английском изъясняться можно или они и по-русски разумеют?
igorle
Цитата(demiurg_spb @ Apr 5 2013, 08:20) *
Получил таки ответ от них:

Хотелось бы спросить... C ними только на английском изъясняться можно или они и по-русски разумеют?

На английском. Там есть как минимум один человек, говорящий по русски. Но он обычно не занимается внешними связями.
Помните что в Израиле выходные - пятница и суббота.
Буратино
Так чем дело кончилось? Какое правильное решение?
ARV
Цитата(Буратино @ May 17 2013, 14:41) *
Так чем дело кончилось? Какое правильное решение?

правильное решение - игнорировать глупые задания
igorle
Цитата(Буратино @ May 17 2013, 13:41) *
Так чем дело кончилось? Какое правильное решение?

Дело не кончилось. Они продлевают это мероприятие. Судя по таблице победителей, последними на сегодня призы получили люди 18 и 19 марта. Всего я насчитал 52 победителя.
Также можно видеть, что за всю историю из не израильтян приз получил только один человек из Норвегии. Русских было не менее одиннадцати (судя по типично русским именам), но все они - израильтяне (судя по адресу).
Буратино
Для меня важно понять: правильное решение лежит исключительно в проф. плоскости или тут еще есть место всяким подколам/приколам и т.п. ?

igorle
Цитата(Буратино @ May 20 2013, 15:01) *
Для меня важно понять: правильное решение лежит исключительно в проф. плоскости или тут еще есть место всяким подколам/приколам и т.п. ?

Исключительно в профплоскости. Людей интересует понимание программистом сути происходящего. Не более того. Когда-то они открыли фирму Jungo и проинтервьюировали кучу народа в Израиле. Статистика была такова - проходил один из 120. Вопросы были достаточно простые, типа операций с указателями. 119 писали в различных форумах о том, какие дебилы в этом Jungo. Вы можете и сейчас найти эти темы в русскоязычных форумах.

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

PS. На всякий случай уточню - этот второй конкурс проводится другими людьми и ни какого отношения к теме топика не имеет.
Idle
Цитата(igorle @ May 20 2013, 21:07) *
119 писали в различных форумах о том, какие дебилы в этом Jungo

не - маркетинг там на высоте!

Цитата
How does Hola make the Internet faster?
The Internet is slowed down by server response times, Internet congestion, round trip times, and poorly written communication stacks in operating systems. Hola removes these bottlenecks by securely caching content on peers as they view it, and later serving it up to other nearby peers as they need it. Hola also compresses communication between peers to further speed the net. As more people install and use Hola, the faster and less congested it will be!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.