Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Accesing 2d arrays with pointer notation

This thread is locked; no one can reply to it. rss feed Print
Accesing 2d arrays with pointer notation
Paul whoknows
Member #5,081
September 2004
avatar

As all of us already know ->

array[4] == *(array+4)

/* BUT */

array[4][4] == ?????

If I have a 2d array like this: array[4][4], how can I access to its elements with pointers notation?

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

kazzmir
Member #1,786
December 2001
avatar

Well just try it out:

1#include <stdio.h>
2 
3int main(){
4 char foo[ 5 ][ 5 ];
5 printf( "Foo = %p\n", foo );
6 printf( "Foo[0] = %p\n", &foo[ 0 ] );
7 printf( "Foo[1] = %p\n", &foo[ 1 ] );
8 printf( "Foo[2] = %p\n", &foo[ 2 ] );
9 printf( "Foo[3] = %p\n", &foo[ 3 ] );
10 
11 printf( "Foo[0][0] = %p\n", &foo[ 0 ][ 0 ] );
12 printf( "Foo[0][1] = %p\n", &foo[ 0 ][ 1 ] );
13 printf( "Foo[0][2] = %p\n", &foo[ 0 ][ 2 ] );
14 printf( "Foo[0][3] = %p\n", &foo[ 0 ][ 3 ] );
15 printf( "Foo[0][4] = %p\n", &foo[ 0 ][ 4 ] );
16 printf( "Foo[0][5] = %p\n", &foo[ 0 ][ 5 ] );
17}

Produces this:

Foo = 0xbffff3f0
Foo[0] = 0xbffff3f0
Foo[1] = 0xbffff3f5
Foo[2] = 0xbffff3fa
Foo[3] = 0xbffff3ff
Foo[0][0] = 0xbffff3f0
Foo[0][1] = 0xbffff3f1
Foo[0][2] = 0xbffff3f2
Foo[0][3] = 0xbffff3f3
Foo[0][4] = 0xbffff3f4
Foo[0][5] = 0xbffff3f5

You can see that the second index into the first array is exactly N bytes away where N = sizeof(type) * elements in the second array.

Paul whoknows
Member #5,081
September 2004
avatar

but how can I access to its elements with pointer notation?

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

Kitty Cat
Member #2,815
October 2002
avatar

int array[h][w];
array[y][x] == *(array + y*w + x);

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Carrus85
Member #2,633
August 2002
avatar

Edit: Sorry, this was a wrong response...

Kitty Cat
Member #2,815
October 2002
avatar

If it's an int **array; that's what you do. But int array[][] isn't the same because it's all one contiguous block in memory. The only pointer is the implicit ones the compiler gives you.
A test:

int main()
{
  int array[1][1];
  printf("&array = %p\n&array[0] = %p\n&array[0][0] = %p\n",
         &array, &array[0], &array[0][0]);
  return 0;
}

gives (with added spacing for ease-of-reading):

&array       = 0xbfb44f64
&array[0]    = 0xbfb44f64
&array[0][0] = 0xbfb44f64

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Paul whoknows
Member #5,081
September 2004
avatar

Thank you Kitticat, that was really helpful!!!

Well I really suck at strings manipulations, look a this

1/* CONSOLE APPLICATION*/
2#include <stdio.h>
3#include <conio.h>
4 
5void main (void)
6{
7/* Prototipos de funciones */
8void carga_datos(char nya[6][20], float *notas);
9char nombres [6][20];
10float notas[6][20];
11carga_datos(nombres, notas);
12 
13}
14 
15void carga_datos(char nya[6][20], float *notas)
16{
17int i=0;
18char coco[20];
19do{
20 printf("\nEnter name :");
21 fflush(stdin);
22 scanf("%s",&nya<i>[0]);
23 i++;
24}while(i<6);
25 
26getch();
27 
28/* now show the strtings*/
29i=0;
30do{
31 printf("\nName :%s",nya[0][0]); /*<-ERROR HERE*/
32 i++;
33}while(i<6);
34getch();
35 
36}

I get an error in the marked line, What the heck am I doing wrong?
I am going to make 2 versions of this stupid program, one with indexes, and the other one with pointer notation, however I can't code the easy one with indexes

:-/

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

ReyBrujo
Moderator
January 2001
avatar

I refuse to help anyone using conio.h :P

Just teasing. You should be using something like printf("\nName :%s",(char *)(nya[0]));, maybe printf("\nName :%s",(char *)(&nya[0]));, although I am not sure which one is correct.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Kitty Cat
Member #2,815
October 2002
avatar

You're passing a char, but it's expecting a pointer to a char. You'd pass nya[0] (or it looks like you meant nya[i]), which will give a pointer to the string.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Paul whoknows
Member #5,081
September 2004
avatar

Master Rey, you know all the answers as usual!!!
Thats works, I am going to KILL my teacher, ;D

Quote:

You're passing a char, but it's expecting a pointer to a char. You'd pass nya(0) (or it looks like you meant nya(i)), which will give a pointer to the string.

Well, so I have to omit the second index, now I think pointer notation is easier than indexes:P

EDIT:
&nya[5][5] is a pointer to a char(a 2d pointer?)
nya[5][5] is a char
nya[5] is a pointer to a char

isn't a bit confusing? now I really think pointer notation is easier.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

LennyLen
Member #5,313
December 2004
avatar

Quote:

&nya[5][5] is a pointer to a char(a 2d pointer?)

Not really. This is no different than in the following snippet:

int *ptr, value;
ptr = &value;

ptr is the pointer. We can point ptr at value though by assigning the address of value (&value) to it. Similarly, you can assign &nya[5][5] to a pointer. Or &nya[5] (or even &nya).

Quote:

nya[5][5] is a char
nya[5] is a pointer to a char

If you think of nya[5] as not just being a pointer to a char, but a pointer to an array of chars, it makes more sense.

Paul whoknows
Member #5,081
September 2004
avatar

Finally finished, I didn't follow KittiCat way exactly, but it works the same.

1#include <stdio.h>
2#include <conio.h>
3#include <string.h> /* Solo se usa para strcpy */
4#include <stdlib.h> /* Solo se usa para exit */
5 
6#define nya_fil 6 /* Cant. de filas para el array nya (nombre y appellido) */
7#define nya_col 20 /* Cant. de columnas para el arrya nya (nombre y appellido) */
8#define notas_fil 6 /* Cant. de filas para el array de notas */
9#define notas_col 7 /* Cant. de coumnas para el array de notas (6 notas + promedio = 7)*/
10 
11/* Struct para grabar a archivo */
12struct _alumno {
13 char nya[20];
14 float promedio;
15} _alumno;
16 
17/* Usado para volcar los datos desde las matrices y grabar el archivo */
18struct _alumno alumnos[6];
19/* Usado para verificacion, permanecera vacio, se cargara solo con los valores leidos desde archivo */
20struct _alumno alumnos_archivo[6];
21 
22/*------------------------------------------ MAIN --------------------------------------------- */
23void main (void)
24{
25/* Puntero para archivo */
26FILE *archivo;
27 
28/* Prototipos de funcione */
29float promedio(float *notas, int alumno);
30 
31/* 1ro filas, luego columnas, array[filas][columans] */
32char _nya [nya_fil][nya_col];
33float _notas[notas_fil][notas_col];
34 
35char *nya = _nya;
36float *notas = _notas;
37 
38/* Cargo los nombres y apellidos primero */
39int i=0,j=0,k=0,l=0;
40for(i=0; i<(nya_fil*nya_col); i+=nya_col) {
41 printf("Enter name and surname ->");
42 fflush(stdin);
43 gets(nya+i);
44 *(nya+i+19)='\0'; /* No dejo ingresar mas de 20 caracteres */
45 
46 /* Linea agregada para grabar datos a struct */
47 strcpy(alumnos[j].nya, nya+i); j++;
48}
49getch();
50 
51/* Ahora cargo las 6 notas y calculo el promedio */
52j=0;
53for(i=0; i<(nya_fil*nya_col); i+=nya_col){
54 for(k=0; k<6; k++){
55 printf("Enter score number %d, for student %s ->",k+1, nya+i);
56 fflush(stdin);
57 scanf("%f",notas+j+k);
58 }
59 /* En la 7ma posicion del la matriz le mando el promedio llamando a funcion */
60 *(notas+j+k)=promedio(notas,j);
61 
62 /* Linea agregada para grabar datos a struct */
63 alumnos[l].promedio = *(notas+j+k); l++;
64 
65 /* Salto al siguiente alumno */
66 j+=notas_col;
67}
68getch();
69 
70/* PUNTO A. Muestrto los datos ingresados tal como lo pide el ejercicio */
71j=0;
72printf("\nNAME AND SURNAME SCORES AVERAGE\n");
73for(i=0; i<(nya_fil*nya_col); i+=nya_col){ //Recorro array de nombres
74 printf("%-20s %.1f %.1f %.1f %.1f %.1f %.1f %.1f \n",nya+i,*(notas+j),*(notas+j+1),*(notas+j+2),*(notas+j+3),*(notas+j+4),*(notas+j+5),*(notas+j+6));
75 j+=notas_col;
76}
77printf("\nPress a key to save data . . .");
78getch();
79 
80/* PUNTO B. Grabamo todo a archivo */
81archivo = fopen("ALUMNOS.DAT", "wb"); /* Abro archivo para escritura */
82if(!archivo) exit (printf("File Error"));
83for(i=0; i<6; i++) {
84 fwrite(&alumnos, sizeof(alumnos), 1, archivo);
85}
86fclose(archivo);
87 
88printf("\nFile saved.");
89printf("\nPress a key for loading data from file. . .\n");
90getch();
91 
92archivo = fopen("ALUMNOS.DAT", "rb"); /* Abro archivo para lectura */
93for(i=0; i<6; i++) {
94 /* Cargo los datos del archivo al array vacio que he reservado */
95 fread(&alumnos_archivo, sizeof(alumnos_archivo), 1, archivo);
96 printf("\nAverage : %.1f , student %s",alumnos_archivo<i>.promedio, alumnos_archivo<i>.nya);
97 getch();
98}
99fclose(archivo);getch();
100}
101 
102/*------------------------------------- PROMEDIO == AVERAGE -------------------------------------------*/
103float promedio(float *notas, int alumno){
104int i;
105float sumatoria=0;
106for(i=0;i<6;i++){
107 sumatoria+=*(notas+i+alumno);
108}
109sumatoria = sumatoria/(notas_col-1);
110return sumatoria;
111}

EDIT: I NEED HELP

I am getting 2 warinings, I am using Borland C++5.0 compiler (win16 console app), but a friend of mine obtained 2 errors instead, compiling with Borland C++5.2.

These are the lines:
(36, 5) Suspicious pointer conversion
(38, 8) Suspicious pointer conversion

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

A J
Member #3,025
December 2002
avatar

Dont use pointers if you dont have to.
Optimzing compilers can do as good or better job of arrays using normal notation (due to aliasing issues)

___________________________
The more you talk, the more AJ is right. - ML

Andrei Ellman
Member #3,434
April 2003

Kitty Cat said:

int array[h][w];
array[y][x] == *(array + y*w + x);

what about array[y][x] == *( (*(array + y)) + x); instead?

AE.

--
Don't let the illegitimates turn you into carbon.

Kitty Cat
Member #2,815
October 2002
avatar

array[y][x] == *( (*(array + y)) + x);
With a static 2d array will cause a compile error. array+y will give you &array[0][y] (remember, an array != a pointer. the only pointer you get from an array is an implicit one from the compiler), deref that and add x, you modify the value at [0][y], and get an int. Try to deref that, and the compiler will error on you. Try to force it with a cast, and you'll more than likely sigsegv.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Paul whoknows
Member #5,081
September 2004
avatar

Quote:

I am getting 2 warinings . . .
These are the lines:
(36, 5) Suspicious pointer conversion
(38, 8) Suspicious pointer conversion

char *nya = _nya; /* wrong */
char *nya = _nya[0]; /* right */

Fixed!

Quote:

Dont use pointers if you dont have to.
Optimzing compilers can do as good or better job of arrays using normal notation (due to aliasing issues)

We are forced to use pointer notation in our exams, if we don't, we get disqualified.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

Andrei Ellman
Member #3,434
April 2003

I always thought that a 2D array was a pointer to an array of pointers into the data. I've written some code that allocates dynamic 2D arrays. First, it allocates a block of memory equivalent to ysize*xsize*datasize, and then it allocates a separate 1D array equivalent to ysize*sizeof(void). This separate array is filled to point to each row of xsize*datasize bytes. The resulting array can be accessed using normal 2D array notation.

AE.

--
Don't let the illegitimates turn you into carbon.

Kitty Cat
Member #2,815
October 2002
avatar

A pointer is a pointer , and an array is an array. int **ptr; is a pointer to a pointer, and int array[foo][bar]; is an array of foo*bar elements. A pointer can point to an array, but a pointer is not an array.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Go to: