LINUX.ORG.RU

Ответ на: комментарий от vromanov
void f (int *f)
{
   printf("%d\n", f[120]);
}

Неожиданно правда? Или даже ВНЕЗАПНО!

Или даже так:

#include <cstdio>

template <typename T>
void f(T a, int, int)
{
  printf("%d\n", a[1][1]);
}

int main()
{
  int a[2][2] ={0, 1, 2, 3};
  f(a, 2, 2);

  int **b= new int *[2];
  b[0] = new int[2];
  b[1] = new int[2];
  b[1][1] = 42;

  f(b, 2, 2);
}

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 1)
Ответ на: комментарий от vromanov

В коде то передается T и T явлется типом массива

T вообще ничем не является.

#include <iostream>
#include <typeinfo>

template<class T>
void foo (T t)
{
    std::cout << sizeof (t) << " " << std::endl;
}

void fooo (int t[][500])
{
    std::cout << sizeof (t) << " " << std::endl;    
}

void foooo (int t[200][500])
{
    std::cout << sizeof (t) << " " << std::endl;    
}

int main (int argc, char *argv[])
{
    int bar[100][500];
    std::cout << sizeof (bar) << std::endl;
    
    foo (bar);
    fooo (bar);
    foooo (bar);

    int **baz = new int*[100];
    for (int i = 0; i < 100; i++) {
        baz[i] = new int[500];
    }
    foo (baz);
    return 0;
}
/tmp $ ./a.out 
200000
8 
8 
8 
8 
yoghurt ★★★★★
()
Ответ на: комментарий от nanoolinux

Вообще признаюсь, меня вся эта тема шокирует. Мне просто не приходит в голову такое использовать. Я бы наверное сделал свою реализацию двухмерного масива поверх одномерного.

sizeof(a)/sizeof(a[0])

vromanov ★★
()
void f(int a[][4], const int n)
{

}

int main()
{
	int a[2][4] = {0};
	f(a, 2);
}
dzidzitop ★★
()
Ответ на: комментарий от vromanov

Я бы наверное сделал свою реализацию двухмерного масива поверх одномерного.

Ну да, я об этом тебе и говорил в теме про спп. Велосипедостроительство процветает.

nanoolinux ★★★★
()
Ответ на: комментарий от yoghurt

Тогда следующий вопрос, есть динамический двухмерный массив и статический двухмерный массив, мне надо две реализации функций написать, для динамического, где память выделена фиг знает как, и для статического, где память выделена «непрерывно» ?

ilovewindows ★★★★★
()
Ответ на: комментарий от stevejobs

это не дад крестами издевательство, это издевательство над здравым смыслом и K&R.

x0r ★★★★★
()
Ответ на: комментарий от puding

Б-же мой, какой кошмар. Во первых не юзай malloc в С++. А во вторых, это не джава, здесь нет сборщика мусора

comp00 ★★★★
()
Ответ на: комментарий от vromanov

Зря бы сделал, в инете есть тесты, по которым «двумерная реализация поверх одномерной» сливает в пух и прах т.к. лишает компилятор возможности оптимизировать

stevejobs ★★★★☆
()
Ответ на: комментарий от puding

лол. С подмножество С++ => разочаровавшись в С++ (в более мощном множестве), ты разочаровываешься в С (менее мощное множество, содержащее в большем). Это дискретка, против нее не попрешь :)

comp00 ★★★★
()
Ответ на: комментарий от stevejobs

Кроме обращения к элементу есть другие операции - ресайз на месте, сериализация, удаление колонки, удаление сроки итд. Результами тестов я несколько удивлен..

vromanov ★★
()
Ответ на: комментарий от vromanov

Не помню конкретные тесты, помню только резюме, а так можно было бы обсудить :(
Сейчас есть живые люди которые знают, что получится после O3?

stevejobs ★★★★☆
()
Ответ на: комментарий от puding

Ну смысл в том, что многомерные массивы, хранятся не в виде абстрактного тела (таблица/куб etc) как удобно изображать человеку, а в виде указателей на указатели. Получается такой такой пирог. Тоесть массив любой размерности можно разбить не векторы, которые и хранить в памяти (уже последовательно), и связывать их указателями. Потому, можно утверждать, что по сути многомерных массивов не существует, это все массивы массивов

comp00 ★★★★
()
Ответ на: комментарий от puding

Эм?
Указатель указывает на указатель который указывает на... указатель. И так до размерности массива

comp00 ★★★★
()
Ответ на: комментарий от comp00

Указатель указывает на указатель, который указывает на указатель... А кто на данные указывать будет?

puding
() автор топика
Ответ на: комментарий от puding

Хинт: ни один указатель не указывает на много чего-то. Он указывает на начало чего-то. От чего-то можно отсчитывать много еще чего-то. Даже если их много!!

cdshines ★★★★★
()

Вот что происходит, когда люди начинают программировать сразу на Qt ;]

grouzen ★★
()
Ответ на: комментарий от cdshines

То есть, указатель раздваивается и одновременно указывает на данные и на следующий указатель.

puding
() автор топика
Ответ на: комментарий от puding

Последние дети получившегося дерева.
Ну есть какой-то вектор указателей из n эл-тов. Каждый этот указатель указывает еще на векторы из k элементов, получается, если эти векторы будут хранить значения, то ячеек будет столько же,сколько способна в себе хранить матрица A[n][k]

comp00 ★★★★
()
Ответ на: комментарий от puding

указатель указывает только на один элемент. Это может либюо данные, либо другой указатель

comp00 ★★★★
()
Ответ на: комментарий от nanoolinux

у крестопоклонников «передать по значению» — последний спасительный бросок, отделяющий бездны безблагодатности. Такшто можно понимать фразу «передать по значению» не буквально, а как аллюзию на спасительную молитву или другой религиозный ритуал, совершаемый перед закатом солнца вручную.

stevejobs ★★★★☆
()
Ответ на: комментарий от puding

Ну ты сам это прочитал?
Я тебе могу их гору кинуть, там написано что и когда лучше юзать
Можешь юзать std::array, но судя по твоим комментам тебе еще рано юзать указатели.
так что почитай умные книги, там все это расписано

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от puding

Что? Он указывает на адрес в памяти, грубо говоря (почитай что-нибудь про организацию памяти. Для затравки ключевые слова: виртуальная память, MMU и т.д.).

Поэтому ты и ходишь по массиву, прибавляя к указателю по 1: *(pointer + offset * 1), т.е. ко второму элементу в массиве интов ты по указателю обратишься по *(pointer + 1), а не *(pointer + sizeof(int)). Потому что (pointer + 1) - это адрес в памяти, на который указывает указатель + еще sizeof(int). То есть, если был адрес 5, то будет 5 + 4 (если инт 4-байтный). Таким образом, один указатель содержит один адрес, но можно, отталкиваясь от этого адреса, пройтись дальше.

cdshines ★★★★★
()
Ответ на: комментарий от puding

А то, что ты описал - это нода простого связного списка. Попробуй, кстати, написать. Поищи на википедии linked list и реализуй. И вообще, поковыряй структуры данных, а то будешь потом такие вопросы задавать.

cdshines ★★★★★
()
Ответ на: комментарий от comp00

Допустим A[0][1] указывает на A[0][2], а A[0][2] - на A[0][3], тогда кто будет указывать на значение, хранящееся в A[0][2]? Если они все указывают на соседа, то значения хранятся в последних указателях, и тогда получается, что A[10][10] хранит всего 10 значений.

puding
() автор топика
Ответ на: комментарий от puding

я таки ошибся, и перепутал лекцию. Динамическое выделение в 3ей лекции ( NxN 57 минута)

comp00 ★★★★
()
Ответ на: комментарий от puding

Если A[0][1] указывает на A[0][2], то тип A[0][1] - указатель на тип, лежащий в А[0][2], но из-за того, что там уже лежит какой-то указатель, то у тебя чем дальше в лес, тем больше дров. Опиши, что ты хочешь сделать вообще.

cdshines ★★★★★
()
Ответ на: комментарий от puding

A[0][1] не указывает на A[0][2] !
Посмотри лекцию. по сути:
A[0] -> A_0[1]. который, уже содержит данные. Вот и получается, что 10 векторов по 10 ячеек с данными 10*10=100

comp00 ★★★★
()
Ответ на: комментарий от grouzen

Это несомненно. Хотя, я больше поклонник Страуструпа и Шилдта. Просто в свое время мне тоже тяжело давались указатели, хотя я много чего читал, пока друг мне не объяснил про хранение данных. Это вроде легко, но не очевидно

comp00 ★★★★
()
Ответ на: комментарий от puding

Смотри:

--------------
*|*|0|1|2|3|4|
 |*|0|1|2|3|4|
 |*|0|1|2|3|4|
 |*|0|1|2|3|4|
--------------
Звездочки - это указатели. Самая левая Звездочка (с большой буквы) - указатель на указатель (чтоб ты проще запомнил, там рядом 2 звездочки: ** - как мнемоника для сишной формы). Эта Звездочка содержит адрес самой первой звездочки (с маленькой) в столбике. А та, в свою очередь, содержит адрес ячейки, в которой хранится первый «0». Отшагнув от адреса в нашей звездочке на размер, необходимый, чтобы вместить «0», мы получим адрес, по которому хранится «1». А чтобы получить адрес второй звездочки с маленькой буквы, нужно от адреса в Звездочке отшагнуть столько, сколько нужно для хранения адреса первой звездочки с маленькой буквы. Таким образом, можно рассматривать маленькие звездочки не как указатели, а как массивы [0,1,2,3,4]. А Звездочка - не указатель на указатель, а массив указателей (по аналогии). То есть ты можешь для удобства представлять, что она указывает на [*,*,*,*].

Почитай книжку, хватит на лоре сидеть.

cdshines ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.