реклама на сайте
подробности

 
 
19 страниц V  « < 3 4 5 6 7 > »   
Reply to this topicStart new topic
> Си
Буратино
сообщение Jan 29 2013, 14:52
Сообщение #61


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



Задача А. Работа над ошибками так сказать..
В этой версии маленькие строки (меньше LEN_BUF байт) копируются в обратном порядке в буфер и возвращается указатель на голову, а если строки большие, то перестановками решаем. Во втором варианте проверям чтоб строка не слишком большой была (меньше MAX_LEN_STR)
Код
#include <stdio.h>

#define  LEN_BUF        100
#define  MAX_LEN_STR    1000

#define  _LenStr        buf[LEN_BUF-1]    // для хранения длины строки
#define  _TmpChar       buf[LEN_BUF-2]    // для хранения временных значений


char * reverse ( char *s ) {

   static char buf[LEN_BUF];              // буфер данных
   char *buf_pointer = &buf[LEN_BUF-1];   // определяем указатель, инициализируем значением адреса

   char *beg = s;                         // определяем указатель, инициализируем адресом начала строки
   char *end;

   while ( (*buf_pointer-- = *s++) ) {    // копипастим
      
      if (buf_pointer <= &buf[0]) {       // если строка больше, чем буфер, то:
              
         while (*++s)
        ;    
                
         if (s - beg > MAX_LEN_STR)
            return "Error, overflow!";

         _LenStr = s - beg;               // Вычисляем длинну строки
         end = s-1;                       // Указатель на конец строки
        
         do {                             // Меняем местами данные:
            _TmpChar = *beg;
            *beg = *end;
            *end = _TmpChar;
         } while (++beg < --end);
        
         return s - _LenStr;
      }
   }  

   return buf_pointer+2;
}


int main() {
   char s[]= "http://www.youtube.com/watch?v=cZjx6ItATW4";
   printf("%s\n", reverse (s) );
}



Не ясно еще как все же быть с одновременным вызовом функций
Код
char str1[] = "String 1";
char str2[] = "String 2";
printf("%s %s\n", reverse(str1), reverse(str2));

Вариант который предлагает ReAl требует введения второго аргумента, что не очень айс


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 29 2013, 15:16
Сообщение #62


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



О майн Готт! Вы на листинг этого чуда хоть смотрели?
Go to the top of the page
 
+Quote Post
Буратино
сообщение Jan 29 2013, 15:43
Сообщение #63


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



Цитата(_Pasha @ Jan 29 2013, 18:16) *
О майн Готт! Вы на листинг этого чуда хоть смотрели?


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


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 29 2013, 15:55
Сообщение #64


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Буратино @ Jan 29 2013, 19:43) *
неа, не смотрел. а что там такого страшного?
последний вариант лучше предыдущих тем. что небольшие строки перевернутся без вызова strlen ,ведь даже в вашем варианте нужно вызвать strlen, а потом до половины размера строки ворочать значения. При варианте с буфером я НЕ вызываю strlen и получаю строку в доп. буфере, однако при большой строке переворачиваю строку без буфера, но при этом strlen также не пользую.

Ниасилил. Strlen() хоть вызывай, хоть делай сам - оно выглядит одинаково.
Чем, извините, это всё лучше, если оно жрет памяти вдвое больше, не заточено под ASCIIZ, в >3раза больше число итераций. О майн Готт! crying.gif
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 29 2013, 16:01
Сообщение #65



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



K&R всплакнули бы от умиления...
Есть такая прилада профайлер, которая позволяет оценить время выполнения кода. Сравните результаты Вашей программы и поминавшихся выше вариантов со strlen().
Про наглядность кода и разбазаривание памяти ... пусть будет Задачей №3.

И попробуйте
Код
int main() {
   char s[]= "http://www.youtube.com/watch?v=cZjx6ItATW4";
   char s1[]= "Пачиму-то не работает";
   printf("%s\n", reverse (s) );
   printf("%s\n", reverse (s1) );
}


UPD: сделайте s1 > LEN_BUF
Go to the top of the page
 
+Quote Post
Буратино
сообщение Jan 29 2013, 16:25
Сообщение #66


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



_Pasha , функция работает в двух так сказать режимах:
а) когда входная строка меньше по длине чем LEN_BUF
б) когда входная строк больше, чем LEN_BUF

в варианте "а" strlen не вызывается, но при этом крутится вся строка
в варианте "б" strlen не вызывается, но выполняются действия аналогичные по смыслу. после этого строка перебирается и меняются местами данные, кол-во итераций длина строки/2. Вот как и у вас по сути.

последняя реализация лучше тем ,что если на входе функции будут разные данные ,то в общем итоге получается оптимальнее!
И обратите внимание - алгоритм "б" дополняет собой алгоритм "а" !

Цитата(xemul @ Jan 29 2013, 19:01) *
K&R всплакнули бы от умиления...
Есть такая прилада профайлер, которая позволяет оценить время выполнения кода. Сравните результаты Вашей программы и поминавшихся выше вариантов со strlen().
Про наглядность кода и разбазаривание памяти ... пусть будет Задачей №3.


Я согласен. Предлагаю обсудить условия проведения соревнования на скорость и денежные призы. Итак!?





Цитата(xemul @ Jan 29 2013, 19:01) *
И попробуйте
Код
int main() {
   char s[]= "http://www.youtube.com/watch?v=cZjx6ItATW4";
   char s1[]= "Пачиму-то не работает";
   printf("%s\n", reverse (s) );
   printf("%s\n", reverse (s1) );
}


ну не знаю ,кажись работает:

Код
  char s[]= "http://www.youtube.com/watch?v=cZjx6ItATW4";
   char s1[]= "http://www.ebay.com/sch/i.html?_from=R40&_sacat=0&_nkw=pl-660&_sop=15";
   printf("%s\n", reverse (s) );
   printf("%s\n", reverse (s1) );


Код
stdout:
4WTAtI6xjZc=v?hctaw/moc.ebutuoy.www//:ptth
51=pos_&066-lp=wkn_&0=tacas_&04R=morf_?lmth.i/hcs/moc.yabe.www//:ptth


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 29 2013, 16:33
Сообщение #67



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Код
int main() {
   char s[]= "http://www.youtube.com/watch?v=cZjx6ItATW4";
   char s1[]= "Пачиму-то не работает 1234567890 1234567890 1234567890 1234567890  1234567890 1234567890 1234567890 1234567890 1234567890 1234567890";
   printf("%s\n", reverse (s) );
   printf("%s\n", reverse (s1) );
}

D:\Work\Soft\Test>a
4WTAtI6xjZc=v?hctaw/moc.ebutuoy.www//:ptth
,=
Go to the top of the page
 
+Quote Post
Буратино
сообщение Jan 29 2013, 17:09
Сообщение #68


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215




Код
#define  LEN_BUF        10

stdout:
4WTAtI6xjZc=v?hctaw/moc.ebutuoy.www//:ptth
0987654321 0987654321 0987654321 0987654321 0987654321 0987654321 0987654321 0987654321 0987654321 1111111111111111111111


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
Буратино
сообщение Feb 27 2013, 20:10
Сообщение #69


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



Есть указатель на указатель на char:
Код
char **argv;

Как и чем его можно инициализировать и как (для чего) можно потом использовать? Что будет если я буду инкрементировать такой указатель на указатель?
К сож. с языком знакомлюсь рывками и че та совершенно запуталсяsad.gif


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
igorle
сообщение Feb 27 2013, 21:03
Сообщение #70


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



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

Код
void foo1(int argc, char **argv)
{
    while (argc--)
        printf("\"%s\"\n", argv++);
}

void foo(void)
{
    char *my_argv[] = {"Hello", "World", "one", "two", "four"};

    foo1(5, my_argv);
Go to the top of the page
 
+Quote Post
toweroff
сообщение Feb 27 2013, 21:08
Сообщение #71


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Да поправят меня, если не прав sm.gif
Указатель передается обычно тогда, когда функция может менять какие-то данные за пределами себя
Указатель за пределами какой-то функции тоже можно менять, не так ли? вот и передается указатель на этот указатель
Go to the top of the page
 
+Quote Post
Lotor
сообщение Feb 28 2013, 04:17
Сообщение #72


Местный
***

Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866



Цитата(toweroff @ Feb 28 2013, 01:08) *
Да поправят меня, если не прав sm.gif
Указатель передается обычно тогда, когда функция может менять какие-то данные за пределами себя
Указатель за пределами какой-то функции тоже можно менять, не так ли? вот и передается указатель на этот указатель

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


--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
Go to the top of the page
 
+Quote Post
igorle
сообщение Feb 28 2013, 06:45
Сообщение #73


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



Цитата(toweroff @ Feb 28 2013, 01:08) *
Да поправят меня, если не прав sm.gif

Формально - прав. Фактически - нет. Поправляю.
Вопрос был о char **argv.
Есть такая штука, как code convention. Именем argv принято обозначать статический массив указателей на строки. Поэтому упаси бог использовать его по тому же принципу, как используют при работе со списками. Например, здесь переменную answer назвать argv нельзя из соображений личной безопасности:

Код
void true_of_false(char **answer, int is_true)
{
    *answer = is_true ? "True" : "False";
}

void foo(void)
{
    char *b_char;

    true_of_false(&b_char, 2013);
    printf("He said %s %s %s!\n", b_char, b_char, b_char);
}


Сообщение отредактировал igorle - Feb 28 2013, 06:46
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 28 2013, 07:06
Сообщение #74


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(igorle @ Feb 28 2013, 10:45) *
То что вы написали тут формально и гарантированно работать не будет ИМХО.
Т.к. вы инициализируете указатель адресом локальной не статической строки и используете этот указатель вне области жизни этих строк (в другом стековом фрейме).
Вот так все формальности будут соблюдены:

Код
void true_of_false(char **answer, int is_true)
{
    static char True[]  = "True";
    static char False[] = "False";

    *answer = is_true ? True : False;
}

Хотя набрёл тут на такое:
Цитата
4. Строковой литерал во всех прочих случаях
Во всех прочих случаях строковой литерал трактуется как НЕявно заведённый статический константный объект типа массив char'ов, инициализированный символами данного строкового литерала с включением неявного завершающего нуля, и далее взятие адреса на нулевой элемент данного объекта.
и немного из другой плюсатой оперы
Цитата
"Память под строковые литералы выделяется статически, поэтому их возврат из функций безопасен" Б. Страуструп

Захотелось найти это в первоисточнике....


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
igorle
сообщение Feb 28 2013, 07:37
Сообщение #75


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



Цитата(demiurg_spb @ Feb 28 2013, 10:06) *
То что вы написали тут формально и гарантированно работать не будет ИМХО....


Это таки будет работать гарантировано. Потому что моя функция возвращает указатели на read only строки из секции data
Ваша функция тоже будет работать, но в ней есть бесполезное копирование строк из read only секции data в read write секцию. Недостатки
- в два раза увеличился объем памяти
- нет защиты от случайного изменения текста (оно в данном случае не желательно)

Посмотрите здесь

Ну и посыпаю голову пеплом по поводу опечатки в названии функции. Должно было быть true_or_false. Хотя так даже прикольно получилось, многозначительно.

Сообщение отредактировал igorle - Feb 28 2013, 07:34
Go to the top of the page
 
+Quote Post

19 страниц V  « < 3 4 5 6 7 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 07:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01509 секунд с 7
ELECTRONIX ©2004-2016