Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.01.2010, 16:42   #1
RUSt88
Участник клуба
 
Регистрация: 29.12.2009
Сообщений: 1,166
По умолчанию массив указателей

не могу понять, в чем проблема
сама задача такая: работа с матрицей при помощи указателей
я сделал так: создал указатель на одномерный массив, элементы к-рого являются указателями на одномерный массив, т.е. получили как бы массив указателей
код абсолютно работающий
Код:
	int **pmat; int *pv; int *pvn, *max;  // объявление указателей на массивы
	int R; // размерность матрицы и векторов
	cout<<"Vvedite razmernost' matricy: "<<endl; // предлагаем ввести пользователю размерность
	cin>>R; // присваиваем переменной R размерность
	pmat = new int *[R];  // создаём массив указателей
	max = new int[R];   //указатель на массив элементов
	for (int i = 0; i < R; i++)
	{
		*(max + i) = 0; //обнуляем массив, нужен для нахождения максимального элемента строки матрицы
	}
	for (int i = 0; i < R; i++)
	{
		*(pmat + i) = new int[R]; //создаём массив указателей
	}
	pv = new int[R]; pvn = new int[R];  //вектор, указанный пользователем, и получившийся в результате умножения новый вектор
	randomize(); //чтобы числа в функции random не повторялись
	for (int i = 0; i < R; i++)  // цикл по строкам
	{
		for (int j = 0; j < R; j++) //цикл по столбцам
		{
			*(*(pmat + i) + j) = random(9); //не предлагаем ввести пользователю элементы матрицы, а заполняем случайными числами 0..9
			if (*(*(pmat + i) + j) > *(max + i))
			{
				*(max + i) = *(*(pmat + i) + j); //находим максимальный элемент строки матрицы
			}
		}
		*(pv + i) = random(9);
		*(pvn + i) = *(pv + i) * *(max + i);
		cout<<*(pvn + i)<<" ";
	}
	delete[] pmat, pv, pvn, max; //удаляем объекты
ПОЧЕМУ вместо *(pmat + i) (и похожее в коде) НЕЛЬЗЯ писать pmat++ ??? Ведь это же, в принципе, одно и то же.

Выдаёт ошибку, в пошаговой отладке видишь как со второго элемента массива pmat указатели идут как NULL.
Я знаю, что вместо *(pmat + i) можно писать pmat[i], но весь вопрос в том, что тогда теряется скорость (читал, как преобразуются эти команды, самая короткая, это pmat++)
IDE - Borland C++ 2009
прогер C\C++\C#\Delphi
ася: [семь 3]-[97]-[1 шесть]
RUSt88 вне форума Ответить с цитированием
Старый 09.01.2010, 16:55   #2
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

Я знаю, что вместо *(pmat + i) можно писать pmat[i], но весь вопрос в том, что тогда теряется скорость...

Где это вы такое прочитали? это компилится в одно и то же:

int* p = 0;

//----------------------------------------

int i = p[5];
00412FF8 mov eax,dword ptr [p]
00412FFB mov ecx,dword ptr [eax+14h]
00412FFE mov dword ptr [i],ecx

//----------------------------------------

int j = *(p + 5);
00413001 mov eax,dword ptr [p]
00413004 mov ecx,dword ptr [eax+14h]
00413007 mov dword ptr [j],ecx

//----------------------------------------
_Ч_ вне форума Ответить с цитированием
Старый 09.01.2010, 17:57   #3
RUSt88
Участник клуба
 
Регистрация: 29.12.2009
Сообщений: 1,166
По умолчанию

*(pmat + i) и pmat[i] компилится в одно и то же, это да, но pmat++ выполняется быстрее, т.к. не происходит поиска адреса по индексу, а сразу перескакивает на след. адрес, это актуально в цикле
Код:
for (int i = 0; i < R; i++)
	{
		*(pmat + i) = new int[R]; //создаём массив указателей
	}
ПОЧЕМУ вместо *(pmat + i) (и похожее в коде) НЕЛЬЗЯ писать pmat++ (переход на след адрес и запись по этому адресу указателя)???
ошибка в том, что тогда указатели в массиве будут NULL
прогер C\C++\C#\Delphi
ася: [семь 3]-[97]-[1 шесть]
RUSt88 вне форума Ответить с цитированием
Старый 09.01.2010, 18:18   #4
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

pmat + 1 - эквивалентно pmat++
pmat + i - не эквивалентно pmat++ (при i > 1)
это вроде бы очевидно.

хотите использовать постинкремент, вот вам ваш переписанный цикл:

Код:

 max = new int[R];

 // было
 for (int i = 0; i < R; i++)
   {
     *(max + i) = 0;
   }

 // стало
 for (int* p = max, end = max + R; p != end; p++)
   {
     *p = 0;
   }

[/CODE]
_Ч_ вне форума Ответить с цитированием
Старый 09.01.2010, 20:51   #5
RUSt88
Участник клуба
 
Регистрация: 29.12.2009
Сообщений: 1,166
По умолчанию

_Ч_ здесь вопрос не в увеличении значения, а в переходе указателя на первый элемент массива на след адрес, т.е. на адрес 2-ого элемент массива и т.д.
Когда мы инкрементируем указатель, он переходит на след адрес на определенное число байт (int - это 4 байта, знач инкремент указателя перепрыгнет на адрес через 4 байта)
Я же не пишу pmat + i, я пишу *(pmat + i) - разные вещи
прогер C\C++\C#\Delphi
ася: [семь 3]-[97]-[1 шесть]

Последний раз редактировалось RUSt88; 09.01.2010 в 20:59.
RUSt88 вне форума Ответить с цитированием
Старый 09.01.2010, 20:54   #6
RUSt88
Участник клуба
 
Регистрация: 29.12.2009
Сообщений: 1,166
По умолчанию

*(pmat + i) - каждый раз переход на след элемент массива, т.е. на след адрес(!!!)
прогер C\C++\C#\Delphi
ася: [семь 3]-[97]-[1 шесть]
RUSt88 вне форума Ответить с цитированием
Старый 09.01.2010, 21:54   #7
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

что-то мы о разных вещах говорим.
ваш вопрос непонятен. попробую ответить на тот вопрос который был задан.
Вопрос:
ПОЧЕМУ вместо *(pmat + i) (и похожее в коде) НЕЛЬЗЯ писать pmat++ ???

Ответ:
Потому что это не одно и то же.
pmat в вашем случае это указатель на укажатель на int (int**)
предположим что в с++ есть оператор typeof(expr).
typeof(*(pmat + i)) == int*;
typeof(pmat++) == int**;
int* != int**

Если вы имели в виду что-то другое, то спросите яснее. А то я не понимаю что вы не понимаете ))
_Ч_ вне форума Ответить с цитированием
Старый 09.01.2010, 23:33   #8
RUSt88
Участник клуба
 
Регистрация: 29.12.2009
Сообщений: 1,166
По умолчанию

хорошо, прямой вопрос

*(pmat + i) нельзя ли заменить это выражение инкрементом (++) ?

например,
pmat++ (ошибка компиляции (невозможно int** в int*)), или *pmat++ (ошибка выполнения (указатели NULL) (НЕ ПОНИМАЮ ПОЧЕМУ???), или по другому

используя (в данном случае!) pmat[i] (или *(pmat + i), равнозначно), теряется смысл использования указателей, нет выигрыша в скорости (а ради этого вся дискуссия, не надо мне предлагать ассемблер)

разберем всё по порядку (поправьте меня, если я ошибаюсь)
pmat[i] - медленный код, т.к. происходит поиск адреса по индексу, к-рый постоянно вычисляется
*(pmat + i) - равнозначно предыдущему коду
pmat++ (или *pmat++ ?) - быстрый код, ничего не вычисляется, происходит переход на адрес следующего элемента (или я ошибаюсь?)

или всё это неправильно, тут можно только pmat[i] и баста?

а как же тогда инкремент указателя? Не просто так же его сделали
сейчас еще читаю лит-ру по этому вопросу, но какая у меня есть, там крайне скудно описан этот вопрос
прогер C\C++\C#\Delphi
ася: [семь 3]-[97]-[1 шесть]
RUSt88 вне форума Ответить с цитированием
Старый 10.01.2010, 00:14   #9
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

*(pmat + i) нельзя ли заменить это выражение инкрементом (++) ?
на этот вопрос я уже ответил постом выше. прочитайте еще раз.


или всё это неправильно, тут можно только pmat[i] и баста?
На этот вопрос уже тоже есть ответ выше. Посмотрите как был переписан цикл для использования только постинкремента.
_Ч_ вне форума Ответить с цитированием
Старый 10.01.2010, 00:39   #10
Viral
 
Регистрация: 08.01.2010
Сообщений: 3
По умолчанию

pmat++ - увеличение значения первого элемента массива на 1 , а *(pmat+1) переход на следующий элемент массива

Последний раз редактировалось Viral; 10.01.2010 в 00:47.
Viral вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
массив указателей в С ++ серг Помощь студентам 1 14.12.2009 18:49
Массив указателей (паскаль) diliana Помощь студентам 19 14.11.2009 11:53
массив указателей на методы класса? cout Общие вопросы C/C++ 2 08.05.2008 09:43
Массив указателей на структуры SNAKE89 Общие вопросы C/C++ 4 27.12.2007 10:14