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

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

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

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

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

Спасибо
P.s Си
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.01.2012, 02:35
Ответы с готовыми решениями:

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

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

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

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

19
1186 / 543 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
14.01.2012, 02:50 2
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
0 / 0 / 0
Регистрация: 14.12.2011
Сообщений: 90
14.01.2012, 03:13  [ТС] 3
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Эксперт С++
12832 / 7569 / 1764
Регистрация: 25.07.2009
Сообщений: 13,961
14.01.2012, 05:40 4
Цитата Сообщение от 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);
}
Код
~/cpp/other $ gcc -o void void.c 
~/cpp/other $ ./void 
abcdefghijklmno
0x61626364
0x65666768
0x696a6b6c
0x6d6e6f00
~/cpp/other $
Вот в С++ так работать не будет
Код
~/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 / 173 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 05:46 5
Цитата Сообщение от VN Посмотреть сообщение
что в данном случае происходит ?
C++
1
int (*p)[2] = int(*)[2])str;
присоединяюсь к вопросу.
В моем понимании так.
- объявляется указатель на на массив типа int состоящий из двух элементов
- матрица приводится (временно перобразуется) к одномерному массиву состоящему из двух элементов и берется адрес первого элемента патрицы.
- адрес из второго пункта присваивается указателю на массив int из двух элементов
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 05:56 6
Цитата Сообщение от greeezz Посмотреть сообщение
матрица приводится (временно перобразуется) к одномерному массиву состоящему из двух элементов и берется адрес первого элемента патрицы.
Только к указателю на одномерный массив. Вроде.
0
278 / 173 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 06:14 7
Цитата Сообщение от soon Посмотреть сообщение
Только к указателю на одномерный массив. Вроде.
да, наверное вы правы.

Подождем может кто прояснит картину.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 06:45 8
Тогда
вот
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 / 173 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 08:13 9
Цитата Сообщение от 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
0 / 0 / 0
Регистрация: 14.12.2011
Сообщений: 90
14.01.2012, 10:22  [ТС] 10
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 11
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
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 12:35 12
Цитата Сообщение от greeezz Посмотреть сообщение
откуда 34 то???
В gcc не смертелен выход на пределы массива +1. Ну, у меня по крайней мере.
Есть подозрение, что при данном смещении str + i натыкается на адрес i, и по нему i присваивается единица. Это хорошо видно при компилировании через g++.
Но через gcc получаются 2 ситуации, раз и два. Т.е. в случае с выводом адреса i, gcc помещает ее раньше чем str.
0
278 / 173 / 21
Регистрация: 10.07.2011
Сообщений: 441
14.01.2012, 20:21 13
Цитата Сообщение от soon Посмотреть сообщение
В gcc не смертелен выход на пределы массива
вы пытаетесь записать данные в память которая не в ходит в диапзон вашего массива. это серьезная ошибка. этого вполне достаточно чтобы так не делать.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.01.2012, 20:29 14
Цитата Сообщение от greeezz Посмотреть сообщение
вы пытаетесь записать данные в память которая не в ходит в диапзон вашего массива. это серьезная ошибка. этого вполне достаточно чтобы так не делать.
Я нигде не говорил, что так можно делать, я специально пытался вызвать сегфолт(уже не помню зачем), и пришел к выводу, что если не выводить адрес переменной i, то gcc поместит ее достаточно близко к str, чтобы можно было перейти на нее, просто прибавляя к str sizeof(int).
0
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.01.2012, 20:47 15
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 16
В C++ лучше пользоваться static_cast'ом, а не (тип) или тип(выражение)
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
15.01.2012, 08:47 17
Цитата Сообщение от soon Посмотреть сообщение
В gcc не смертелен выход на пределы массива +1.
По стандарту гарантируется осмысленность значения указателя на элемент, следующий за последним элементом массива, что сделано для применимости к массивам алгоритмов STL, но разыменовывать такие указатели стандарт запрещает.
0
278 / 173 / 21
Регистрация: 10.07.2011
Сообщений: 441
15.01.2012, 10:49 18
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
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
15.01.2012, 19:18 19
Цитата Сообщение от soon Посмотреть сообщение
В gcc не смертелен выход на пределы массива +1.
Я, возможно, не так выразился. Как я уже сказал, я намеренно пытался вызвать segmentation fault, т.е. я имел ввиду, чтобы вызвать сегфолт нужно разыменовать следующий за следующим за концом массива элемент. Смысл разымновывать ptr + size, если программа не упадет? Зачем я пытался это сделать - не помню(как я, опять-же, говорил. Ну взбрело резко в голову, мол надо вызвать сегфолт, ну и попытался). Нет смысла говорить мне о том, что так делать нельзя в реальных задачах, я это понимаю.
Суть то оказалась не в этом. Я действительно удивился, когда вместо вылета программы я получил бесконечный цикл. На первый взгляд ошибок не было(если не считать за ошибку выход за пределы массива). Поэтому я закинул его на форум и убежал по делам. Уже на выходе меня посетила мысь о возможном присваивании i = 1. Так и было. Но, как оказалось, стоит только вывести адрес i, как программа перстает циклится.
Собственно, ответ на свой вопрос я уже получил, да и от темы мы отклонились. За сим флудить прекращаю.
0
greeezz
15.01.2012, 20:10     Как осуществляется преобразование типов (для чего)?
  #20

Не по теме:

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

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

1
15.01.2012, 20:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.01.2012, 20:10
Помогаю со студенческими работами здесь

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

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

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

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


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

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