Чтобы быстрее понять указатели, не нужны никакие Шилдты, а тем более Страуструпы, которые еще больше запутают человека. Как вариант мне в свое время помогло осиливания того же x86 ассемблера, после чего сразу все стало понятно и больше вопросов не возникало.
Почитал K&R, кое-что из «Глава 5. Указатели и массивы». Понял мало, но по своей проблеме узнал, что для того, чтобы передавать двумерный массив в функцию без указания размерности нужно передавать указатель на указатель. Завтра буду курить.
Еще один платиновый тред. Одни неучи пытаются рассказать другим неучам то, чего сами не знают. dev во всём великолепии.
Чтобы быстрее понять указатели, не нужны никакие Шилдты, а тем более Страуструпы, которые еще больше запутают человека. Как вариант мне в свое время помогло осиливания того же x86 ассемблера, после чего сразу все стало понятно и больше вопросов не возникало.
Как же хорошо, что я знакомство с компьютером именно с ассемблера и начинал. (А если точнее, со схемотехники ЭВМ и принципов работы процессора.)
Все, кто пытается программировать, не зная, во что реально превращаются все объектно-ориентированные быдлокоды — поетнциальные обезьяны с гранатами. Никогда не знаешь, в какой момент вылезет их невежество и во что оно выльется.
Если ты говоришь о косвенности как о двойном (в общем случае - n-кратном) разыменовании указателя на указатель ([на указатель]*), то о какой косвенности может идти речь в случае
Ну смысл в том, что многомерные массивы, хранятся не в виде абстрактного тела (таблица/куб etc) как удобно изображать человеку, а в виде указателей на указатели.
Двумерный массів: int[10][20] - честный сплошной участок памяті
То что вы описали - это массив одномерных массивов.
На этой неделе вообще по плюсам столько вопросов от тех, кто не читал k&r. Как будто k&r - многотомное собрание сочинений кернигана и риччи в 1200 страниц каждое, и всего 24 тома!!!
//Задать размерность
int QwMatrixHeight = 20;
int QwMatrixWidth = 20;
//Создать матрицу
QwMatrixElement*** QwMatrix;
//Выделить память под элементы матрицы
for (int i = 0; i < QwMatrixHeight; i++) {
for (int j = 0; j < QwMatrixWidth; j++) {
QwMatrix[i][j] = new QwMatrixElement();
}
}
//Передача матрицы в функцию
void QwDoSomethingWithMatrix(QwMatrixElement*** matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j]->someProperty = true;
}
}
}
//Использование в программе
QwDoSomethingWithMatrix(QwMatrix, QwMatrixHeight, QwMatrixWidth);
Обрати внимание на 0 аллокаций в куче, на код аллокации на стеке, на дефолтный конструктор, на два способа обхода и на непрерывный layout элементов матрицы в памяти.
Если h и w неизвестны на момент компиляции, то нужно делать как предложил tailgunner, то есть писать свой класс с аллокацией одним куском и доступом с помощью арифметики i * w + j индексов. На самом деле (по стандарту), для статических T[h][w] и std::array<std::array<T, w>, h> компилятор сам располагает их непрерывно в памяти и пишет ту же самую арифметику для индексов в ассемблер для [ i ][j].
тупняк.
Массивы могут выделяться на стеке или на куче
естественно, что это совершенно разные структуры, и способы организации памяти у них разные.
Тот факт что в википедии под array подразумевают выделение на стеке, не означает что массивы, выделенные на куче не являются массивами.
Да по факту это не многомерный массив, в массив указателей. Но знаешь ли, компьютер тоже не с 0 и 1 работает, как в школе преподают.
однако понимание что ключ-значение бд есть включающая в себя указатели общность облегчает понимание указателей и вообще различение/общее среди имя-именуемое
#include <stdlib.h>
#include <stdio.h>
int g=0;
void* m_init(size_t t){
int* a=(int*)malloc(t*sizeof(int));
int i;
for(i=0;i<t;i++){
a[i]=g++;
}
return a;
}
void * g_dynarr(char* sz){
if(!sz[1]){
return m_init(sz[0]);//simple test
}
void**p=malloc(sz[0]*sizeof(void*));
int i;for(i=0;i<sz[0];i++){
p[i]=g_dynarr(sz+1);
}
return p;
}
void cl(void* a,char* sz){
return ;
}
int main(int c,char **z){
char sz[]={10,10,0,1,1,10,0};//if short need +2 but ++;
int i,j,k,l,m,n;
//int***** a=(int*****)g_dynarr(sz);//bad_idia for g_dynarr(NULL) and g_dynarr("")
/* sz={1,2,3,4,5,10,0};
for(i=0;i<sz[0];i++){
for(j=0;j<sz[1];j++){
for(k=0;k<sz[2];k++){
for(l=0;l<sz[3];k++){
for(m=0;m<sz[4];m++){
for(n=0;n<sz[5];n++){
printf(" %d",a[i][j][k][l][m]);
}
printf("\n");
}
}
}
}
}*/
{//test 10x10
int **a=(int**)g_dynarr(sz);
for(i=0;i<sz[0];i++){
for(j=0;j<sz[1];j++){
printf(" %d",a[i][j]);
}
printf("\n");
}
cl(a,sz);
}
{//test 2x3x4;
sz[0]=2;sz[1]=3;sz[2]=4;g=0;
//sz[2]=10;
sz[3]=0;
int ***a=(int***)g_dynarr(sz);
for(i=0;i<sz[0];i++){
printf("plane %d\n",i);
for(j=0;j<sz[1];j++){
for(k=0;k<sz[2];k++){
printf(" %d",a[i][j][k]);
}
printf("\n");
}
}
cl(a,sz);
}
return 0;
}
на стек оверфлоу где то было - да и вообще отличная стратегия - берём большой кусок M - принимаем за ноль его начало и тогда развлекаемся номер есть смещение в этом массиве и конструкция M[M[....]]
В школе учили Паскаль, который мне не нравился тем, что не генерировал бинарников. Тогда я решил учить самый мощный язык, как мне показалось, который «может все». Вот, потихоньку быдлокодю. Хоть в математике я «полный NULL», писать все равно нравится.
В школе учили Паскаль, который я осилил по книжке за три дня. Сейчас уже забыл. Он мне не нравился тем, что не генерировал бинарников. Тогда я решил учить самый мощный язык, как мне показалось, который «может все». Вот, потихоньку быдлокодю. Хоть в математике я «полный NULL», писать все равно нравится.