Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.50/10: Рейтинг темы: голосов - 10, средняя оценка - 4.50
Mort
0 / 0 / 0
Регистрация: 10.01.2009
Сообщений: 4
1

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

10.01.2009, 23:15. Просмотров 1878. Ответов 21
Метки нет (Все метки)

Здравствуйте. У меня проблема: никак не могу понять эти указатели. Есть задача: пользователь вводит слово. затем, если число букв чётное - удаляем 2 центральных символа; если не чётное - то, соответственно, 1 центральный символ. Затем просто выводим результат. Если брать слово как буквенный массив, то проблемы никакой (просто двигаем индекс букв). НО нужно двигать именно указатель. Помогите пожалуйста, а то сам никак не могу =(
Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.01.2009, 23:15
Ответы с готовыми решениями:

задача с Указателями
помогите!!как этот код написать с указателями?? #include "stdafx.h" ...

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

путаница с указателями
Люди, помогите, пожалуйста! Имеется двумерный динамический массив, объявленный...

Работа с указателями
Всем здравия. Нужна ваша помощь. Есть задание по С++. К сожалению работала в...

Указателями массивов
#include <iostream> #include <math.h> #include <stdlib.h> #include <iomanip>...

21
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
10.01.2009, 23:34 2
char a[n];
a[i] == *(a+i)
0
Mort
0 / 0 / 0
Регистрация: 10.01.2009
Сообщений: 4
11.01.2009, 00:19  [ТС] 3
а если чуть-чуть конкретней пожалуйста?
0
accept
4833 / 3255 / 455
Регистрация: 10.12.2008
Сообщений: 10,569
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 )
0
Mort
0 / 0 / 0
Регистрация: 10.01.2009
Сообщений: 4
11.01.2009, 10:04  [ТС] 5
Это ясно. Дело в том, что я не могу понять сам алгоритм: как убрать два(или один) центральных символа двигая сам указатель, а не индекс отдельных букв.
0
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
11.01.2009, 10:20 6
чего тут понимать двигаешь указатель к первому элементу, который нужно убрать и записываешь в него i+2 элемент
char *p = &c[0];
p = p + strlen(c)>>1 - 1 - strlen(c)&1;
p тогда будет указывать на первый удаляемый элемент. ну а дальше по четности
0
accept
4833 / 3255 / 455
Регистрация: 10.12.2008
Сообщений: 10,569
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;
}
побитовые операции имеют очень низкий приоритет
0
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
11.01.2009, 13:08 8
при чем тут приоритет?
они работают быстро
0
accept
4833 / 3255 / 455
Регистрация: 10.12.2008
Сообщений: 10,569
11.01.2009, 13:39 9
притом что ты с ошибкой написал из-за этого
0
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
11.01.2009, 13:54 10
Цитата Сообщение от Ensase Посмотреть сообщение
чего тут понимать двигаешь указатель к первому элементу, который нужно убрать и записываешь в него i+2 элемент
char *p = &c[0];
p = p + strlen(c)>>1 - (1 - strlen(c)&1);
p тогда будет указывать на первый удаляемый элемент. ну а дальше по четности
да пока на телефоне тыкал скобки потерял
0
accept
4833 / 3255 / 455
Регистрация: 10.12.2008
Сообщений: 10,569
11.01.2009, 14:00 11
ещё одна осталась

я б даже сказал не переходя ко второй ошибке, ты неправильно исправил ошибку
0
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
11.01.2009, 15:45 12
см. вложение
0
Вложения
Тип файла: txt mian.txt (174 байт, 44 просмотров)
accept
4833 / 3255 / 455
Регистрация: 10.12.2008
Сообщений: 10,569
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);
0
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
11.01.2009, 16:45 14
в файле который прикреплен все нормально работает

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

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

допустим длина строки равна 5, 1-5 = -4, это 1111100 (еденицы налево идут до края типа), получится количество символов чётное, ты понял или нет ?
0
Вложения
Тип файла: txt main.txt (256 байт, 14 просмотров)
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
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, что неправильно
0
accept
4833 / 3255 / 455
Регистрация: 10.12.2008
Сообщений: 10,569
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);
0
Ensase
Флудер
192 / 30 / 11
Регистрация: 23.03.2007
Сообщений: 334
12.01.2009, 04:43 19
Еще после твоего второго сообщения я понял в чем была ошибка. обычно я не задумываюсь про приоритеты, а обильно пичкаю скобками

зы: этот пример - сравнение выполняется раньше сдвига
0
accept
4833 / 3255 / 455
Регистрация: 10.12.2008
Сообщений: 10,569
12.01.2009, 08:31 20
Код
 
#include <stdio.h>

main()
{
    if (2 & 2 > 1)
        printf("yes\n");
    return 0;
}
вот показательный, не выведет ничего
0
12.01.2009, 08:31
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.01.2009, 08:31

пример с указателями
#include &quot;stdafx.h&quot; #include&lt;iostream&gt; #include &lt;clocale&gt; #include &lt;cmath&gt;...

Проблема с указателями.
Доброго времени суток. Такой вопрос: если имеется массив указателей на объекты,...

Работа с указателями
Написать программу работы с указателями. LONG *p1; ULONG x = 5; LONG y =...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru