crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
rp80
  опции профиля:
сообщение 26.10.2011, 23:35
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 10.9.2011
Пользователь №: 2860

Спасибо сказали: 0 раз(а)




Репутация:   0  


Упражнения из страуструпа. Подскажите пожалуйста все ли тут верно?

//указатель на массив char
typedef char* PARChar;

//Массив из из семи указателей на целые
typedef int* P7Aint[7];

//Указатель на массив из 7 указателей на целые
typedef int* P7PAint[7];
//То же самое, что и предыдущее ибо
    int a=3;
    P7Aint p7;
    p7[0]=&a;
    int** pp7=p7;//Указатель на массив из 7ми указателей



//Массив из 8ми массивов по 7ми указателей на целые чила
typedef int *P78int[8][7];



И еще 1 вопрос. Можно ли инициализировать тип typedef int* PT[] не списком не инициализации?
Пример:
    int* pc[6];
    pc[0]=new int[20];
    pc[0][1]=5;
//Можно ли также инициализировать и с typedef?

typedef int* PT[];
int b=5;
PT pt1={&b,&b,&b};//Ok
PT pt2=new int*[10];//Error
PT pt3[10];//Error


Спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 27.10.2011, 7:05
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата
//Указатель на массив из 7 указателей на целые
typedef int* P7PAint[7];

это неверно.

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

new int*[10] даёт указатель на массив указателей на int (тип int **), а PT - массив указателей. тут просто несоответствие типов, потому что указатель нельзя привести к массиву, можно только наоборот: адрес массива привести к указателю. это связано с выделением памяти компилятором: массивы хранятся в памяти строго последовательно и компилятор должен точно знать размер объекта. у указателя этого размера нет.

определение PT pt3[10] пытается создать массив из 10 элементов типа PT, но размер каждого элемента неизвестен заранее, а и компилятор просто не может выделить память под такой массив.

Сообщение отредактировал Iron Bug - 27.10.2011, 7:08
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 27.10.2011, 7:09
Сообщение #3


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата
//Указатель на массив из 7 указателей на целые
typedef int* P7PAint[7];


не, вот так будет правильно:

//Массив из из семи указателей на целые
typedef int* P7Aint[7];

//Указатель на массив из 7 указателей на целые
typedef P7Aint* P7PAint[7];


Сообщение отредактировал Алексей1153 - 27.10.2011, 7:09
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 27.10.2011, 7:13
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Алексей1153 @ 27.10.2011, 9:09) *
не, вот так будет правильно:

нет. это будет массив из 7 указателей на массивы из 7 указателей :) достаточно просто расставить скобки, на самом деле.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 27.10.2011, 7:28
Сообщение #5


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


ну да, звёздочка лишняя
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 27.10.2011, 8:11
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Алексей1153 @ 27.10.2011, 9:28) *
ну да, звёздочка лишняя

да не только. вообще, в принципе не то.

достаточно двух скобок в исходном выражении, чтобы стало правильно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 27.10.2011, 8:26
Сообщение #7


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Iron Bug, скобки - ну нафиг, начинается путаница с объявлением функции вечно ) А я - за простоту и читаемость

предпочитаю определить лесенку понятных типов, чем корявую многоэтажку
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 27.10.2011, 8:49
Сообщение #8


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Алексей1153 @ 27.10.2011, 10:26) *
предпочитаю определить лесенку понятных типов, чем корявую многоэтажку

это НЕ лесенка. массив указателей и указатель на массив никак не связаны меж собой. это просто разные типы. и лесенка тут совершенно никуда не упирается.
единственный способ определить указатель на массив - использовать скобки. потому что приоритет оператора [] выше приоритета взятия значения указателя *

Сообщение отредактировал Iron Bug - 27.10.2011, 8:52
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 27.10.2011, 9:12
Сообщение #9


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


а, ты про квадратные скобки ))

ну если честно, я не пользуюсь такими типами, как type[] , у меня только указатели. И я сейчас путаюсь с непривычки

под лесенкой я подразумеваю следующее: не городить в одну строчку указатель на тип-перетип, а определить конкретный тип, а затем массив элементов этого типа, либо массив указателей на этот тип. Но вот квадратных скобок в определении типа typedef у меня точно не будет

Цитата
единственный способ определить указатель на массив


нифига подобного:

int** pp; //указатель на массив указателей на int
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 27.10.2011, 9:30
Сообщение #10


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Алексей1153 @ 27.10.2011, 11:12) *
а, ты про квадратные скобки ))

нет. про круглые. и про определения массивов указателей и указателей на массивы.
и лесенки тут ни при чём.

Цитата(Алексей1153 @ 27.10.2011, 11:12) *
int** pp; //указатель на массив указателей на int

это указатель без фиксированного размера. а разговор идёт про массивы, которые называют array. компилятор с ними совсем по-другому работает. это массивы с фиксированным размером, создаваемые в стеке. и они определяются только через скобки. указатели приводятся только в одну сторону: от фиксированных к динамическим, но не наоборот. иногда имеет смысл применять фиксированные (это быстрее).

Сообщение отредактировал Iron Bug - 27.10.2011, 9:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 27.10.2011, 9:34
Сообщение #11


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Iron Bug, а покажи пример с круглыми, когда это не будет похоже на объявление типа указателя на функцию, я что-то в сомнениях ))

а небольшие массивы на стеке иногда использую, но работаю с ними через указатель и размер массива. Привычнее и нагляднее )
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
rp80
  опции профиля:
сообщение 27.10.2011, 12:08
Сообщение #12


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 10.9.2011
Пользователь №: 2860

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 27.10.2011, 8:05) *
Цитата
//Указатель на массив из 7 указателей на целые
typedef int* P7PAint[7];

это неверно.

Спасибо за ответ.

Но смотри. Первая строчка "Указатель на массив чар". char* PARChar;. У тебя возражений не вызвала. Предыдущее задание было массив чар(я не стал его писать из-за очевидности). Там, соответственно, такое же объявление: char* PChar;

Ну а далее ведь тоже самое.
int v[5];
int* pv;=v//Ok

int* P7Aint[7];//Массив указателей
int** pP7=P7Aint;//Указатель на массив указателей

//Или ты имеешь в виду что-то вроде этого?
int* (*P7PAint)[7]=P7Aint[7];//Это работает, но если честно, не очень понятно как.

Если последнее верно, не мог бы ты разжевать что именно происходит здесь с расставлением скобок?

Цитата(Iron Bug @ 27.10.2011, 8:05) *
во втором случае: так делать нельзя, ибо размер массива должен быть константным. компилятор заранее не знает его и требует точного размера.

new int*[10] даёт указатель на массив указателей на int (тип int **), а PT - массив указателей. тут просто несоответствие типов, потому что указатель нельзя привести к массиву, можно только наоборот: адрес массива привести к указателю. это связано с выделением памяти компилятором: массивы хранятся в памяти строго последовательно и компилятор должен точно знать размер объекта. у указателя этого размера нет.

определение PT pt3[10] пытается создать массив из 10 элементов типа PT, но размер каждого элемента неизвестен заранее, а и компилятор просто не может выделить память под такой массив.


Здесь вроде дошло наконец..

Спасибо


int* (*P7PAint)[7]=&P7Aint[7];

Только вот так, конечно.

Тогда и "Указатель на массив чар" надо, по идее определять так:

char c[5];
char (*pc)[5]=&c;
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 27.10.2011, 12:48
Сообщение #13


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Про скобки:
Приоритет оператора [] выше приоритета *.
Поэтому выражение
typedef int *P7PAint[7];

означает массив из семи указателей на int.

Фактически получается int (*(P7PAint[7])) (скобки расставлены так, как это воспринимает компилятор). Начинаем разворачивать скобки, начиная с наружних. Получается, что выражение *P7PAint[7] есть int. Далее, выражение P7PAint[7] есть int*. То есть, каждый элемент P7PAint имеет тип int* - указатель на тип int.

Чтобы объявить указатель на массив, нужно указать компилятору, чего мы хотим, и расставить приоритеты:
typedef int (*P7PAint)[7];

Вот теперь это один указатель на массив из семи int-ов. То есть, приритеты выглядят так: int ((*P7PAint)[7]). Это означает, что (*P7PAint)[7] имеет тип int (каждый элемент массива (*P7PAint)[7] есть целое число), то есть, *P7PAint имеет тип int[7] . То есть, P7PAint есть указатель на массив из 7 элементов типа int, что и требовалось.

да, кстати:
при указателе на массив на стеке (определённый через []) размер массива должен быть явно указан. потому что выражение int (*foo)[] в общем смысле не может быть размещено компилятором как самостоятельный объект в памяти. его можно использовать только как указатель на уже готовую структуру данных, например, как-то так:
typedef int (*FOO)[];

int data[]={1,2,3};

FOO foo=(int(*)[])data;

cout << *(*foo+0) << " " << *(*foo+1) << " " << *(*foo+2) << endl;

но это вряд ли принесёт особую выгоду, ибо тут можно просто запутаться.

Сообщение отредактировал Iron Bug - 27.10.2011, 12:49
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
rp80
  опции профиля:
сообщение 27.10.2011, 14:47
Сообщение #14


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 10.9.2011
Пользователь №: 2860

Спасибо сказали: 0 раз(а)




Репутация:   0  


Все понятно, наконец, спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 16.7.2025, 1:45