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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.93
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
#1

Парадокс: значение переменной равно её адресу - C++

29.09.2009, 13:33. Просмотров 1741. Ответов 26
Метки нет (Все метки)

Друзья! Вот код, в нём всё понятно.
Выводятся одинаковые значения. Но ведь этого не может быть!
Хотя бы потому не может, что по адресу, который выводится первым, должно находиться значение символа '0'!
Ну, то есть первая и третья строка вывода предсказуемы. Но вторая вообще ни в какие ворота не лезет.
Помогите разобраться, пожалуйста. Спасибо.

C++
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main () {
 char s [5]= {'0','1','2','3','4'};
 
 printf ("eto znachenie peremennoi s  %x\n", s);
 printf ("a eto eo adres! oni pochemu-to ravni    %x\n", &s  );
 printf ("a eto adres nulevogo elementa! %x\n", &s[0]  );
 getchar ();
 return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.09.2009, 13:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Парадокс: значение переменной равно её адресу (C++):

Чему равно значение переменной d? - C++
int a = 5, b = 6, c = 7, d: d = (b ++- ( --c)) + (b + a--);

Поменять значение по указанному адресу в переменной типа std::string - C++
Здравствуйте форумчане. Не получается никак правильно использовать средства С++. Задача такова: Например есть две строки типа...

Нюансы использования препроцессора и макросов: чему будет равно значение переменной a? - C++
Чему будет равно значение переменной a? #define square(x) (x * x) int b = square(2.5); int a = square(2 + b);

Чему будет равно значение переменной z после выполнения следующего фрагмента программы? - C++
Пожалуйста, очень прошу помогите с тестами(( 1)Чему будет равно значение переменной z после выполнения следующего фрагмента программы при...

Чему будет равно значение переменной s после выполнения следующего фрагмента программы - C++
Очень прошу помогите решить!!!! 1) Чему будет равно значение переменной s после выполнения следующего фрагмента программы при...

Напишите структуру switch, которая выполняет следуя действия как что значение переменной grade равно: - C++
Напишите структуру switch, которая выполняет следуя действия как что значение переменной grade равно: &quot;А&quot; то добавить к sum 4; 'В', то...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Paulie
Айхрень...
306 / 174 / 4
Регистрация: 02.06.2009
Сообщений: 1,078
29.09.2009, 14:54 #16
kravam, ну а если уж совсем брутально &&s?
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
29.09.2009, 14:57  [ТС] #17
Наверное, переменная s имеет две ипостаси.
Что такое s? Адрес нулевого элемента массива.
Но не только. s это ещё и имя массива.

Если пишется s, то имеется ввиду адрес нулевого элемента.
Если пишется &s, то имеется ввиду адрес всего массива. Опять то есть его нулевого элемента.
Больше никак, по-моему.

Хе... Получается s какая-то виртуальная переменная.
Действительно. Собственного адреса не имеет...
Rififi
2359 / 1054 / 44
Регистрация: 03.05.2009
Сообщений: 2,656
29.09.2009, 14:57 #18
kravam,

мне непонятно, почему Вы решили, что Ваше статус кво позволяет отсылать меня туда, не зная куда

знания стандарта языка, на котором программируешь, не зависят от количества медалек.

Но как бы то ни было. K&R, глава 5.3 "Указатели и массивы"

Не в курсе что там написано, тех-книгами, которые старше моей бабушки как-то не интересуюсь.
Если мне что-то не понятно, я читаю не допотопную литературу, а свежайший стандарт c++. и тебе советую.
GAV_13
81 / 81 / 4
Регистрация: 14.09.2009
Сообщений: 252
29.09.2009, 15:04 #19
А не так?:
C++
1
2
3
4
char* p;
p=s;
//p - адрес s
//*p - само s
Paulie
Айхрень...
306 / 174 / 4
Регистрация: 02.06.2009
Сообщений: 1,078
29.09.2009, 15:05 #20
kravam, а ты дизассемблером его.... и посмотри сократи код до 3х строк, чтобы было проще разобраться. Просто мне сейчас некогда заниматься этим. Работа

Добавлено через 38 секунд
Цитата Сообщение от GAV_13 Посмотреть сообщение
само s
Само s это и ест адрес на первый элемент.
GAV_13
81 / 81 / 4
Регистрация: 14.09.2009
Сообщений: 252
29.09.2009, 15:10 #21
#Мессир, я имел ввиду выведет значение)
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,602
29.09.2009, 15:33 #22
Цитата Сообщение от kravam Посмотреть сообщение
А вот как найти адрес s?
А вот, как:
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
int main(){
    char s1[] = "abcd";
    char s2[] = "abcd";
    char *s3 = s1;
    
    printf("%tx\t%tx\t%tx\n", s1, s2, s3);
    
    return 0;
}
R0mm
Псевдо программист
192 / 113 / 15
Регистрация: 19.09.2009
Сообщений: 303
29.09.2009, 15:51 #23
Не то.
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
29.09.2009, 16:04  [ТС] #24
Цитата Сообщение от #Мессир Посмотреть сообщение
kravam, а ты дизассемблером его.... и посмотри сократи код до 3х строк, чтобы было проще разобраться. Просто мне сейчас некогда заниматься этим. Работа
Не так просто, это же не асемблерный код. Одно дело бряки на функции ставить, другое дело отслеживать переменные, не видя их имён. Но я попробовал.
Вот код, я его запустил в OllyDbg

C++
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main () {
 void* uk_1;
 void* uk_2;
 char s [5]= {'0','1','2','3','4'};
 printf ("&s[1]= %x",&s[1]);
 uk_1= s; 
 uk_2= &s;
 return 0;
}
Поставил бряк на выполнение printf. И вот такой наблюдаю код

004012DD |. E8 4E050000 CALL <JMP.&msvcrt.printf> ; \printf
004012E2 |. 8D45 D8 LEA EAX,DWORD PTR SS:[EBP-28]
004012E5 |. 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX
004012E8 |. 8D45 D8 LEA EAX,DWORD PTR SS:[EBP-28]
004012EB |. 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX

Вот после выполнения printf (первая строка) по РАЗНЫМ адресам [EBP-C] и [EBP-10] кладётся одно и то же значение. (EAX)
Я посмотрел, что это за значение. Это адрес. и по нему находится этот самый массив. То есть адрес этого массива кладётся два раза по разным адресам.
Остаётся предположить, что это выполняются две такие инструкции:

C++
1
2
 uk_1= s; 
 uk_2= &s;
В общем, поняно всё. Переменная s, как я уже говорил- двояка и виртуальна (не имеет собсвенного адреса). В первом случае это адрес нулевого элемента, во втором- адрес всего массива (автоматически опять же нулевого элемента.) Всем спасибо.
Nick Alte
Эксперт С++
1636 / 1008 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
29.09.2009, 20:38 #25
Позвольте слегка вставить свои 5 копеек. Тут наблюдается путаница между понятиями значения и адреса. Переменная s не "виртуальная", это просто массив. Формально значением такой переменной является содержимое всего массива. Но массивы в Си и С++ не имеют традиционной семантики значения: нельзя присвоить один массив другому, передать его значение в функцию через стек и т.п. Семантика массивов тесно переплетена с семантикой указателей, так что значение переменной-массива при любом удобном случае деградирует (pointer decay) до указателя на первый элемент массива. Это происходит, в частности, при передаче этого значения в printf.
accept
4821 / 3241 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
30.09.2009, 05:26 #26
Цитата Сообщение от kravam
В моём случае s (та самая вышеупомянутая переменная типа массив)
тип массив преобразуется в тип указатель на элемент того же типа, что и массив

C
1
    printf ("eto znachenie peremennoi s  %x\n", s);
так как s - имя массива, то оно преобразуется в указатель на нулевой элемент и только потом подаётся в функцию printf
DrMcSheen
60 / 60 / 1
Регистрация: 25.05.2009
Сообщений: 521
30.09.2009, 06:36 #27
Цитата Сообщение от kravam Посмотреть сообщение
C++
1
2
3
 char s [5]= {'0','1','2','3','4'};
 
 printf ("eto znachenie peremennoi s  %x\n", s);
По-моему, вся проблема в том, что переменной s в чистом виде у тебя не сущществует.
Есть только лишь массив s[x].
И, теоретически, компилятор должен был заругаться на обращение к s.
А он оказался умничкой, и сам сообразил, что s это и есть &s.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.09.2009, 06:36
Привет! Вот еще темы с ответами:

Доступ к переменной по абсолютному адресу. - C++
Мне нужно обратится к ячейке памяти с известным конкретным адресом (это может быть вектор прерывания, переменная БИОС итд). Как это сделать...

Присвоить значение наименьшего элемента массива переменной М1, номер строки, где находится этот элемент, - переменной Т, номер столбца - переменной С - C++
Массив С действительных чисел имеет 5 строк и 11 столбцов. Присвоить значение наименьшего элемента массива переменной М1, номер строки, где...

Присвоить переменной К номер элемента массива, равно заданному числу. - C++
Задан массив целых чисел X, упорядоченный по возрастанию, а также целое число Y. Присвоить переменной К номер того элемента массива Х,...

по адресу получить значение - C++
Господа создаю программу которая задаёт значение и показывает адрес ячейке , запускаю её и в другой программе в исходник пишу этот адрес ,...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
30.09.2009, 06:36
Ответ Создать тему
Опции темы

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