Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Индексация указателей

27K
21 мая 2015 года
mnanorn
78 / / 01.12.2013
Здравствуйте!

Задача: умножить строку iRank матрицы iMtxA на столбцовую матрицу iMtxB (да, это - столбец :) ). Казалось бы, очевидный код, а вызвал проблемы:
Код:
#define SZ_MATRIX   5

...

int** iMtxA = {{4, 8, 2, 5, 3},
               {7, 8, 6, 5, 0},
               {4, 7, 2, 7, 9},
               {6, 4, 7, 8, 3},
               {2, 0, 5, 3, 9}};
int*  iMtxB =  {7, 3, 2, 9, 6};
int   iMtx  = 0;
int   iRank = 0;
int   i     = 0;

...

for(i = 0; i < (SZ_MATRIX - 1); i++)
    iMtx += iMtxA[iRank][i] * iMtxB[i];
Результат:Насколько я понимаю, указатель и имя массива - синонимы. Почему ошибка доступа к памяти?

Спасибо за разъяснение.
260
22 мая 2015 года
Ramon
1.1K / / 16.08.2003
А вы не занимайтесь х*ней.
 
Код:
int iMtxA[][SZ_MATRIX] = { { 4, 8, 2, 5, 3 },
{ 7, 8, 6, 5, 0 },
{ 4, 7, 2, 7, 9 },
{ 6, 4, 7, 8, 3 },
{ 2, 0, 5, 3, 9 } };
int  iMtxB[] = { 7, 3, 2, 9, 6 };
326
24 мая 2015 года
sadovoya
757 / / 19.11.2005
Если не ошибаюсь, многомерный статический массив на самом деле одномерный (в смысле сродни с type*), компилятор по всем индексам вычисляет линейный адрес элемента. Но только при обращении к массиву. А указатель надо делать "одномерный" и пересчет в линейный адрес делать самому.
Код:
#include <iostream>

using namespace std;

int main() {
    int array2d[][4] = {
        {10, 20, 30, 40},
        {50, 60, 70, 80},
        {15, 25, 35, 45}
    };
    int *p = (int*)array2d;
    for (int i = 0; i < 3; i++) {
        for(int j = 0; j < 4; j++)
            cout << p[i*4+j] << "; ";
        //либо:
        //cout << *(p+i*4+j)<< "; ";
        cout << endl;
    };

    return 0;
}
Способ хранения стандартизирован или зависит от реализации - не помню. Пример мой у меня работает.

P.S. Лучше действительно не страдать :)
27K
22 мая 2015 года
mnanorn
78 / / 01.12.2013
Спасибо, помогло. Однако, яснее не стало. Почему мой вариант дает ошибку?
27K
25 мая 2015 года
mnanorn
78 / / 01.12.2013
Спасибо большое! Конечно, лучше не страдать. Просто меня смутил второй аргумент int main(). Там ведь безразмерный char argv[][] или char** argv и все работает, а тут нет. )
326
27 мая 2015 года
sadovoya
757 / / 19.11.2005
Прием для переделки статического 2D массива в "двумерный" указатель. Может пригодиться для передачи в ф-ции "сишного" стиля, ожидающие type**:
Код:
#include <iostream>

using namespace std;

int main() {
    int array2d[][4] = {
        {10, 20, 30, 40},
        {50, 60, 70, 80},
        {15, 25, 35, 45}
    };

    int **pp = new int*[3];
    for (int i = 0; i < 3; i++)
        pp[i] = array2d[i];

    for(int i = 0; i < 3; i++) {
        for(int j = 0; j <4; j++)
            cout << pp[i][j] << "; ";
        //либо:
        //cout << *(*(pp+i)+j)<< "; ";
        cout << endl;
    }

    delete [] pp;

    return 0;
}
Сама идея, возможны вариации. Например, чтобы не мешать динамическую память, в таком роде можно:
Код:
int *m[] = {array2d[0], array2d[1], array2d[2]};
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++)
            cout << m[i][j] << "; ";
        cout << endl;
    }

    cout << endl;

    int **pp2 = m;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++)
            cout << pp2[i][j] << "; ";
        cout << endl;
    }

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог