Reputation: 105
I am missing a fundamental point on passing values.
In my code, I wrote this prototype/function:
void drawFont (char A[],unsigned char length, char x1, char y1, uint16 FGcolor);
I call the function using a call like this:
drawFont ("William",7,15,25,YEL,0);
or
drawFont ("W",1,15,25,YEL,0);
Both of these work fine in the code. If I examine A[0] in the function, I will see a value of '57' representing an ASCII 'W'. All fine and good.
My question/problem is: When I attempt to replicate the 'W' using the ASCII value instead of the string representation, my code fails Example:
drawFont (57,1,15,25,YEL,0);
The value of A[0] in the code is: 0, but the address of A is 57. So somehow the compiler assumes that I want to pass a pointer? I'm confused, why did it pass the string fine, but not the value?
Thanks in advance from a novice C programmer.
Upvotes: 1
Views: 382
Reputation: 177
Your function requires a string ( char[] ) as an argument. When you pass "William" it is interpreted as a string, that's normal. When you pass "W" it is also interpreted as a string:
string[2] = { 'W' + 0 } //notice the null byte following your char
That's because you used double-quotes " instead of single-quotes '. Therefore passing 57 or 'W' is viewed as a single char and not a char[]/string which then gives you an error since your function is expecting a char[] and you gave it a char.
Upvotes: 0
Reputation: 178409
The prototype for your function declares that the first parameter is a pointer to a character:
void drawFont (char A[],...);
If you pass an integer, you are breaking the rules. The compiler should warn about it. Mine gives a warning about the following code on the line with func(57)
:
void func(char a[])
{
}
char arr[] = {87,84,70};
int main()
{
func(57);
func("W");
func(arr);
}
x.c(9) : warning C4047: 'function' : 'char *' differs in levels of indirection from 'int'
x.c(9) : warning C4024: 'func' : different types for formal and actual parameter 1
If you look at the assembly output from the compiler, you can see the problem more clearly (I cut out the uninteresting parts):
PUBLIC _arr
_DATA SEGMENT
_arr DB 057H ;Here's the char array at an address in memory.
DB 054H
DB 046H
ORG $+1
$SG1297 DB 'W', 00H ;Here's the "W" at an address in memory (nul-terminated)
_DATA ENDS
; 9 : func(57);
00003 6a 39 push 57 ; Push 57 as the address, WRONG!
00005 e8 00 00 00 00 call _func
0000a 83 c4 04 add esp, 4
; 10 : func("W");
0000d 68 00 00 00 00 push OFFSET $SG1297 ; Push the address of the string.
00012 e8 00 00 00 00 call _func
00017 83 c4 04 add esp, 4
; 11 : func(arr);
0001a 68 00 00 00 00 push OFFSET _arr ; Push the address of the array.
0001f e8 00 00 00 00 call _func
00024 83 c4 04 add esp, 4
The code is expecting to go to an address to read characters. Who knows what is in address 57.
Upvotes: 1
Reputation: 453
If you pass
drawFont (57,1,15,25,YEL,0);
you will be doming the same as
drawFont ('W',1,15,25,YEL,0);
which is just one character. The function requires an array of characters, that's why it's not correct.
Upvotes: 2
Reputation: 20862
The value of A[]
is actually a pointer, such as &A[0]
(you could rewrite the function using char *A
instead of char A[]
That is the address of the first slot, not what is stored in it. In the memory location pointed to by the pointer, there exists a value 57
. When you write a function with a char array or char pointer parameter, you tell the compiler: I will pass you a memory address. Go to that address and start reading each char (number) until you arrive at the null byte, then stop.
But when you pass literal integer 57 as the argument, that is not a valid pointer to an array of characters. You are missing the level of indirection.
So lets assume your char A[] resides at 0xfeaa0011
In RAM at 0xfeaa0011
-> "William" (or 52, ...)
The correct call to drawFont() actually looks like drawFont(0xfeaa0011
, 1, 15, 25, YEL, 0)
So you see replacing the pointer with 57 isn't the same thing.
Upvotes: 1