Форум программистов, компьютерный форум CyberForum.ru

Задача с указателями - C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
Mort
0 / 0 / 0
Регистрация: 10.01.2009
Сообщений: 4
10.01.2009, 23:15     Задача с указателями #1
Здравствуйте. У меня проблема: никак не могу понять эти указатели. Есть задача: пользователь вводит слово. затем, если число букв чётное - удаляем 2 центральных символа; если не чётное - то, соответственно, 1 центральный символ. Затем просто выводим результат. Если брать слово как буквенный массив, то проблемы никакой (просто двигаем индекс букв). НО нужно двигать именно указатель. Помогите пожалуйста, а то сам никак не могу =(
Спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
10.01.2009, 23:34     Задача с указателями #2
char a[n];
a[i] == *(a+i)
Mort
0 / 0 / 0
Регистрация: 10.01.2009
Сообщений: 4
11.01.2009, 00:19  [ТС]     Задача с указателями #3
а если чуть-чуть конкретней пожалуйста?
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.01.2009, 00:39     Задача с указателями #4
нужно двигать именно указатель
указатель двигается с помощью прибавления или отнимания от него числа (количества шагов), отсчёт шагов начинается с нуля, размер шага вычисляется сам (он зависит от типа данных с которыми объявлен указатель), т.е. если объявляешь указатель char *p шаг будет равен размеру типа char (1 байт), если же int *ip; шаг будует равен размеру типа int (2 или 4 в зависимости от реализации языка C в компиляторе), если же struct list *Nodeptr; шаг будует равен размеру типа struct list (сколько там наберётся элементов суммарный размер плюс дыры после выравнивания)
в памяти ячейки идут подряд одна за другой равны одному байту, поэтому и адресы их отличаются на еденицу, если у тебя тип int (и равен 4) то и два рядом стоящих int'а будут отличаться на 4 байта (шаг будет равен 1 а адресы отличаются на 4, шаг будет 2 а адресы отличаются на 8 )
Mort
0 / 0 / 0
Регистрация: 10.01.2009
Сообщений: 4
11.01.2009, 10:04  [ТС]     Задача с указателями #5
Это ясно. Дело в том, что я не могу понять сам алгоритм: как убрать два(или один) центральных символа двигая сам указатель, а не индекс отдельных букв.
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
11.01.2009, 10:20     Задача с указателями #6
чего тут понимать двигаешь указатель к первому элементу, который нужно убрать и записываешь в него i+2 элемент
char *p = &c[0];
p = p + strlen(c)>>1 - 1 - strlen(c)&1;
p тогда будет указывать на первый удаляемый элемент. ну а дальше по четности
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.01.2009, 12:07     Задача с указателями #7
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
#include <stdio.h>
#include <string.h>
 
#define MAXLINE  1000   /* максимальная длина строки */
 
/* удаляет центральные символы (если длина чётная)
   или символ (если длина нечётная) строки */
main()
{
    char line[MAXLINE], *p;
    int n;
    
    sprintf(line, "one two");
    p = line + strlen(line)/2 - ((strlen(line) % 2) ? 0 : 1);
    for (n = (strlen(line) % 2) ? 1 : 2; (*p = *(p+n)) != '\0'; p++);
        ;
    printf("%s\n", line);
    return 0;
}
побитовые операции имеют очень низкий приоритет
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
11.01.2009, 13:08     Задача с указателями #8
при чем тут приоритет?
они работают быстро
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.01.2009, 13:39     Задача с указателями #9
притом что ты с ошибкой написал из-за этого
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
11.01.2009, 13:54     Задача с указателями #10
Цитата Сообщение от Ensase Посмотреть сообщение
чего тут понимать двигаешь указатель к первому элементу, который нужно убрать и записываешь в него i+2 элемент
char *p = &c[0];
p = p + strlen(c)>>1 - (1 - strlen(c)&1);
p тогда будет указывать на первый удаляемый элемент. ну а дальше по четности
да пока на телефоне тыкал скобки потерял
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.01.2009, 14:00     Задача с указателями #11
ещё одна осталась

я б даже сказал не переходя ко второй ошибке, ты неправильно исправил ошибку
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
11.01.2009, 15:45     Задача с указателями #12
см. вложение
Вложения
Тип файла: txt mian.txt (174 байт, 44 просмотров)
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.01.2009, 16:24     Задача с указателями #13
Код
    (1-strlen(c)&1);
ты не понимаешь как тут выполняются операции ?

сначала strlen возвращает значение, потом оно из еденицы вычитается, а потом побитовое умножение происходит, потому что сдвиги идут после + -, а & | вообще после сравнений == != идут

Код
    p = p + (strlen(c)>>1)-(1-strlen(c)&1);
надо

Код
    p = p + (strlen(c) >> 1) - 1 - (strlen(c) & 1);
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
11.01.2009, 16:45     Задача с указателями #14
в файле который прикреплен все нормально работает

зы: честно говоря мне уже надоело. те чего надо?
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.01.2009, 16:49     Задача с указателями #15
Код
    p = p + (strlen(c) >> 1) - 1 + (strlen(c) & 1);
вообще правильно вот так будет
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.01.2009, 17:00     Задача с указателями #16
твой файл я исправил (и имя и объявление strlen и scanf читает теперь правильно, и по теме у тебя мало того что там ошибка, мало того что ты не понимаешь в чём там ошибка, так даже если её исправить всё неправильно работает)

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

допустим длина строки равна 5, 1-5 = -4, это 1111100 (еденицы налево идут до края типа), получится количество символов чётное, ты понял или нет ?
Вложения
Тип файла: txt main.txt (256 байт, 14 просмотров)
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
11.01.2009, 22:23     Задача с указателями #17
это называется переливание из пустого в порожнее или по-другому занудство.
все выше сказанное можно было уложить в одно сообщение
при этом никакого отношения к теме вся эта чепуха не имеет

Добавлено через 4 часа 38 минут 45 секунд
и не важно что получается отрицательное число (это еще как посмотреть), так как после 1-strlen(c) следует &1 все биты кроме 0го не важны
и это будет эквивалентно
x%2 ? 1 : 0, что правильно
а вот
1+(strlen(c)&1)
будет давать 2 при strlen = 1, что неправильно
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
12.01.2009, 02:57     Задача с указателями #18
это называется переливание из пустого в порожнее или по-другому занудство
это называется ты код неправильно написал

и не важно что получается отрицательное число
важно, потому что отрицательное число получается чётным когда строка содержит 5 символов и нечётным когда строка содержит 4 символа, на краю оказывается соответствующий бит

задание
abc - вырезать b
abcd - вырезать bc

p, который установлен на a в обоих случаях при добавлении половины в первом случае оказывается на b, а во втором случае оказывается на c; в обоих случаях мы шагаем влево (в первом перейдёт на a во втором перейдёт на b), а потом шагаем вправо на значение этого бита чётности (в первом случае он равен еденице, во втором случае он равен нулю), т.е. в первом случае он шагает влево и вправо, а во втором случае только влево (таким образом получается правильная установка для обоих случаев на b)

твой код я запускал, на тебе ещё пример

Код
 
#include <stdio.h>

main()
{
    int a = 1;
    
    if (a << 1 == 2)
        printf("yes a = %d\n", a);
    return 0;
}
как ты думаешь она выведет 2 ?

Добавлено через 2 часа 36 минут 27 секунд
я понял, они обе правильные только работают по разному и ошибка у них наступает при нуле (указатель с начала строки смещается влево)
Код
    p += (strlen(c) >> 1) - 1 + (strlen(c) & 1);
    p += (strlen(c) >> 1) - (1 - strlen(c) & 1);
Ensase
Флудер
 Аватар для Ensase
191 / 29 / 5
Регистрация: 23.03.2007
Сообщений: 335
12.01.2009, 04:43     Задача с указателями #19
Еще после твоего второго сообщения я понял в чем была ошибка. обычно я не задумываюсь про приоритеты, а обильно пичкаю скобками

зы: этот пример - сравнение выполняется раньше сдвига
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.01.2009, 08:31     Задача с указателями
Еще ссылки по теме:

Работа с указателями C++
работа с указателями C++
C++ Программа с «указателями»
Работа с указателями C++
C++ Непонятки с указателями

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
12.01.2009, 08:31     Задача с указателями #20
Код
 
#include <stdio.h>

main()
{
    if (2 & 2 > 1)
        printf("yes\n");
    return 0;
}
вот показательный, не выведет ничего
Yandex
Объявления
12.01.2009, 08:31     Задача с указателями
Ответ Создать тему
Опции темы

Текущее время: 00:41. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru