Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
6 / 6 / 1
Регистрация: 28.09.2018
Сообщений: 396
1

Арифметика указателей. Но больше precedence

04.04.2019, 02:13. Показов 1859. Ответов 12

Author24 — интернет-сервис помощи студентам
Всё хорошо до

C
1
2
3
4
5
6
7
printf("--*b++ = %d\n", --*b++);
    /* Адрес двацатки + 1...
        Теперь b = &a[2]...
        30 = 30 - 1: должно быть, 29
        ...а вышло 18
        ?!
        */
Вот код:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <conio.h>
 
int main(void) {
 
    int a[5] = { 10, 20, 30, 40 , 50 }, *b, i = 0;
 
    printf("Initially: / Изначально:\n");
    for( i = 0 ; i < 5 ; i++ )  printf("a[%d] = %d\n", i, a[i]);
    printf("__________\n\n");
    
    b = a;
    //...в указатель b занесли адрес десяточки...
 
    printf("*b - 3... <=>\n\
    a[0] - 3 = 10 - 3 = %d\n\n", *b - 3);
    /*..здесь звёздочка исп-ся для разыменования ( dereferencing ),
        т.е. взятия значения */
    
        printf("(*++b) + 7 = %d\n", (*++b) + 7);
    /* теперь b = &a[1]
        двацаточка + 7: должно быть, 27 */
        printf("--(*b) + 4 = %d\n", --(*b) + 4);
    /* 20 = 20 - 1 + 4
        Должно быть, 23 */    
        printf("--*b++ = %d\n", --*b++);
    /* Адрес двацатки + 1...
        Теперь b = &a[2]...
        30 = 30 - 1: должно быть, 29*/
        /*printf("++*b = %d\t„®«¦*® Ўлвм 31\n", ++*b);
 
        printf("___________\nЌ*и ¬*ббЁў:\n\n");
 
        for ( i = 0 ; i < 5 ; i++ ) printf(" %d", a[i]);*/
 
        getch();
 
 }
И выходные данные:

Арифметика указателей. Но больше precedence


Спасибо
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.04.2019, 02:13
Ответы с готовыми решениями:

Удалить слова содержащие больше чем N символов с помощью указателей
Задание: Удалить слова содержащие больше чем N символов с помощью указателей. уже дня 4 пытаю...

Арифметика указателей
есть size_t * pointer_1; logfile_f(&quot;\npointer_1 is 0x%X&quot;, pointer_1); есть size_t * pointer_2...

арифметика указателей
Здравствуйте. Объясните, пожалуйста, код из инета: 1. &quot;переменная A типа int приводится к типу...

Арифметика указателей
Эквивалентны ли эти две записи? int *p1=new int; int *p2=p1; или int *p1=new int;

12
2307 / 1133 / 702
Регистрация: 25.04.2016
Сообщений: 3,229
04.04.2019, 02:42 2
Лучший ответ Сообщение было отмечено number_118 как решение

Решение

printf("--(*++b) = %d\n", --(*++b)); будет 29

--*b означает взять значение по адресу b и уменьшить на 1
*--b означает уменьшить адрес b на 1 и затем взять значение по получившемуся адресу

Именно поэтому с инкрементами и декрементами в указателях стоит быть осторожнее, а лучше вообще не использовать без надобности, поскольку в зависимости от положения они могут менять адрес самого указателя.
1
6 / 6 / 1
Регистрация: 28.09.2018
Сообщений: 396
04.04.2019, 03:17  [ТС] 3
stake-k26, ну почему же не использовать?

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

C
1
2
3
b = a + 1; 
// &a[1]
// непонятно, зачем начинать со второго, но да пусть
b++ <=> b = &a[1] + 1 <=> &a[2] --> т.о. можно перебирать массив ( обфускация, конечно )

Во-вторых. Увидел, что там же оно постфиксное - значит "используется потом". Если тут нет тех самых "точек следования", то тогда я бы ожидал 19, а не 18.

Спасибо.
0
2307 / 1133 / 702
Регистрация: 25.04.2016
Сообщений: 3,229
04.04.2019, 03:56 4
number_118, не за что.

Цитата Сообщение от number_118 Посмотреть сообщение
ну почему же не использовать?
Цитата Сообщение от stake-k26 Посмотреть сообщение
не использовать без надобности
...
0
6 / 6 / 1
Регистрация: 28.09.2018
Сообщений: 396
04.04.2019, 05:12  [ТС] 5
stake-k26, но почему 18, а не 19?

P.S. В принципе, я понял:

> меняют адрес самого указателя в зависимости от положения

По-Вашему выходит, что причина - неопределённое поведение ( если я правильно употребляю термин ). Потому что в принципе, чтобы обратиться к адресу указателя, должно быть &p, чего тут нет.
0
2307 / 1133 / 702
Регистрация: 25.04.2016
Сообщений: 3,229
04.04.2019, 14:13 6
Лучший ответ Сообщение было отмечено number_118 как решение

Решение

number_118, нет, вы неправильно поняли. Дело в том, что на предыдущем шаге вы делаете "--(*b) + 4" и если +4 ничего не изменяет, то --(*b) уменьшает значение a[1] на единицу, и у вас получается массив [10 19 30 40 50], и после этого вы выполняете "--*b++" - еще дополнительно уменьшаете a[1] на 1, т.е. теперь уже получается --19 = 18.

Вы бы это легко заметили, если бы после каждого шага выводили массив на экран.
1
6 / 6 / 1
Регистрация: 28.09.2018
Сообщений: 396
04.04.2019, 15:29  [ТС] 7
stake-k26 , немного не по теме сейчас напишу.

Вообще спасибо Вам. Только замечу следующее.

Я код чз комментирование отключал-подключал, это же видно из кода выше

Суть в том, что я упёрся в логику, разумеется, незаконную для констант, рода

C
1
2
3
4
5
int a = 5, *p = &a;
* p -= 1;
/*...и логика, что <=>
5-- <=> вывести 4,
а в переменной остаётся прежнее */

Не по теме:

Остаётся только удивляться себе.

0
83 / 59 / 29
Регистрация: 15.05.2013
Сообщений: 188
04.04.2019, 17:49 8
Это как понять? a остается равно 5 после присваивания или неверный комментарий?
0
2307 / 1133 / 702
Регистрация: 25.04.2016
Сообщений: 3,229
04.04.2019, 18:26 9
shadowmaan, нет, а становится 4, смотрите:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
int main (void)
{
    int a = 5;      // a равно 5
    int *p = &a;    // в указатель p записать адрес переменной a
    printf("a = %d\np = %d\n\n", a, *p);
    *p -= 1;        // достать значение по адресу p и уменьшить его на 1
                    // поскольку p хранит адрес переменной a, то *p -= 1; - это
                    // то же самое, что и a -= 1;
    printf("a = %d\np = %d\n\n", a, *p);
    return 0;
}
0
83 / 59 / 29
Регистрация: 15.05.2013
Сообщений: 188
04.04.2019, 18:30 10
Верно. Я просто не понял ваших ожиданий из предыдущего отрывка кода.
0
2307 / 1133 / 702
Регистрация: 25.04.2016
Сообщений: 3,229
04.04.2019, 18:38 11
shadowmaan, в комментарии указана ошибка, которую допустил number_118, он думал, что после применения декремента значение переменной не изменится. Т.е. как вы и сказали: "a остается равно 5", но на самом деле это не так. Из-за этого он и допустил ошибку в своих вычислениях.
0
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
04.04.2019, 18:43 12
C
1
            printf("--(*++b) = %d\n", --(*++b)); будет 29
Кликните здесь для просмотра всего текста

Здравствуйте.
Имхо, так советовать писать новичкам не стоит.
Для прочего существуют агрессивные режимы компилятора.
C
1
2
3
4
5
6
7
    /**/
    char* names[]={"misterX","Vasya","Vanya","Alenushka"};
    unsigned ages[]={0,10,20,30};
    char  literals[]={'0','A','B','C'};
    for(int i=0; i<3;i++) print("\n\tHello %s. \t\tYour age is %d. \tYour literals is %c",*names[i],ages[i],literals[i]);
    /*_______pointers________*/
    for(int i=0; i<3;i++) print("\n\tHello %s. \t\tYour age is %d. \tYour literal is %c",*(*(names+i)),*(ages+i),*(literals+i));
1
2307 / 1133 / 702
Регистрация: 25.04.2016
Сообщений: 3,229
04.04.2019, 18:44 13
если в двух словах, то ошибка вот в этом:

C
1
2
3
int a = 5;
printf("a = %d\n", a-1);    // а по-прежнему равно 5, но на экран выводится 4
printf("a = %d\n", --a);    // а стало 4, и на экран выводится 4
0
04.04.2019, 18:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.04.2019, 18:44
Помогаю со студенческими работами здесь

Арифметика указателей (указатель на void*)
У меня есть указатель на void*, который я получил с помощью void *beginPointer = VirtualAlloc(NULL,...

Индексация массивов, арифметика указателей
инициализирую одномерный массив и делаю на него указатель const int N = 6; int X =...

Способы создания объектов и арифметика указателей
Вот сам код: class ListNode { public: ListNode(int val) { next=NULL; ...

Как работает арифметика указателей, память массивов
В книге : х Это тоже самое что *(х+3)=120 Птм он грит : значение х в данном случае увеличивается...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru