Elite Games - Свобода среди звезд!
.
ВНИМАНИЕ!
Наша конференция посвящена космической тематике и компьютерным играм.
Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!

  » Чугунку про Си | страница 1
Конференция предназначена для общения пилотов. Для удобства она разделена на каналы, каждый из которых посвящен определенной игре. Пожалуйста, открывайте темы только в соответствующих каналах и после того, как убедитесь, что данный вопрос не обсуждался ранее.

Поиск | Правила конференции | Фотоальбом | Регистрация | Список пилотов | Профиль | Войти и проверить личные сообщения | Вход

   Страница 1 из 1
 
Поиск в этой теме:
Железный канал: «Чугунку про Си»
_RAZAAR_
 147 EGP


Рейтинг канала: 2(11)
Репутация: -17
Сообщения: 2840 Предупреждений: 1
Откуда: РАЗААРЪ - 40Лы от Лаве
Зарегистрирован: 15.04.2008
Такой пример

 Cкрытый текст   (кликните здесь для просмотра)
main()
{
float arr[]{ 0.1f, 0.2f, 3.0f };
printf("%i", (int)&arr[2] - (int)&arr[0]);
return 0;
}


что не нравится компилятору?

 Cкрытый текст   (кликните здесь для просмотра)
$ g++ L6_6.cpp -o L6_6
L6_6.cpp: In function ‘int main()’:
L6_6.cpp:6:15: error: cast from ‘float*’ to ‘int’ loses precision [-fpermissive]
6 | printf("%i", (int)&arr[2] - (int)&arr[0]);
| ^~~~~~~~~~~~
L6_6.cpp:6:30: error: cast from ‘float*’ to ‘int’ loses precision [-fpermissive]
6 | printf("%i", (int)&arr[2] - (int)&arr[0]);
| ^~~~~~~~~~~~

_________________
Quaere Vērum
------------------------
    Добавлено: 21:46 18-03-2021   
Grebomet
 1438 EGP


Модератор
Рейтинг канала: 7(717)
Репутация: 273
Сообщения: 4721
Откуда: Питербурх
Зарегистрирован: 06.01.2003
_RAZAAR_ :
что не нравится компилятору?

Ну он же тебе написал: не нравится, что ты приводишь указатель на флоаты к инту.

Начнем с того, что инт - это число со знаком. Причем на 64-битной машине он частенько бывает 32-битным (привет винде и ее модели памяти).
А указатель - это беззнаковая величина. В 64-битной программе он равен 64 битам (указатель на член класса может быть и больше).

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

64 бита беззнаковых не влезают в int, а даже если и влезают, то арифметика с такими интами чревата граблями. Вот тебе компилятор и не дает нагородить граблей.

Собственно, а что ты хотел получить? Размер двух флоатов в памяти? Это можно сделать так:

Код:
float arr[] {0.1f, 0.2f};
std::cout << sizeof(arr) << std::endl;


А если тебе надо именно через адресную арифметику, то как-то так:

Код:
float arr[] {0.1f, 0.2f, 0.3f};
std::cout << ((char*)(&arr[2]) - (char*)(&arr[0])) << std::endl;

_________________
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.

Последний раз редактировалось: Grebomet (00:47 19-03-2021), всего редактировалось 1 раз
    Добавлено: 00:43 19-03-2021   
AnrDaemon
 847 EGP


Модератор
Рейтинг канала: 8(760)
Репутация: 37
Сообщения: 12218

Зарегистрирован: 17.10.2004
А вы C и C++ не попутали?
_________________
Люблю свободный полёт... :)
    Добавлено: 01:18 19-03-2021   
Grebomet
 1438 EGP


Модератор
Рейтинг канала: 7(717)
Репутация: 273
Сообщения: 4721
Откуда: Питербурх
Зарегистрирован: 06.01.2003
Тощна! Попутали. Хы...
Но сути дела это не меняет - приводить указатель к инту не надо, его надо приводить к указателю.
_________________
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.
    Добавлено: 10:22 19-03-2021   
_RAZAAR_
 147 EGP


Рейтинг канала: 2(11)
Репутация: -17
Сообщения: 2840 Предупреждений: 1
Откуда: РАЗААРЪ - 40Лы от Лаве
Зарегистрирован: 15.04.2008
Grebomet :
Тощна! Попутали. Хы...
Но сути дела это не меняет - приводить указатель к инту не надо, его надо приводить к указателю.


Так точно! Чугунок попутал , это C++ Улыбка

Это вопрос из теста выглядел так :
Что выведет на экран приведённая ниже программа
и далее было вообще то буквально вот так:

float arr[]{ 0.1f, 0.2f, 3.0f };
printf("%i", (int)&arr[2] - (int)&arr[0]);


предполагается показать число являющееся разностью указателей адресов элементов массива?
Видимо число байт между начальным адресом элемента 2 и начальным адресом элемента 0?
то-есть размер двух первых элементов массива вместе?
я правильно понимаю?

& -это address pointer?
_________________
Quaere Vērum
------------------------

Последний раз редактировалось: _RAZAAR_ (12:09 20-03-2021), всего редактировалось 1 раз
    Добавлено: 12:07 20-03-2021   
Grebomet
 1438 EGP


Модератор
Рейтинг канала: 7(717)
Репутация: 273
Сообщения: 4721
Откуда: Питербурх
Зарегистрирован: 06.01.2003
_RAZAAR_ :
предполагается показать число являющееся разностью указателей адресов элементов массива?

Ну видимо да. Других вариантов как-то маловато.
Просто тестирующие, как обычно, спешили и не проверили свой код в реальных условиях.
Настоящие пацаны используют адресную арифметику на указателях и не парятся. Точнее, парятся только размерами типа, на который указывает указатель.

_RAZAAR_ :
& -это address pointer?

Это оператор взятия адреса.
_________________
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.
    Добавлено: 15:05 20-03-2021   
_RAZAAR_
 147 EGP


Рейтинг канала: 2(11)
Репутация: -17
Сообщения: 2840 Предупреждений: 1
Откуда: РАЗААРЪ - 40Лы от Лаве
Зарегистрирован: 15.04.2008
а на это

 Cкрытый текст   (кликните здесь для просмотра)
#include "stdio.h"

main()
{
float arr[]{ 0.1f, 0.2f, 3.0f };
printf((char*)(&arr[2]) - (char*)(&arr[0]));
}


ругает вот так


 Cкрытый текст   (кликните здесь для просмотра)
$ g++ tst61.cpp -o tst61
tst61.cpp: In function ‘int main()’:
tst61.cpp:6:25: error: invalid conversion from ‘long int’ to ‘const char*’ [-fpermissive]
6 | printf((char*)(&arr[2]) - (char*)(&arr[0]));
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
| |
| long int
In file included from tst61.cpp:1:
/usr/include/stdio.h:200:13: note: initializing argument 1 of ‘int printf(const char*, ...)’
200 | int printf (const char *__restrict, ...)
| ^~~~~~~~~~~~

_________________
Quaere Vērum
------------------------
    Добавлено: 00:36 21-03-2021   
Grebomet
 1438 EGP


Модератор
Рейтинг канала: 7(717)
Репутация: 273
Сообщения: 4721
Откуда: Питербурх
Зарегистрирован: 06.01.2003
_RAZAAR_ :
printf((char*)(&arr[2]) - (char*)(&arr[0]));

Строку формата забыл: printf("%как", что);
_________________
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.
    Добавлено: 01:09 21-03-2021   
_RAZAAR_
 147 EGP


Рейтинг канала: 2(11)
Репутация: -17
Сообщения: 2840 Предупреждений: 1
Откуда: РАЗААРЪ - 40Лы от Лаве
Зарегистрирован: 15.04.2008
Grebomet :
_RAZAAR_ :
printf((char*)(&arr[2]) - (char*)(&arr[0]));

Строку формата забыл: printf("%как", что);


Да так точно забыл
ответ 8 - тоесть размер двух элементов этого массива
из трёх флоат чисел 8 байт тоесть один элемент занимает 4 байта (32бит)?
или это размер одного элемента 8 байт?
_________________
Quaere Vērum
------------------------
    Добавлено: 10:50 21-03-2021   
Grebomet
 1438 EGP


Модератор
Рейтинг канала: 7(717)
Репутация: 273
Сообщения: 4721
Откуда: Питербурх
Зарегистрирован: 06.01.2003
Это размер двух элементов. Флоаты - это 32-битная величина, поэтому 4 байта каждый.

Если точнее, то это расстояние между элементами в массиве. Результат тот же, но семантика сильно другая. Улыбка

И вообще так лучше не делать, ибо есть прекрасный оператор sizeof, который определяет размер любого типа еще на этапе компиляции. Т.е. достаточно вывести sizeof(float)*2 и никаких массивов заводить не надо.
_________________
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.
    Добавлено: 13:07 21-03-2021   
_RAZAAR_
 147 EGP


Рейтинг канала: 2(11)
Репутация: -17
Сообщения: 2840 Предупреждений: 1
Откуда: РАЗААРЪ - 40Лы от Лаве
Зарегистрирован: 15.04.2008
Grebomet :
Это размер двух элементов. Флоаты - это 32-битная величина, поэтому 4 байта каждый.

Если точнее, то это расстояние между элементами в массиве. Результат тот же, но семантика сильно другая. Улыбка

И вообще так лучше не делать, ибо есть прекрасный оператор sizeof, который определяет размер любого типа еще на этапе компиляции. Т.е. достаточно вывести sizeof(float)*2 и никаких массивов заводить не надо.


Ну видимо да, просто урок конкретно по массивам был 9 вопросов теста и вот только один както криво афтор составил ну или спецом с подвохом был чтоб тестируемый задумался лучше.
чесно говоря еслиб все вопросы с подвохом были толку наверно от них былобы больше..

и еррор лог компилятора невнятный
cast from ‘float*’ to ‘int’ loses precision
по нему выходит что я пытаюсь конвертировать когда
из этой строчки printf("%i", (int)&arr[2] - (int)&arr[0]); явно видно что никаких конвертаций указывая адрес а не значение элемента быть недолжно.
оно что вообще работать небудет или гдето с синтаксисом чтото?
вот так компилируется
printf("%i", (&arr[2]) - (&arr[0]))
но ответ 2 непонятен, почему эта запись означает что между элементом ноль и элементом два - 2 елемента массива?
их то там два но я же вроде говорю дать мне разность адресов этих илементов? или нет?
адрес элементов массива в конечном итоге разве может быть чемто иным кроме адреса и конкретного типа числа которым он представлен?
_________________
Quaere Vērum
------------------------
    Добавлено: 16:21 21-03-2021   
Grebomet
 1438 EGP


Модератор
Рейтинг канала: 7(717)
Репутация: 273
Сообщения: 4721
Откуда: Питербурх
Зарегистрирован: 06.01.2003
_RAZAAR_ :
и еррор лог компилятора невнятный
cast from ‘float*’ to ‘int’ loses precision
по нему выходит что я пытаюсь конвертировать когда
из этой строчки printf("%i", (int)&arr[2] - (int)&arr[0]); явно видно что никаких конвертаций указывая адрес а не значение элемента быть недолжно.

Он ругается на конкретно вот эту конструкцию: (int)&arr[x].
Результат операции arr[x] - это float.
Результат операции &arr[x] - это float*.
А дальше идет попытка привести указатель к инту: (int)&arr[x].
Вот это-то приведение и чревато потерей значимых бит.

_RAZAAR_ :
оно что вообще работать небудет или гдето с синтаксисом чтото?

Работать оно будет, но не во всех случаях. В тех случаях, когда значимые биты адреса перестанут влезать в 31 бит инта, начнутся интересные глюки: отрицательные значения инта или вообще обрезанная половина адреса.
Посему это и сделали ошибкой компиляции.

_RAZAAR_ :
вот так компилируется
printf("%i", (&arr[2]) - (&arr[0]))
но ответ 2 непонятен, почему эта запись означает что между элементом ноль и элементом два - 2 елемента массива?

Именно так, 2 элемента массива. Добро пожаловать в адресную арифметику, сынок. Улыбка

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

Код:
int *pointerToInt = 0;
printf("%p\n", ++pointerToInt ); // выведет 0х0000004, т.к. размер инта - 4.

double *pointerToDouble = 0;
printf("%p\n", ++pointerToDouble ); // выведет 0х0000008, т.к. размер дабла - 8.

char *pointerToChar = 0;
printf("%p\n", ++pointerToChar ); // выведет 0х0000001, т.к. размер чара - 1.

void *pointerToVoid = 0;
printf("%p\n", ++pointerToVoid ); // не скомпилируется. У типа void нет размера,
// посему нельзя узнать, на сколько байт его увеличивать.

_________________
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.
    Добавлено: 18:10 21-03-2021   
_RAZAAR_
 147 EGP


Рейтинг канала: 2(11)
Репутация: -17
Сообщения: 2840 Предупреждений: 1
Откуда: РАЗААРЪ - 40Лы от Лаве
Зарегистрирован: 15.04.2008
a почему
float *pointerToFloat = 0;
printf("%p\n", ++pointerToFloat ); // размер флоата 32 бита а не 64?
это ограничение?

или double тоже можно использовать как флоат?
_________________
Quaere Vērum
------------------------
    Добавлено: 16:36 23-03-2021   
Dimaxx
 949 EGP


Рейтинг канала: 8(856)
Репутация: 204
Сообщения: 5684
Откуда: Северодвинск
Зарегистрирован: 26.06.2002
float одинарная точность (32 бита), double - двойная (64 бита).

В расчетах - конечно можно, во float будет потеря точности.
_________________
"Если мы не покончим с войной, война покончит с нами." Г. Г. Уэллс
    Добавлено: 17:22 23-03-2021   
Grebomet
 1438 EGP


Модератор
Рейтинг канала: 7(717)
Репутация: 273
Сообщения: 4721
Откуда: Питербурх
Зарегистрирован: 06.01.2003
На всякий случай: в double тоже будет потеря точности, т.к. числа с плавающей точкой приблизительные. Улыбка
Просто на флоатах оно вылазит раньше и резче, чем на даблах. А еще в интелах математический сопроцессор внутри себя оперирует 80-битными числами, что еще немножко скрывает сию фундаментальную проблему.
_________________
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.
    Добавлено: 20:59 23-03-2021   
Железный канал: «Чугунку про Си»
 
  
Показать: 
Предыдущая тема | Следующая тема |
К списку каналов | Наверх страницы
Цитата не в тему: ...пока я склонял их к сожительству, громко вопили "By the Split!" а потом отправлялись в пешее эротическое путешествие по галактике(Joker_SE о пиратах в Х2)

  » Чугунку про Си | страница 1
Каналы: Новости | Elite | Elite: Dangerous | Freelancer | Star Citizen | X-Tension/X-BTF | X2: The Threat | X3: Reunion | X3: Terran Conflict | X Rebirth | X4: Foundations | EVE Online | Orbiter | Kerbal Space Program | Evochron | VoidExpanse | Космические Миры | Онлайновые игры | Другие игры | Цифровая дистрибуция | play.elite-games.ru | ЗВ 2: Гражданская война | Творчество | Железо | Игра Мечты | Сайт
   Дизайн Elite Games V5 beta.18