Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/70: Рейтинг темы: голосов - 70, средняя оценка - 4.73
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
1

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

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

Author24 — интернет-сервис помощи студентам
Всем привет!
У меня путаница вышла со всем этим разнообразием типов данных в С++.
Вообще, тип 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 написаны в одной строке, то что...ОНИ ОДИНАКОВЫ???

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

Ошибка в типах данных?!
Есть строка вида 3е-07 15, разбиваю split и записываю значение в ячейку. Но записывается значение...

Ошибка в типах данных
Нужно составить условие вида: if abs(c-m) = abs(m-a) and abs(d-k)= abs(k-b)then writeln ('Точка...

Различия в типах данных
Создаю БД MySQL 5.5. Для текстовых полей я нашел 4 типа: -char; -text; -varchar. Объясните...

Биты в типах данных
У меня такая проблема: например есть две переменных типа short (16 bit) x1 и x2, и пусть x1 = 55,...

42
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
02.11.2009, 20:31 2
По умолчанию int означает то же, что и long int (раньше, кстати, было short int, потом перепилили). На архитектуре x86 double - самый крутой из встроенных типов с плавающей точкой. long double на этой архитектуре означает то же, что и double (хотя в некоторых вариантах long double - это 10-байтовое число с плавающей точкой). Этот тип никому не должен занимать 3 машинных слова.
1
125 / 116 / 17
Регистрация: 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
Естественно это длинна в байтах
1
Эксперт С++
7175 / 3234 / 81
Регистрация: 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
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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'а (что НЕ противоречит стандарту). Иногда бывает, что это настраивается по опции. Так что присоединяюсь к вопросу предыдущего оратора: что у тебя за компилятор?
1
Эксперт С++
7175 / 3234 / 81
Регистрация: 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 байта.
1
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
02.11.2009, 22:44 7
Цитата Сообщение от odip Посмотреть сообщение
Чего-то мне не попадались такие компиляторы - везде было sizeof(long double) == 10.
GCC 4.3.4, sizeof(long double) == 12
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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 байта.
Дырка между двумя полями вычисляется исходя из размера второго поля, а не первого
1
125 / 116 / 17
Регистрация: 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 у такой структуры!
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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 что-то написано).
1
125 / 116 / 17
Регистрация: 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.

Ну и, пожалуй, на этом всё. А то мы и так уже далеко ушли от темы...
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
03.11.2009, 11:16 12
Это уже больше похоже на извраты конкретного компилятора, а не особенности языка Си\Си++
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
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
Находится таблица со всеми возможными типами данных, но как её прочитать (эту таблицу) я что-то
не пойму.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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" поддерживаются не всеми компиляторами (но подавляющим большинством)
2
Эксперт С++
7175 / 3234 / 81
Регистрация: 17.06.2009
Сообщений: 14,164
03.11.2009, 15:36 15
Насчет 64-битных все прогнал - нужно брать int64_t
Или __int64 для Visual Studio.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
03.11.2009, 15:37 16
Что именно прогнал?
0
Эксперт С++
7175 / 3234 / 81
Регистрация: 17.06.2009
Сообщений: 14,164
03.11.2009, 15:38 17
GCC 4.3.4, sizeof(long double) == 12
Сейчас соберу gcc посвежее, проверю
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
03.11.2009, 15:38 18
Цитата Сообщение от odip Посмотреть сообщение
Сейчас соберу gcc посвежее, проверю
Программные соглашения написаны много лет назад и от свежести компилятора не зависят
0
Эксперт С++
7175 / 3234 / 81
Регистрация: 17.06.2009
Сообщений: 14,164
03.11.2009, 15:40 19
Хочешь 64-битный тип - лучше используй int64_t, чем некий long long.

Добавлено через 1 минуту
2Evg: Меня не интересует упаковка long double в структуры, которую ты пытаешься проверить.
Меня интересует сколько реально занимает тип long double.
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
03.11.2009, 15:42  [ТС] 20
Evg

То есть всё это, что ты написал, полностью соответствует той таблице?
==============================================================================
P.s
Типы "long long" и им подобные у меня не работают. Проверял. Создать переменную такого типа
не получается; пишет, что некорректно. (illegal).
0
03.11.2009, 15:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.11.2009, 15:42
Помогаю со студенческими работами здесь

Ошибка в типах данных
Здравствуйте. Помогите пожалуйста исправить ошибки в коде var p,it,a,m,b:integer; Procedure...

видимо путаюсь в типах данных
Здравствуйте. Для понимая о чем говорим: #include &lt;iostream&gt; #include &lt;ctype.h&gt; #include...

Макрос. Ошибка в типах данных
Помогите исправить ошибку. В Макросе ошибка на выделенной строке и пишет несоответвие типов. Sub...

Ошибка в типах данных extended и string
Делаю программку на подобии теста, необходимо считывать тексты из нескольких Edit'ов и если они...


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

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