About very complex C types...

Programming, for all ages and all languages.
Post Reply
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

About very complex C types...

Post by JJeronimo »

Let's define a pointer to a 80 chars array in C:

Code: Select all

char (*myarray)[80];
Now, if a have the following pointer:

Code: Select all

int (*my4Darray)[80][43][123];
...that contains an address that I want to assign to myarray.

Code: Select all

myarray = my4Darray;
That looks fine... but the compiler will complain because the pointers have different types... So I have to add a cast... Well, let's add the ca.......... but wait! How do I construct a cast for a pointer-to-array type??!

Of course, I can work arround this by converting to void*...

Code: Select all

myarray = (void*) my4Darray;
Or by defining new array-of-80-char type and convert my4Darray to it:

Code: Select all

typedef char eightychars[80];

/*(...)*/

myarray = (eightychars*) my4Darray;
But how can I convert to this type directly without doing any of these ugly work-arrounds?

Thanks!
JJ
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: About very complex C types...

Post by Candy »

JJeronimo wrote:Let's define a pointer to a 80 chars array in C:

Code: Select all

char (*myarray)[80];
Now, if a have the following pointer:

Code: Select all

int (*my4Darray)[80][43][123];
...that contains an address that I want to assign to myarray.

Code: Select all

myarray = my4Darray;
That looks fine...
That's a pointer to an array of 80*43*123 ints. You want to assign that to an array that contains 80 chars? A char isn't compatible with an int, and you don't specify how you want to map a 3d array onto a 1d array.

What are you trying to do?
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Yes, please let us know what you're trying to accomplish, there might be a much nicer way of doing things.
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

Post by JJeronimo »

Ready4Dis wrote:Yes, please let us know what you're trying to accomplish, there might be a much nicer way of doing things.
Simple...
I have an address in a pointer of some type that is NOT a pointer to an unidimentional array... And, for some reason, I want to assign that address to a pointer of the aforementioned type, to be able to temporarily use different C typing rules for accessing the array...

So I need to put a cast operator, but I don't know what's the cast operators for this kind of convertion...

JJ
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

Re: About very complex C types...

Post by JJeronimo »

Candy wrote:That's a pointer to an array of 80*43*123 ints. You want to assign that to an array that contains 80 chars? A char isn't compatible with an int, and you don't specify how you want to map a 3d array onto a 1d array.
MAP?! Who talked about MAPING?!
I want to convert an *address*, and I (think) that addresses don't need to be mapped into each other just to be converted!!!!!
What are you trying to do?
I have a pointer to the VGA video memory which is:

Code: Select all

typedef struct {char character;  char attribute;} Vga_character;

Vga_character (*vga_txt_matrix)[80];
So that I can access a character directly doing:

Code: Select all

char mychar = vga_txt_mat[line][column].character;
But sometimes, when I have a pointer to Vga_character, I want to know the line of the txt display, but if I do:

Code: Select all

int Ypos = pointer_to_Vga_character - vga_txt_mat;
But the compiler complains because the types are incompatible, so I need to put a cast in front of pointer_to_Vga_character to convert it to the type of vga_txt_mat.

Well, the question is: what's the cast for this type of convertion?

JJ
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

If that's all you wanted to do, try this:

int tDiff = (int)pointer_to_Vga_character - (int)vga_txt_mat;

Cast them both to integers first, this gives you the difference in bytes.
Now, if you want the difference in how many characters...

tDiff/=2; //This is now the difference in characters...

Now if you wanted to know what line this was...

yPos=tDiff/80; //Assuming 80 char's per line!
xPos=tDiff%80; //Grab it's x position.

In my video driver, I simply store the x/y variables and have a function to set/get them, so I know where the cursor is at all times. In any program using a pointer to video memory, you could easily do the same, just store the x/y coords so you don't have to look it up, but there may be some reason to do this.
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

Post by JJeronimo »

Ready4Dis wrote:If that's all you wanted to do, try this:

int tDiff = (int)pointer_to_Vga_character - (int)vga_txt_mat;

Cast them both to integers first, this gives you the difference in bytes.
The difference in bytes is not very useful... instead, the index *uses* to be useful...
And... I guess the correct way of calculating the difference in bytes of two pointers is by casting to void* and doing the difference between pointers operation (though I've read that the K&B-based compilers didn't have void*), not only but also because void* has the size of the (non-segmented) pointer in a given architecture...

JJ
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: About very complex C types...

Post by Solar »

JJeronimo wrote:...a pointer to a 80 chars array in C:

Code: Select all

char (*myarray)[80];
char myarray[80]; makes myarray a pointer to a 80 chars array (as myarray is the address of the first element of myarray[80]). Your construct above creates... a pointer to the pointer to the first element?
JJeronimo wrote:

Code: Select all

int (*my4Darray)[80][43][123];
That's not a 4D array, that's (a pointer to?) a 3D array. And you should get off those magic numbers. 8)

Then, you should become more precise in stating your problem, and stand up to the criticism. Your assigning of my4Darray - int based - to myarray - char based - is pretty bad mojo, and Candy is right to give it some flak.

I'll give your specific problem some thought tomorrow (too late to make sense of it ATM), but the general problem I see is that you are lacking fluency on C pointers / arrays. I see a handful of potential problems / bugs / errors in what little pseudocode you've shown here. Try working up from the base (one-dimensional arrays) with a couple of test programs, doing some pointer arithmetics, double-checking your intermediate results, and step by step going more complex, to get a better idea of what works and what doesn't. Trust me, it will save you serious headaches later on.
Every good solution is obvious once you've found it.
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

Re: About very complex C types...

Post by JJeronimo »

Solar wrote:I'll give your specific problem some thought tomorrow (too late to make sense of it ATM), but the general problem I see is that you are lacking fluency on C pointers / arrays. I see a handful of potential problems / bugs / errors in what little pseudocode you've shown here. Try working up from the base (one-dimensional arrays) with a couple of test programs, doing some pointer arithmetics, double-checking your intermediate results, and step by step going more complex, to get a better idea of what works and what doesn't. Trust me, it will save you serious headaches later on.
No, it doesn't cause me many headaches...
And, by the way, I've already obtained my answer in a programming newsgroup...

Code: Select all

(type (*) [80])
For the example I gave in the thread's first post...


I'm not very fluent in C pointers, that's true... But I don't have patience to solve meaningless exercises!
I learn much more coding interesting things than playing with language features without any goal in sight...
Fluency comes with experience!

JJ
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

Re: About very complex C types...

Post by JJeronimo »

Solar wrote:
JJeronimo wrote:...a pointer to a 80 chars array in C:

Code: Select all

char (*myarray)[80];
char myarray[80]; makes myarray a pointer to a 80 chars array (as myarray is the address of the first element of myarray[80]).
No! Nowhere in heel char myarray[80]; does create a pointer!
It creates an array, which is NOT the same thing!
It statically reserves 80 memory-neighbour chars, and makes the symbol "myarray" translate to the address of the first element...
You cannot do myarray++; because myarray is a symbol, not a pointer variable...
Your construct above creates... a pointer to the pointer to the first element?
What?! It creates a pointer to an array of 80 chars!
The "thing" that it points to is an array of 80 chars, this is, if you use an index the compiler will calculate (or make the output code calculate) the address of the corresponding *array* (and the object returned is a pointer to char).

If I do char (*myarray)[80]; and then myarray++;, the pointer's value will be incremented by 80*sizeof(char).
If I then do myarray[n], the pointer returned will be numerically equal to myarray's, but it's type would be pointer-to-char (to which I can apply another index to access any specific char), and not pointer-to-array-of-80-chars...
Did you understand?!
JJeronimo wrote:

Code: Select all

int (*my4Darray)[80][43][123];
That's not a 4D array, that's (a pointer to?) a 3D array.
Yes, more or less...
But I wouldn't use this type of thing to access a 3D array, because that would require me to state everywhere that I'm accessing the first element of the array...
And you should get off those magic numbers. 8)
What's the problem with magic numbers? I think they irrelevant to the problem!

JJ
Last edited by JJeronimo on Thu Jan 15, 2009 11:02 am, edited 1 time in total.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

JJeronimo wrote:
Ready4Dis wrote:If that's all you wanted to do, try this:

int tDiff = (int)pointer_to_Vga_character - (int)vga_txt_mat;

Cast them both to integers first, this gives you the difference in bytes.
The difference in bytes is not very useful... instead, the index *uses* to be useful...
And... I guess the correct way of calculating the difference in bytes of two pointers is by casting to void* and doing the difference between pointers operation (though I've read that the K&B-based compilers didn't have void*), not only but also because void* has the size of the (non-segmented) pointer in a given architecture...

JJ
Why is the difference in bytes not useful? You know that each character is 2 bytes, so simply divide the answer by 2, gives you the same answer as you're looking for, and you're only casting to integers, no void*, no (*)[]. If you cast to (*)[] you still have to convert that to an integer when you're done, unless you're assigning it to a (*)[]. Anyways, hope you have it all worked out now either way, have fun coding.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: About very complex C types...

Post by Solar »

JJeronimo wrote:I'm not very fluent in C pointers, that's true... But I don't have patience to solve meaningless exercises!
But you expect the patience in other people when answering your posts...
No! Nowhere in heel char myarray[80]; does create a pointer!
It creates an array, which is NOT the same thing!
If you declare int myarray[SIZE], then myarray and &(myarray[0]) are one and the same thing - the address, i.e. a pointer, to the first element of the array. It's not a pointer variable, true.
If I then do myarray[n], the pointer returned will be numerically equal to myarray's, but it's type would be pointer-to-char (to which I can apply another index to access any specific char), and not pointer-to-array-of-80-chars...
Did you understand?!
Yes, I got it now... you should perhaps encapsule that in an inline function, or perhaps a macro, and add some commentary to it, since that kind of pointer arithmetics could easily confuse people. (It confused you, for starters. ;) )
What's the problem with magic numbers? I think they irrelevant to the problem!
Style. Since those numbers are irrelevant to the problem, why should they be there, instead of e.g. COLS instead of 80? That way, people won't argue about the irrelevant numbers, and your code example would become much clearer too.
Every good solution is obvious once you've found it.
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

Re: About very complex C types...

Post by JJeronimo »

Solar wrote:
JJeronimo wrote:I'm not very fluent in C pointers, that's true... But I don't have patience to solve meaningless exercises!
But you expect the patience in other people when answering your posts...
I don't think it would be worth to do simple exercises to learn these kind if things... I really do prefer coding something useful...
What's the problem with magic numbers? I think they irrelevant to the problem!
Style. Since those numbers are irrelevant to the problem, why should they be there, instead of e.g. COLS instead of 80? That way, people won't argue about the irrelevant numbers, and your code example would become much clearer too.
Ok, ok... I'll take care of that in my following posts...

JJ
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: About very complex C types...

Post by Candy »

JJeronimo wrote:
Solar wrote:
JJeronimo wrote:I'm not very fluent in C pointers, that's true... But I don't have patience to solve meaningless exercises!
But you expect the patience in other people when answering your posts...
I don't think it would be worth to do simple exercises to learn these kind if things... I really do prefer coding something useful...
If you learn the answers to the questions you have now, you will have questions tomorrow. If you learn the thought behind the questions you have now, you will give answers tomorrow.
What's the problem with magic numbers? I think they irrelevant to the problem!
Style. Since those numbers are irrelevant to the problem, why should they be there, instead of e.g. COLS instead of 80? That way, people won't argue about the irrelevant numbers, and your code example would become much clearer too.
Ok, ok... I'll take care of that in my following posts...

JJ
There are more advantages. You can't make a number a variable the same way as making a define a variable, more constants can be 80 whilst they don't symbolize the same value logically, you could want to change cols to 132 which would cost you a load of search&replace, complicated by the previous item. Also, you're not working with logical entities but with concrete numbers. You have a lot to learn.
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

Re: About very complex C types...

Post by JJeronimo »

Candy wrote:
Style. Since those numbers are irrelevant to the problem, why should they be there, instead of e.g. COLS instead of 80? That way, people won't argue about the irrelevant numbers, and your code example would become much clearer too.
Ok, ok... I'll take care of that in my following posts...
There are more advantages. You can't make a number a variable the same way as making a define a variable, more constants can be 80 whilst they don't symbolize the same value logically, you could want to change cols to 132 which would cost you a load of search&replace, complicated by the previous item. Also, you're not working with logical entities but with concrete numbers. You have a lot to learn.
In my code I usually *do* use symbolic constants, only in the post I didn't use...

JJ
Post Reply