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

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 55, средняя оценка - 4.67
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
#1

Вопрос о типах данных С++ - C++

02.11.2009, 20:16. Просмотров 7114. Ответов 42
Метки нет (Все метки)

Всем привет!
У меня путаница вышла со всем этим разнообразием типов данных в С++.
Вообще, тип long double должен занимать 3 машинных слова (или 12 байт).
Но вот когда я пишу :
C++
1
2
3
4
5
6
7
#include <iostream.h>
#include <cstddef>
void main() {
    long double qq=10;
    size_t qwer=sizeof qq;
    cout <<qwer <<endl;
}
то в результате выводится значение 8. А почему???

И вот я ещё нашел кое-что по типам данных :
http://www.cppreference.com/wiki/ru/data_types
Как понимать таблицу в пункте "Модификаторы типа"?
Если типы long и long int написаны в одной строке, то что...ОНИ ОДИНАКОВЫ???

Спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.11.2009, 20:16     Вопрос о типах данных С++
Посмотрите здесь:
видимо путаюсь в типах данных C++
C++ Вычислить значение выражения при различных вещественных типах данных
Вычислить значение выражения при различных вещественных типах данных C++
C++ Вычислить значение выражения при различных вещественных типах данных (float и double)
C++ Запутался в типах
C++ Наследование в шаблонных типах
C++ Распаковка parameter pack в наследуемых типах
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1608 / 1000 / 118
Регистрация: 27.09.2009
Сообщений: 1,930
Завершенные тесты: 1
02.11.2009, 20:31     Вопрос о типах данных С++ #2
По умолчанию int означает то же, что и long int (раньше, кстати, было short int, потом перепилили). На архитектуре x86 double - самый крутой из встроенных типов с плавающей точкой. long double на этой архитектуре означает то же, что и double (хотя в некоторых вариантах long double - это 10-байтовое число с плавающей точкой). Этот тип никому не должен занимать 3 машинных слова.
АНК
124 / 115 / 2
Регистрация: 27.02.2007
Сообщений: 291
02.11.2009, 20:35     Вопрос о типах данных С++ #3
Цитата Сообщение от gromo Посмотреть сообщение
У меня путаница вышла со всем этим разнообразием типов данных в С++.
Вот что дал Bulder 6
sizeof(int): 4
sizeof(__int64): 8
sizeof(long): 4
sizeof(float): 4
sizeof(double): 8
sizeof(long double): 10
sizeof(char): 1
sizeof(short): 2
Естественно это длинна в байтах
odip
Эксперт С++
7156 / 3296 / 59
Регистрация: 17.06.2009
Сообщений: 14,164
02.11.2009, 21:55     Вопрос о типах данных С++ #4
2gromo: Что у тебя за компилятор и что за OC ?

тип long double обычно занимает 10 байт, что соответствует внутреннему формату сопроцессора.

По умолчанию int означает то же, что и long int (раньше, кстати, было short int, потом перепилили).
Язык C требует чтобы было: sizeof(char)<=sizeof(short int)<=sizeof(int)<=sizeof(long).
Обычно для 32-bit:
sizeof(short int)==2
sizeof(int)==4
sizeof(long)==4

Для 64-bit:
sizeof(short int)==2
sizeof(int)==4
sizeof(long)==8
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
02.11.2009, 22:18     Вопрос о типах данных С++ #5
Аналогично стандарт не накладывает никаких обязательств на реализацию типов float, double и long double. На большинстве архитектур float и double делаются соответственно 32- и 64-битными и работают в стандарте IEEE-754. Что касается long double - то он по разному сделан. Для intel'а как правило sizeof (long double) равен 12 (т.е. 96 бит), при этом 80 бит являются значащими, а 16 бит не используются (нужны как padding для выравнивания). Но некоторые компиляторы не умеют работать с long double и трактуют тип long double как эквивалент double'а (что НЕ противоречит стандарту). Иногда бывает, что это настраивается по опции. Так что присоединяюсь к вопросу предыдущего оратора: что у тебя за компилятор?
odip
Эксперт С++
7156 / 3296 / 59
Регистрация: 17.06.2009
Сообщений: 14,164
02.11.2009, 22:41     Вопрос о типах данных С++ #6
Для intel'а как правило sizeof (long double) равен 12 (т.е. 96 бит), при этом 80 бит являются значащими, а 16 бит не используются (нужны как padding для выравнивания).
Чего-то мне не попадались такие компиляторы - везде было sizeof(long double) == 10.
Да и АНК тоже самое пишет.
Выравнивание будет производиться, если ты начнешь структуру делать типа такой:
struct {
int i0;
long double ld0;
int i1;
}
Тогда очевидно что между ld0 и i1 по умолчанию будет добавлено 2 байта.
Gravity
562 / 556 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
02.11.2009, 22:44     Вопрос о типах данных С++ #7
Цитата Сообщение от odip Посмотреть сообщение
Чего-то мне не попадались такие компиляторы - везде было sizeof(long double) == 10.
GCC 4.3.4, sizeof(long double) == 12
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
02.11.2009, 22:52     Вопрос о типах данных С++ #8
Проверил в борландовском компиляторе - и вправду там размер 10. Если написать структуру из двух long double'ов, то sizeof будет 24. Если структуру из long double и двух char'ов, то sizeof будет 16. Исходя из этого получается что всё-таки отводится 12 байт. При этом то, что sizeof от long double'а выдаётся как 10 - на мой взгляд это косяк

Цитата Сообщение от odip Посмотреть сообщение
Тогда очевидно что между ld0 и i1 по умолчанию будет добавлено 2 байта.
Дырка между двумя полями вычисляется исходя из размера второго поля, а не первого
АНК
124 / 115 / 2
Регистрация: 27.02.2007
Сообщений: 291
02.11.2009, 23:34     Вопрос о типах данных С++ #9
Цитата Сообщение от Evg Посмотреть сообщение
Если написать структуру из двух long double'ов, то sizeof будет 24. Если структуру из long double и двух char'ов, то sizeof будет 16.
А выравнивание данных надо бы поставить по-байтное. Тогда у структуры из двух long double'ов sizeof будет 20. А то можно получить sizeof и 32 у такой структуры!
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
02.11.2009, 23:44     Вопрос о типах данных С++ #10
Цитата Сообщение от АНК Посмотреть сообщение
А выравнивание данных надо бы поставить по-байтное. Тогда у структуры из двух long double'ов sizeof будет 20.
Я не знаю, как это на брланде и микрософте делать, но на gcc результаты такие

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 <conio.h>
 
int main (void)
{
    struct s1 { long double a[2]; };
    struct s2 { long double a1, a2; };
    struct s3 { long double a[2]; } __attribute__((packed));
    struct s4 { long double a1, a2; } __attribute__((packed));
    struct s5 { long double a; char c; };
    struct s6 { long double a; char c; } __attribute__((packed));
    printf ("%d\n", sizeof(struct s1));
    printf ("%d\n", sizeof(struct s2));
    printf ("%d\n", sizeof(struct s3));
    printf ("%d\n", sizeof(struct s4));
    printf ("%d\n", sizeof(struct s5));
    printf ("%d\n", sizeof(struct s6));
    getch();
    return 0;
}
Код
24
24
24
24
16
13
Добавлено через 1 минуту
Цитата Сообщение от АНК Посмотреть сообщение
Тогда у структуры из двух long double'ов sizeof будет 20. А то можно получить sizeof и 32 у такой структуры!
Поля в структуре раскладываются не кому как захочется, а СТРОГО по программным соглашениям на архитектуру. Все компиляторы должны это делать одинаково (правда для упакованных полей наврядли в ABI что-то написано).
АНК
124 / 115 / 2
Регистрация: 27.02.2007
Сообщений: 291
03.11.2009, 09:06     Вопрос о типах данных С++ #11
Цитата Сообщение от Evg Посмотреть сообщение
Поля в структуре раскладываются не кому как захочется, а СТРОГО по программным соглашениям на архитектуру
Абсолютно с вами согласен!

Параметрами выравнивания у компилятора Борланда можно управлять опцией -аХХ. По умолчанию стоит -а4, т.е. 10-байтные элементы в структурах выравниваются до 12-и байт.

Если поставить -а8, то для следующего примера
C++
1
2
3
4
5
6
7
8
9
10
  long double ld[2] = {0};
 
  struct {
    long double dd[2];
  } val;
 
  struct {
    long double d1;
    long double d2;
  } val2;
результат будет
sizeof(ld)=20
sizeof(val)=24
sizeof(val2)=32
А этой опцией можно управлять через окно Project Options на закладке Advanced Compiler.

Ну и, пожалуй, на этом всё. А то мы и так уже далеко ушли от темы...
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
03.11.2009, 11:16     Вопрос о типах данных С++ #12
Это уже больше похоже на извраты конкретного компилятора, а не особенности языка Си\Си++
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
03.11.2009, 12:33  [ТС]     Вопрос о типах данных С++ #13
Компилятор у меня Microsoft Visual C++ 6.0.
Я просто сейчас изучаю преобразования типов и в книге говорится о таких типах, о
которых в предыдущих главах не было ни слова. Например, цитата из книги:

При приведении к целому типы char, signed char, unsigned char и short int
преобразуются в int. Тип unsigned short int трансформируется в int, если этот тип
достаточен для представления всего диапазона значений unsigned short int (обычно
это происходит в системах, отводящих полслова под short и целое слово под int), в
противном случае unsigned short int заменяется на unsigned int.
Я думал, что тип char может быть только unsigned char и signed char. А здесь говорится о char,
signed char и unsigned char как о трёх разных типах. И ещё какой-то тип unsigned short int.
Я не могу просто понять какие комбинации из ключевых слов можно составлять, чтобы получились
типы данных.

Добавлено через 15 минут
По ссылке http://www.cppreference.com/wiki/ru/data_types
Находится таблица со всеми возможными типами данных, но как её прочитать (эту таблицу) я что-то
не пойму.
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
03.11.2009, 13:38     Вопрос о типах данных С++ #14
Цитата - какой-то бред. Либо выдрано из контекста и какие-то слова, не попавшие в цитату, могут прояснить ситуацию. Но я склоняюсь к тому, что это бред

Целые типы бывают знаковые и беззнаковые. Можно записывать по разному (одно из фривольностей языка Си). Для начала считай, что типы бывают следующие (со временем поймёшь, как оно на самом деле). В каждой строке несколько вариантов записи одного и того же типа, на первом месте ставлю наиболее употребительный

char, signed char: 8-битное знаковое
unsigned char: 8-битное беззнаковое
short, short int, signed short, signed short int: 16-битное знаковое
unsigned short, unsigned short int: 16-битное беззнаковое
int, signed int: 32-битное знаковое
unsigned, unsigned int: 32-битное беззнаковое
long, long int, signed long, signed long int: 32-битное знаковое для кодов с 32-битным режимом адресации и 64-битное знаковое для кодов с 64-битным режимом адресации
unsigned long, unsigned long int: 32-битное беззнаковое для кодов с 32-битным режимом адресации и 64-битное беззнаковое для кодов с 64-битным режимом адресации
long long, long long int, signed long long, signed long long int - 64-битное знаковое
unsigned long long, unsigned long long int - 64-битное беззнаковое

При этом типы "long long" поддерживаются не всеми компиляторами (но подавляющим большинством)
odip
Эксперт С++
7156 / 3296 / 59
Регистрация: 17.06.2009
Сообщений: 14,164
03.11.2009, 15:36     Вопрос о типах данных С++ #15
Насчет 64-битных все прогнал - нужно брать int64_t
Или __int64 для Visual Studio.
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
03.11.2009, 15:37     Вопрос о типах данных С++ #16
Что именно прогнал?
odip
Эксперт С++
7156 / 3296 / 59
Регистрация: 17.06.2009
Сообщений: 14,164
03.11.2009, 15:38     Вопрос о типах данных С++ #17
GCC 4.3.4, sizeof(long double) == 12
Сейчас соберу gcc посвежее, проверю
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
03.11.2009, 15:38     Вопрос о типах данных С++ #18
Цитата Сообщение от odip Посмотреть сообщение
Сейчас соберу gcc посвежее, проверю
Программные соглашения написаны много лет назад и от свежести компилятора не зависят
odip
Эксперт С++
7156 / 3296 / 59
Регистрация: 17.06.2009
Сообщений: 14,164
03.11.2009, 15:40     Вопрос о типах данных С++ #19
Хочешь 64-битный тип - лучше используй int64_t, чем некий long long.

Добавлено через 1 минуту
2Evg: Меня не интересует упаковка long double в структуры, которую ты пытаешься проверить.
Меня интересует сколько реально занимает тип long double.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.11.2009, 15:42     Вопрос о типах данных С++
Еще ссылки по теме:
C++ Вопрос по вводу данных
Опишите промежутки чисел и символов при разных типах C++
Вопрос по передаче данных в функции C++
C++ Вычислить значение выражения при различных вещественных типах данны
Глупый вопрос по типу данных Variant C++

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

Или воспользуйтесь поиском по форуму:
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
03.11.2009, 15:42  [ТС]     Вопрос о типах данных С++ #20
Evg

То есть всё это, что ты написал, полностью соответствует той таблице?
==============================================================================
P.s
Типы "long long" и им подобные у меня не работают. Проверял. Создать переменную такого типа
не получается; пишет, что некорректно. (illegal).
Yandex
Объявления
03.11.2009, 15:42     Вопрос о типах данных С++
Ответ Создать тему
Опции темы

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