Page 1 of 1
About very complex C types...
Posted: Fri Dec 22, 2006 8:20 pm
by JJeronimo
Let's define a pointer to a 80 chars array in C:
Now, if a have the following pointer:
...that contains an address that I want to assign to myarray.
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*...
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
Re: About very complex C types...
Posted: Sat Dec 23, 2006 4:46 am
by Candy
JJeronimo wrote:Let's define a pointer to a 80 chars array in C:
Now, if a have the following pointer:
...that contains an address that I want to assign to myarray.
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?
Posted: Sat Dec 23, 2006 5:07 am
by Ready4Dis
Yes, please let us know what you're trying to accomplish, there might be a much nicer way of doing things.
Posted: Sat Dec 23, 2006 9:38 am
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
Re: About very complex C types...
Posted: Sat Dec 23, 2006 9:51 am
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
Posted: Wed Dec 27, 2006 7:53 am
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.
Posted: Wed Dec 27, 2006 5:27 pm
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
Re: About very complex C types...
Posted: Wed Dec 27, 2006 7:07 pm
by Solar
JJeronimo wrote:...a pointer to a 80 chars array in C:
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?
That's not a 4D array, that's (a pointer to?) a 3D array. And you should get off those magic numbers.
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.
Re: About very complex C types...
Posted: Wed Dec 27, 2006 9:49 pm
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...
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
Re: About very complex C types...
Posted: Wed Dec 27, 2006 10:13 pm
by JJeronimo
Solar wrote:JJeronimo wrote:...a pointer to a 80 chars array in C:
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?!
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.
What's the problem with magic numbers? I think they irrelevant to the problem!
JJ
Posted: Thu Dec 28, 2006 5:02 am
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.
Re: About very complex C types...
Posted: Fri Dec 29, 2006 8:55 am
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.
Re: About very complex C types...
Posted: Fri Dec 29, 2006 10:25 pm
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
Re: About very complex C types...
Posted: Sat Dec 30, 2006 1:41 am
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.
Re: About very complex C types...
Posted: Sat Dec 30, 2006 11:32 am
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