If the function is defined in the same translation unit (and the prototype is just a forward declaration) then it doesn't matter, the compiler will most likely inline the function and you won't be able to tell the difference.
If the function is defined in another translation unit (external linkage) then the compiler generates a function call.  Most calling conventions pass the first few parameters in registers, that would definitely be the case for the character or reference to the character.  If you pass by value the compiler will load the character into the register for the first parameter, if you pass by reference the compiler will place the address of the character in the register for the first parameter, the called function will then load the character from that address.  Which is more efficient? Probably passing by value, but in today's CPUs with out-of-order execution and multiple instructions dispatched every cycle the reality is you probably can't tell the difference.
Here's a simple c++ program to see what gcc generates on Linux:
extern char byvalue( char );
extern char byref( const char & );
int main( int argc, char * argv[] )
{
    char c = byvalue( argv[0][0] ) + byref( argv[0][1] );
    return c;
}
I compiled and looked at the generated code:
$ g++ -O3 param.cpp -c -o param.o
$ objdump -D param.o|less
Here's what the generated code for those two calls look like in function main - %rdi/%edi is the register for the first (and in this case only) parameter:
0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   53                      push   %rbx
   2:   48 89 f3                mov    %rsi,%rbx
   5:   48 83 ec 08             sub    $0x8,%rsp
   9:   48 8b 06                mov    (%rsi),%rax
   c:   0f be 38                movsbl (%rax),%edi     ; %edi is character
   f:   e8 00 00 00 00          callq  14 <main+0x14>  ; byvalue
  14:   48 8b 3b                mov    (%rbx),%rdi
  17:   89 c5                   mov    %eax,%ebp
  19:   48 83 c7 01             add    $0x1,%rdi       ; %rdi is address of character
  1d:   e8 00 00 00 00          callq  22 <main+0x22>  ; byref
  22:   48 83 c4 08             add    $0x8,%rsp
  26:   01 e8                   add    %ebp,%eax
  28:   5b                      pop    %rbx
  29:   0f be c0                movsbl %al,%eax
  2c:   5d                      pop    %rbp
  2d:   c3                      retq   
As you can see the compiler generated code to either load the character
   c:   0f be 38                movsbl (%rax),%edi     ; %edi is character
   f:   e8 00 00 00 00          callq  14 <main+0x14>  ; byvalue
Or load the address of the character
  19:   48 83 c7 01             add    $0x1,%rdi       ; %rdi is address of character
  1d:   e8 00 00 00 00          callq  22 <main+0x22>  ; byref