Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
3 / 3 / 5
Регистрация: 21.10.2012
Сообщений: 182

Дана программа из 7 строк. Почему y,z не увеличивают свои значения на 1?

02.07.2013, 22:13. Показов 998. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
#include<stdio.h>
int main(){
int x = 1, y = 1, z = 1, u;
u = ++x || ++y && ++z;
printf("x=%d, y=%d, z=%d, u=%d",x,y,z,u);
return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.07.2013, 22:13
Ответы с готовыми решениями:

Почему переменные одного и того же класса меняют свои значения одновременно
Действительно, столкнулся с таким фактом. Объявляю свой класс: ref class My_Class { public: static array&lt;int&gt;^ mas =...

Почему указатель теряет свои значения после выхода с метода, память выделена динамически
#include &lt;iostream&gt; using namespace std; void sqr( int* a, int length ); int main() { int *a = new int; int length =...

Дана прямоугольная таблица a[1:n,1:n]. Найти количество строк, начинающихся со значения t
Дана прямоугольная таблица a. Найти количество строк, начинающихся со значения t. (Двумерный массив)

10
12 / 10 / 0
Регистрация: 01.07.2013
Сообщений: 62
02.07.2013, 22:22
нет оператора присваивания для этих переменных
C++
1
y = ++y;  // вычисляется значение справа от знака = и присваивается переменной слева от этого знака
0
3 / 3 / 5
Регистрация: 21.10.2012
Сообщений: 182
02.07.2013, 22:30  [ТС]
120°, без присваивания значение все равно должно увеличиваться, вот пример:
C++
1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main(){
int x = 1, y = 1, z = 1;
++x;
++y;
++z;
printf("x=%d, y=%d, z=%d",x,y,z);
return 0;
}
0
12 / 10 / 0
Регистрация: 01.07.2013
Сообщений: 62
02.07.2013, 22:36
прошу прощения. ступил немного
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
02.07.2013, 22:40
Цитата Сообщение от 120° Посмотреть сообщение
нет оператора присваивания для этих переменных
да ладно? подучи-ка операторы.
Цитата Сообщение от Sammm Посмотреть сообщение
Почему y,z не увеличивают свои значения на 1?
возможно, компилятор оптимизирует код и, заранее присваивает U=1 после первого действия ++x, понимая, что раз х не равен нулю, то и лог.выражение х ИЛИ что-то_там тоже будет равно истине, т.е. единице! И обрывает вычисление выражения.
2
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
03.07.2013, 01:43
Kuzia domovenok, Лень всему голова
Sammm, почитайте что-нибудь по теме "Ленивые операторы"
0
78 / 60 / 9
Регистрация: 26.06.2013
Сообщений: 198
03.07.2013, 07:44
По большому счету здесь дело не в оптимизации, а в стандарте.
5.15 Logical OR operator
1 The || operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). It returns true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.

Думаю, это было бы уже слишком, если бы компилятор позволял себе такую оптимизацию вопреки стандартам.
Кстати, в данном случае VC2008++ создает честный код для дебаг-версии

Замечание

Для инкремента целых чисел VC++ создает подобный код:
MOV EAX, DWORD PTR[VAR]
ADD EAX, 1 ; Если результат 0, то ZF будет установлен, иначе - сброшен.
MOV DWORD PTR[VAR], EAX

Assembler
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
39
40
41
42
43
;...
    int x = 1, y = 1, z = 1, u;
004113BE  mov         dword ptr [x],1 
004113C5  mov         dword ptr [y],1 
004113CC  mov         dword ptr [z],1 
 
    u = ++x || ++y && ++z;
; Инкремент x. 
004113D3  mov         eax,dword ptr [x]
004113D6  add         eax,1
004113D9  mov         dword ptr [x],eax
; Переход (true), если ZF==0 (если x!=0)
004113DC  jne         main+60h (411400h)
 
; Инкремент y.
004113DE  mov         ecx,dword ptr [y]
004113E1  add         ecx,1
004113E4  mov         dword ptr [y],ecx
; Переход (false), если ZF==1 (если y==0).
004113E7  je          main+54h (4113F4h)
 
; Инкремент z.
004113E9  mov         edx,dword ptr [z]
004113EC  add         edx,1
004113EF  mov         dword ptr [z],edx
; Переход (true), если ZF==0 (если z!=0).
004113F2  jne         main+60h (411400h)
 
; Результат false, запись в стек.
004113F4  mov         dword ptr [ebp-0F4h],0
 
; Переход (сохранение результата в u).
004113FE  jmp         main+6Ah (41140Ah)
 
; Результат true, запись в стек.
00411400  mov         dword ptr [ebp-0F4h],1
 
; Сохранение результата в u.
0041140A  mov         eax,dword ptr [ebp-0F4h] 
00411410  mov         dword ptr [u],eax 
 
    printf("x=%d, y=%d, z=%d, u=%d",x,y,z,u);
;...


В релизе конечно же оптимизирует и выкидывает все вычисления вообще, сразу заталкивая значения в стек для вызова функции.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main ()
{
    int x = 1, y = 1, z = 1, u;
    u = ++x || ++y && ++z;
    printf("x=%d, y=%d, z=%d, u=%d",x,y,z,u);
00401000  push        1    
00401002  push        1    
00401004  push        1    
00401006  push        2    
00401008  push        offset string "x=%d, y=%d, z=%d, u=%d" (402104h) 
0040100D  call        dword ptr [__imp__printf (4020A0h)] 
00401013  add         esp,14h 
    return 0;
00401016  xor         eax,eax 
}
00401018  ret
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
03.07.2013, 09:41
Sammm, потому что логика твоего алгоритма следующая или ++x или (++y && ++z) - как сказал выше nxtech,
Цитата Сообщение от nxtech Посмотреть сообщение
The || operator groups left-to-right.
, т.е первое ИЛИ всегда отрабатывает, а второе никогда не работает. Собственно переставь в своём коде u = ++y && ++z || ++x; и увидишь что теперь инкремент х не сработал.
А вот если оставить всё как есть и присвоить х значение -1 то получим отработку обоих условий
C
1
2
3
4
5
6
7
#include<stdio.h>
int main(){
int x = -1, y = 1, z = 1, u;
u = ++x || ++y && ++z;
printf("x=%d, y=%d, z=%d, u=%d",x,y,z,u);
return 0;
}
http://codepad.org/aGrzdCzG
В подобных случаях полезно всё разбивать на понятные логике if-else конструкции. Вот для пущего понимания
C
1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>
int main(){
int iVal = 0;
int x = -1, y = 1, z = 1, u;
if(iVal = ++x)
   u = iVal;
else
if(iVal = ++y && ++z)
   u = iVal;
printf("x=%d, y=%d, z=%d, u=%d",x,y,z,u);
return 0;
}
http://codepad.org/DnIxmPlR
1
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
03.07.2013, 10:01
Цитата Сообщение от Sammm Посмотреть сообщение
u = ++x || ++y && ++z;
логика операторов И и ИЛИ
ИЛИ равно ИСТИНА если один из операторов ИСТИНА(!=0)
И равно ЛОЖЬ если один из операторов равно ЛОЖЬ(==0)
смотрим
++x ИСТИНА значит и выражение ИСТИНА, нет смысла высчитывать другие операторы, они просто отбрасываются
этот прием можно использовать для "мирных целей"
например
C++
1
if(a&& b/a)
никогда не будет деления на 0
потому что если a==0 это ЛОЖЬ и и второй оператор b/a не будет рассчитываться
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
03.07.2013, 10:26
Цитата Сообщение от Croessmah Посмотреть сообщение
почитайте что-нибудь по теме "Ленивые операторы"
А я не будь дураком взял и почитал. )
Очень интересно. Только по запросу "ленивые операторы" нагугливается сплошь только почта и сотовая техподдержка, так что лучше искать по "ленивые вычисления".

Вот даже вынес в отдельную тему - Ленивые вычисления.
0
03.07.2013, 10:39

Не по теме:

Цитата Сообщение от SatanaXIII Посмотреть сообщение
Только по запросу "ленивые операторы" нагугливается сплошь только почта и сотовая техподдержка
Первая же страница:

не знаю, где тут сотовые операторы с почтой :)

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.07.2013, 10:39
Помогаю со студенческими работами здесь

Дана прямоугольная таблица a[1:n,1:n]. Найти количество строк, начинающихся со значения t
Дана прямоугольная таблица a. Найти количество строк, начинающихся со значения t.

Почему INSERT INTO удаляет значения из уже существующих строк?
Делаю запрос TRUNCATE `table1`; INSERT INTO `table1` (`id`,`date`) SELECT `id`, `date` FROM `table2`; даные вставляются. потом ...

Почему программа вылетает при конкатенации строк?
Собственно код #ifndef __STRING #define __STRING #include &lt;ostream&gt; class String { public: String();

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

Найти среднее арифметическое элементов каждой из строк заданной матрицы (почему не работает программа?)
Задана квадратная матрица А размером N х N (N&lt;=10), состоящая из действительных элементов. Найти среднее арифметическое элементов каждой...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru