populating a 2D array question

Z

Zach

Hi,

I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:

zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];

Zach
 
J

Jens Thoms Toerring

Zach said:
I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:
zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];


No, you can't do that, you have to assign to each element
individually. All you can do is "populate" a complete row
in one go if you want to initialize it from a row of another
array of at least the same size and the same type by using
memcpy() but that's it. There isn't any implicit looping over
arrays of any dimensions in C.
Regards, Jens
 
Z

Zach

Zach said:
I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:
zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];


No, you can't do that, you have to assign to each element
individually. All you can do is "populate" a complete row
in one go if you want to initialize it from a row of another
array of at least the same size and the same type by using
memcpy() but that's it. There isn't any implicit looping over
arrays of any dimensions in C.


Hi Jens,

Oh ok, thanks.

Zach
 
M

Malcolm McLean

Hi,

I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:

zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];

No, except for one exception involving structures, C has no syntax for
operating on more than one element at a time. So everything you do
with arrays has to be done in loops.

2 dimensional arrays are very badly implemented in C. Almost always
it's easier to use a 1 dimensional array allocated with malloc() and
just calculate the index as you go:

array[y * width + x] = 0;
 
K

Keith Thompson

Zach said:
I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:

zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];


If that were legal, it would be an array assignment (or, in the case
of the second one, a sort of slice assignment where the elements
being assigned are non-contiguous). The "=" assignment operator
doesn't operate on arrays. ("=" can be used to *initialize* an
array, but it's not an assignment operator in that context.)

If the language supported what you're trying to do, the compiler
would generate the equivalent of a loop. You'll just have to
write the loop yourself (except in certain cases where you can use
memcpy(), but memcpy() itself is probably implemented via a loop).

One odd corner case is that if a struct contains an array member,
assigning a value of the struct type assigns the array member.
This applies only for arrays whose dimensions are determined at
compile time.
 
T

Tom St Denis

One odd corner case is that if a struct contains an array member,
assigning a value of the struct type assigns the array member.
This applies only for arrays whose dimensions are determined at
compile time.

Does VLA apply to structs as well?

e.g.

int func(int n)
{
struct { int v[n]; } a, b;
a = b;
return a.v[0];
}

???

Tom
 
L

luser- -droog

Zach said:
I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:
zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];


If that were legal, it would be an array assignment (or, in the case
of the second one, a sort of slice assignment where the elements
being assigned are non-contiguous).  The "=" assignment operator
doesn't operate on arrays.  ("=" can be used to *initialize* an
array, but it's not an assignment operator in that context.)
[snip]
One odd corner case is that if a struct contains an array member,
assigning a value of the struct type assigns the array member.
This applies only for arrays whose dimensions are determined at
compile time.


That helps for rows, but not for slices.

#include <stdlib.h>
#include <stdio.h>
struct row {
double row[3];
};
double mat[3][3];
void rowassign(double mat[][3], size_t i, double row[3]) {
*(struct row *)&mat[0] = *(struct row *)row;
}
int main () {
rowassign(mat, 0, (double [3]){ 1.0, 0.0, 0.0 });
rowassign(mat, 1, (double [3]){ 0.0, 1.0, 0.0 });
rowassign(mat, 2, (double [3]){ 0.0, 0.0, 1.0 });
int i,j;
for (i=0;i<3;i++) {
for (j=0;j<3;j++) printf("%f ", mat[j]);
puts("");
}
}
 
Z

Zach

No, except for one exception involving structures, C has no syntax for
operating on more than one element at a time. So everything you do
with arrays has to be done in loops.

Ah I see that now.
2 dimensional arrays are very badly implemented in C. Almost always
it's easier to use a 1 dimensional array allocated with malloc() and
just calculate the index as you go:

array[y * width + x] = 0;

Good idea! Cheers.

Zach
 
Z

Zach

If that were legal, it would be an array assignment (or, in the case
of the second one, a sort of slice assignment where the elements
being assigned are non-contiguous).  The "=" assignment operator
doesn't operate on arrays.  ("=" can be used to *initialize* an
array, but it's not an assignment operator in that context.)

If the language supported what you're trying to do, the compiler
would generate the equivalent of a loop.  You'll just have to
write the loop yourself (except in certain cases where you can use
memcpy(), but memcpy() itself is probably implemented via a loop).

One odd corner case is that if a struct contains an array member,
assigning a value of the struct type assigns the array member.
This applies only for arrays whose dimensions are determined at
compile time.

I see. Expectations adjusted :) Thanks for the food for thought.

Zach
 
K

Keith Thompson

Tom St Denis said:
One odd corner case is that if a struct contains an array member,
assigning a value of the struct type assigns the array member.
This applies only for arrays whose dimensions are determined at
compile time.

Does VLA apply to structs as well?

e.g.

int func(int n)
{
struct { int v[n]; } a, b;
a = b;
return a.v[0];
}

No, structs and unions cannot have VLAs as members.

C99 6.7.2.1p8 (and the associated footnote) and 6.7.5.2p2.
 
S

Seebs

I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:
zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];


I have absolutely no idea what you think this would do. I mean, none
at all. It's like you're banging on keys randomly and asking whether
it'll work. I can't even guess what you think it would do if it worked.

Imagine that you have an array, zSet[2][2] = { { 0, 0 }, { 0, 0 } };

After this, you write:

zset[0][ ] = 3;

what do you expect to happen? I mean, obviously, it won't compile,
it's completely incoherent. But what were you trying to express? What
would be the resulting values of zSet?

-s
 
K

Keith Thompson

Seebs said:
I'm populating a 2d array and wondering if it is valid to leave one
dimension with blank brackets while i assign a value to the other
dimension or must i fill them both in at once? Right now I was
thinking of doing:
zSet[ ] = lineZ[i+ (i-2)+11];
zSet[ ] = lineZ[i+ (i-1)+11];


I have absolutely no idea what you think this would do. I mean, none
at all. It's like you're banging on keys randomly and asking whether
it'll work. I can't even guess what you think it would do if it worked.

Imagine that you have an array, zSet[2][2] = { { 0, 0 }, { 0, 0 } };

After this, you write:

zset[0][ ] = 3;

what do you expect to happen? I mean, obviously, it won't compile,
it's completely incoherent. But what were you trying to express? What
would be the resulting values of zSet?


I can easily imagine a language (not C) in which empty brackets impose a
list context, causing the RHS value to be replicated across the range of
the index. Given that assumption,
zSet[0][ ] = 3;
would set zSet to { { 3, 3 }, { 0, 0 } }, and a subsequent
zSet[ ][0] = 4;
would set zSet to { { 4, 3 }, { 4, 0 } }.

I don't think I've seen this particular feature in any language;
Perl has some elements of it, but doesn't go quite that far.
 
M

Mark Wooding

Keith Thompson said:
I can easily imagine a language (not C) in which empty brackets impose a
list context, causing the RHS value to be replicated across the range of
the index. [...]
I don't think I've seen this particular feature in any language;
Perl has some elements of it, but doesn't go quite that far.

Algol 68's slicing comes very close. Its `rowing' coversion won't
turn a scalar into a vector by replicating, but

BEGIN [2, 2] INT v := ((0, 0), (0, 0));
v[1, ] := (3, 3);
v[, 1] := (4, 4);
print(v)
END

prints

+4 +3 +4 +0

as requested. (Algol 68 wants to start indexing from 1, which is
annoying.)

-- [mdw]
 
H

Heikki Kallasjoki

I can easily imagine a language (not C) in which empty brackets impose a
list context, causing the RHS value to be replicated across the range of
the index. Given that assumption,
zSet[0][ ] = 3;
would set zSet to { { 3, 3 }, { 0, 0 } }, and a subsequent
zSet[ ][0] = 4;
would set zSet to { { 4, 3 }, { 4, 0 } }.

I don't think I've seen this particular feature in any language;
Perl has some elements of it, but doesn't go quite that far.

The MATLAB language (as well as the more or less compatible Octave) work
somewhat like that:

octave:1> zSet = zeros(2);
octave:2> zSet(1,:) = 3;
octave:3> zSet:),1) = 4;
octave:4> zSet
zSet =
4 3
4 0

(The indexing is 1-based, and you can use expressions like
"A:),1:3:end-5) = 0" to zero every third column except not in the last
five, and so on.)

The n-dimensional arrays of SciPy/NumPy, a numerical-computing oriented
Python package, also work likewise.
 
T

Tom St Denis

Does VLA apply to structs as well?

int func(int n)
{
   struct { int v[n]; } a, b;
   a = b;
   return a.v[0];
}

No, structs and unions cannot have VLAs as members.

C99 6.7.2.1p8 (and the associated footnote) and 6.7.5.2p2.

Ah, makes sense I guess. Not that I'd ever use a VLA, that's just
stack smashing waiting to happen...

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top