Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
VN
 Аватар для VN
0 / 0 / 0
Регистрация: 14.12.2011
Сообщений: 90

Как осуществляется преобразование типов (для чего)?

14.01.2012, 02:35. Показов 2683. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как осуществляется преобразование типов (для чего)?

int *p=(int*)str; // ругается на p

Спасибо
P.s Си
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.01.2012, 02:35
Ответы с готовыми решениями:

Для чего в приведенном коде используется преобразование типов
if (choose==7){ printf ("Проверим составное или простое число при k=18\n"); k=18; a=4*(k+3)+1; printf("4(k+3)+1=...

Преобразование типов double в int для задания размерности массива
Объясните, пожалуйста. Не объявляется массив, хотя его размеры объявил как константы. // #ifndef M_PI #define M_PI...

Преобразование типов, как понять фразу из учебника
В книжке "Язык программирования C++" (Липпман) есть такой абзац. Не могу разобраться остаток от деления по модулю каких чисел берется? ...

19
 Аватар для Gepar
1186 / 543 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
14.01.2012, 02:50
VN, преобразование типов необходимо не столь часто, более разумный пример тебе
C
1
char *c=(char*) malloc(sizeof(char)*1);
Здесь без преобразования типов не обойтись так как malloc возвращает просто выделенную память в виде указателя на void, в переменной указатель на char мы собираемся хранить переменную типа char, а не просто кусок памяти поэтому и нужно сделать преобразование. Конечно мы можем сделать так
C
1
void *c=malloc(sizeof(char)*1);
Но теперь мы будем сильно ограничены в действиях с переменной с потому как все операции с типом char нам теперь не доступны.
В твоём примере компилятор ругается не на p, а на то что ты преобразовывать собрался что-то не правильно и из твоего str тип int* не сделать.
0
VN
 Аватар для VN
0 / 0 / 0
Регистрация: 14.12.2011
Сообщений: 90
14.01.2012, 03:13  [ТС]
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include  <stdlib.h>
 
 
 
 
 int main ()
{
    int str[2][16]={{0,4,4,3,4,3},{8,3,4,2,4,4,4}};
    int (*p)[2]=(int(*)[2])str;
 
 
  return(0);
}
что в данном случае происходит ? Cмотрел по отладке не понял почему указатель ссылается на 0,4 (после преобразования ).
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
14.01.2012, 05:40
Цитата Сообщение от Gepar Посмотреть сообщение
VN, преобразование типов необходимо не столь часто, более разумный пример тебе
C
1
char *c=(char*) malloc(sizeof(char)*1);
Здесь без преобразования типов не обойтись так как malloc возвращает просто выделенную память в виде указателя на void, в переменной указатель на char мы собираемся хранить переменную типа char, а не просто кусок памяти поэтому и нужно сделать преобразование.
На самом деле в С всё совсем не так!
C
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
#include <stdio.h>
#include <stdlib.h>
 
int main(void){
    int len = 16, i;
    char * buf = malloc(len);
    
    if ( ! buf ){
        perror("malloc");
        exit(1);
    }
    
    for ( i = 0; i < len-1; ++i )
        buf[i] = 'a' + i;
    buf[i] = 0;
    printf("%s\n", buf);
    
    /* мало того, так тоже отработает */
    for ( i = 0; i < len / sizeof(int); ++i )
        printf("%#x\n", ((int*)buf)[i]);
    
    free(buf);
    
    exit(0);
}
Code
1
2
3
4
5
6
7
8
~/cpp/other $ gcc -o void void.c 
~/cpp/other $ ./void 
abcdefghijklmno
0x61626364
0x65666768
0x696a6b6c
0x6d6e6f00
~/cpp/other $
Вот в С++ так работать не будет
Code
1
2
3
4
~/cpp/other $ g++ -o void++ void.c
void.c: In function 'int main()':
void.c:6: error: invalid conversion from 'void*' to 'char*'
~/cpp/other $
но ТС про С спрашивал...

Цитата Сообщение от VN Посмотреть сообщение
int *p=(int*)str; // ругается на p
Просто из любопытства - а Вы этим чего добиться хотели?
0
278 / 174 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 05:46
Цитата Сообщение от VN Посмотреть сообщение
что в данном случае происходит ?
C++
1
int (*p)[2] = int(*)[2])str;
присоединяюсь к вопросу.
В моем понимании так.
- объявляется указатель на на массив типа int состоящий из двух элементов
- матрица приводится (временно перобразуется) к одномерному массиву состоящему из двух элементов и берется адрес первого элемента патрицы.
- адрес из второго пункта присваивается указателю на массив int из двух элементов
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 05:56
Цитата Сообщение от greeezz Посмотреть сообщение
матрица приводится (временно перобразуется) к одномерному массиву состоящему из двух элементов и берется адрес первого элемента патрицы.
Только к указателю на одномерный массив. Вроде.
0
278 / 174 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 06:14
Цитата Сообщение от soon Посмотреть сообщение
Только к указателю на одномерный массив. Вроде.
да, наверное вы правы.

Подождем может кто прояснит картину.
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 06:45
Тогда
вот
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include  <stdlib.h>
 
 int main ()
{
    int str[2][16]={{0,4,4,3,4,3},{8,3,4,2,4,4,4}};
    int (*p)[2]=(int(*)[2])str;
    int i;
    for(i = 0; i < 34; ++i)
        //*(*p + i) = 1;
        *(*str + i) = 1;
    return(0);
}
еще. Строка с p как и положено вылетает. А str - зацикливается. Почему так
0
278 / 174 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 08:13
Цитата Сообщение от soon Посмотреть сообщение
еще. Строка с p как и положено вылетает. А str - зацикливается. Почему так
откуда 34 то???
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
 
int main() {
    int str[2][16] = { { 0, 4, 4, 3, 4, 3 }, { 8, 3, 4, 2, 4, 4, 4 } };
    int (*p)[2] = (int(*)[2]) str;
    int i;
    for (i = 0; i < 32; ++i) {
        //*(*p + i) = 1;
        *(*str + i) = i;
    }
    for (i = 0; i < 32; ++i) {
        //*(*p + i) = 1;
        std::cout << *(*str + i) << std:: endl;
    }
    std::cin.get();
    return (0);
}
0
VN
 Аватар для VN
0 / 0 / 0
Регистрация: 14.12.2011
Сообщений: 90
14.01.2012, 10:22  [ТС]
int *p=(int*)str; // ругается на p
Просто из любопытства - а Вы этим чего добиться хотели?
Например у меня массив
int str[2][16]={{0,4,4,3,4,3},{8,3,4,2,4,4,4}};
2 по 16
а я его с помощью указателя хочу рассматривать как
16 по 2.Так как допускается создание указателя на другую размерность.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
14.01.2012, 11:06
VN, вот 16 по 2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
int main ()
{
   int str[2][16] = { 
             { 0, 4, 5, 3, 4, 3}, 
             { 8, 3, 4, 2, 4, 4, 4} 
                    };
   int (*p)[2]  = reinterpret_cast<int (*)[2]>(str);
   
   std::cout << p[1][0] << std::endl;
   return 0;
}
http://liveworkspace.org/code/... 613301a4c8
1
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 12:35
Цитата Сообщение от greeezz Посмотреть сообщение
откуда 34 то???
В gcc не смертелен выход на пределы массива +1. Ну, у меня по крайней мере.
Есть подозрение, что при данном смещении str + i натыкается на адрес i, и по нему i присваивается единица. Это хорошо видно при компилировании через g++.
Но через gcc получаются 2 ситуации, раз и два. Т.е. в случае с выводом адреса i, gcc помещает ее раньше чем str.
0
278 / 174 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 20:21
Цитата Сообщение от soon Посмотреть сообщение
В gcc не смертелен выход на пределы массива
вы пытаетесь записать данные в память которая не в ходит в диапзон вашего массива. это серьезная ошибка. этого вполне достаточно чтобы так не делать.
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 20:29
Цитата Сообщение от greeezz Посмотреть сообщение
вы пытаетесь записать данные в память которая не в ходит в диапзон вашего массива. это серьезная ошибка. этого вполне достаточно чтобы так не делать.
Я нигде не говорил, что так можно делать, я специально пытался вызвать сегфолт(уже не помню зачем), и пришел к выводу, что если не выводить адрес переменной i, то gcc поместит ее достаточно близко к str, чтобы можно было перейти на нее, просто прибавляя к str sizeof(int).
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.01.2012, 20:47
VN, преобразования типов выполнятся при всяком присваивании значений переменным, чей тип отличается от типа присваиваемых значений и при всяком вызове подпрограмм с фактическими параметрами, типы которых не совпадают с типами формальных параметров. Иногда преобразования типов явные, иногда неявные, например,
C++
1
2
3
4
5
6
double a;
int b;
a=2; // Здесь будет выполнено неявно преобразование типа
a=b; // И здесь тоже
b=(int) a; // А здесь явное
b=(int) 2.4; // И здесь тоже
.
0
186 / 186 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
15.01.2012, 05:00
В C++ лучше пользоваться static_cast'ом, а не (тип) или тип(выражение)
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
15.01.2012, 08:47
Цитата Сообщение от soon Посмотреть сообщение
В gcc не смертелен выход на пределы массива +1.
По стандарту гарантируется осмысленность значения указателя на элемент, следующий за последним элементом массива, что сделано для применимости к массивам алгоритмов STL, но разыменовывать такие указатели стандарт запрещает.
0
278 / 174 / 21
Регистрация: 10.07.2011
Сообщений: 441
15.01.2012, 10:49
soon, в разбираемом примере всего 32 индекса. от 0 до 31 включительно.
даже если следовать вашей логике о выходе на +1 это будет 32ой индекс. а ни как не 33ий как вы пытаетесь сделать вот в этом вашем примере.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include  <stdlib.h>
 
 int main ()
{
    int str[2][16]={{0,4,4,3,4,3},{8,3,4,2,4,4,4}};
    int (*p)[2]=(int(*)[2])str;
    int i;
    for(i = 0; i < 34; ++i)
        //*(*p + i) = 1;
        *(*str + i) = 1;
    return(0);
}
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
15.01.2012, 19:18
Цитата Сообщение от soon Посмотреть сообщение
В gcc не смертелен выход на пределы массива +1.
Я, возможно, не так выразился. Как я уже сказал, я намеренно пытался вызвать segmentation fault, т.е. я имел ввиду, чтобы вызвать сегфолт нужно разыменовать следующий за следующим за концом массива элемент. Смысл разымновывать ptr + size, если программа не упадет? Зачем я пытался это сделать - не помню(как я, опять-же, говорил. Ну взбрело резко в голову, мол надо вызвать сегфолт, ну и попытался). Нет смысла говорить мне о том, что так делать нельзя в реальных задачах, я это понимаю.
Суть то оказалась не в этом. Я действительно удивился, когда вместо вылета программы я получил бесконечный цикл. На первый взгляд ошибок не было(если не считать за ошибку выход за пределы массива). Поэтому я закинул его на форум и убежал по делам. Уже на выходе меня посетила мысь о возможном присваивании i = 1. Так и было. Но, как оказалось, стоит только вывести адрес i, как программа перстает циклится.
Собственно, ответ на свой вопрос я уже получил, да и от темы мы отклонились. За сим флудить прекращаю.
0
15.01.2012, 20:10

Не по теме:

soon, ну вы уж извините что мы на вас как хищники набросились. Ну не могли мы знать о чем вы подумали когда из дома выходили. :)

Цитата Сообщение от soon Посмотреть сообщение
... Ну взбрело резко...
Вспонимлся вопрос из КВН.
"А вам не приходила в голову..... стрела?!" :)

1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.01.2012, 20:10
Помогаю со студенческими работами здесь

Преобразование типов в C++: как преобразовать строку в тип double?
Здравствуйте помогите пожалуйста, необходимо преобразовать правильно тип то есть b типа double и в следующей строки тоже должно быть...

Как запретить преобразование типов при использовании cin
Как запретить преобразование типов при использовании объекта потокового ввода cin. Проблема в том, что существует переменная типа int и со...

Преобразование типов - как строку чисел перевести в целочисленный массив ?
Как строку чисел например 1343245 перевести в интовый масив.

По какому правилу осуществляется приведение типов в Java
Совсем уже запутался)) Знаю как это делать, но четко правило сформулировать не могу((( Подскажите pliz

Преобразование типов для объекта
Доброго времени суток. Хотелось бы услышать ответ на вопрос о преобразовании типов для объектов. Например, имеем объект, класса...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru