Cartoondog
Cartoondog

Reputation: 105

Passing values to an function

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

Answers (4)

Kyle
Kyle

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

Mark Tolonen
Mark Tolonen

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

Renato Medeiros
Renato Medeiros

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

mrjoltcola
mrjoltcola

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

Related Questions