Passing an array of chars to a function

J

jr

Sorry for this very dumb question, but I've clearly got a long way to go!
Can someone please help me pass an array into a function. Here's a starting
point.

void TheMainFunc()
{
// Body of code...

TCHAR myArray[512];
DoStuff(myArray);
}

void DoStuff(TCHAR theArray)
{
...
}


I can't quite get my head around what the variable "myArray" is - is it a
pointer to a memory address that would hold a TCHAR (a wide char if
UNICODE)?

Thanks

John
 
R

Rolf Magnus

jr said:
Sorry for this very dumb question, but I've clearly got a long way to
go! Can someone please help me pass an array into a function.

You cannot pass arrays into functions. Usually, a pointer to the array's
first element is passed instead.
Here's a starting point.

void TheMainFunc()
{
// Body of code...

TCHAR myArray[512];
DoStuff(myArray);
}

void DoStuff(TCHAR theArray)
{
...
}


I can't quite get my head around what the variable "myArray" is - is
it a pointer to a memory address that would hold a TCHAR (a wide char
if UNICODE)?

myArray is an array of TCHAR. Your DoStuff function takes a parameter of
type TCHAR, i.e. _one_ character.

Try:
void DoStuff(TCHAR* theArray)

When you pass the array to DoStuff, it will be automatically converted
into a pointer to its first element.
 
D

David Harmon

TCHAR myArray[512];
DoStuff(myArray);
}

void DoStuff(TCHAR theArray)
{

void DoStuff(TCHAR * theArray)
{
I can't quite get my head around what the variable "myArray" is - is it a
pointer to a memory address that would hold a TCHAR (a wide char if
UNICODE)?

No, it's not a pointer, it's the actual storage for 256 instances of
TCHAR. But you often may refer to it as if it was a pointer, and C is
very ambivalent about that, converting the array variable name to a
pointer with little provocation where non-array types would require
operator& to get the pointer. C++ would probably prefer to consistently
require the operator&, but goes along with C for compatibility.
 
R

Rolf Magnus

David said:
TCHAR myArray[512];
I can't quite get my head around what the variable "myArray" is - is
it a pointer to a memory address that would hold a TCHAR (a wide char
if UNICODE)?

No, it's not a pointer, it's the actual storage for 256 instances of
TCHAR.

Sure about that? ;-)
 
J

Jumbo

Rolf Magnus said:
You cannot pass arrays into functions. Usually, a pointer to the array's
first element is passed instead.
Of course you pass arrays into functions:
#include <iostream>

void foo(char arr[]){
std::cout<< arr<<'\n';
arr[5]='!';
}

int main( )
{
char arr[10] = "hello";
foo(arr);
std::cout<< arr<<'\n';
}

Also if you alter the array inside the function the original is also
altered.

<snip>

HTH.
 
D

David Harmon

David said:
TCHAR myArray[512];
I can't quite get my head around what the variable "myArray" is - is
it a pointer to a memory address that would hold a TCHAR (a wide char
if UNICODE)?

No, it's not a pointer, it's the actual storage for 256 instances of
TCHAR.

Sure about that? ;-)

Oopsie. I didn't think he really needed the full 512.
 
J

Jack Klein

Of course you pass arrays into functions:

No, you can't.

From the ISO C++ standard, "5.2.2 Function call", paragraph 7:

"The lvalue tor value (4.1), array to pointer (4.2), and function to
pointer (4.3) standard conversions are performed on the argument
expression."

The name of an array used as a function call argument is always
converted to a pointer to its first element.

But you can pass an array to a function if it is enclosed in a struct
or class and you pass an instance of the struct or class by value.
 
A

ArunPrakash

Hi jr,
when u declare an array in c or c++, the variable name is a
pointer to the first element of the array. So u can treat the variable
name as a pointer. In your case myArray is a pointer to a TCHAR. (
similar to TCHAR * myArray ).
as far as your function signature goes, in order for it to compile
successfully it must be either of these 2 i guess..

void DoStuff( TCHAR * theArray )
{
}

or

void DoStuff( TCHAR theArray[] )
{
}

Hi All,
This is my first post and reply. So plz bear with my mistakes, if
any. But for jr, i hope there are no mistakes.

Thanks and Regards,
Arun Prakash. B
 
J

Jumbo

Jack Klein said:
No, you can't.

From the ISO C++ standard, "5.2.2 Function call", paragraph 7:

"The lvalue tor value (4.1), array to pointer (4.2), and function to
pointer (4.3) standard conversions are performed on the argument
expression."

The name of an array used as a function call argument is always
converted to a pointer to its first element.

But you can pass an array to a function if it is enclosed in a struct
or class and you pass an instance of the struct or class by value.
Yip :)
 
R

Rolf Magnus

Jumbo said:
Rolf Magnus said:
You cannot pass arrays into functions. Usually, a pointer to the
array's first element is passed instead.
Of course you pass arrays into functions:
#include <iostream>

void foo(char arr[]){

arr is not an array, but a pointer to its first element. You can see
that it's not an array, because it doesn't have a size between its [],
and arrays _always_ have a size. The only place where this is allowed
is if you define an array and initialize it, so the size can be
determined from the initializer, like:

char c[] = "Hello, world\n";
std::cout<< arr<<'\n';
arr[5]='!';
}

int main( )
{
char arr[10] = "hello";
foo(arr);
std::cout<< arr<<'\n';
}

Also if you alter the array inside the function the original is also
altered.

Yes, that's because you didn't pass the array. If you had done that, the
function would have a copy of it and the original couldn't be modified
by that function.
 
J

Jeff Schwab

Jack said:
No, you can't.

From the ISO C++ standard, "5.2.2 Function call", paragraph 7:

"The lvalue tor value (4.1), array to pointer (4.2), and function to
pointer (4.3) standard conversions are performed on the argument
expression."

The name of an array used as a function call argument is always
converted to a pointer to its first element.

But you can pass an array to a function if it is enclosed in a struct
or class and you pass an instance of the struct or class by value.

Those conversions aren't always performed, because they're not always
necessary. Here's an example of passing an array by value. Without the
explicit template argument, the decay to a pointer type does take place.

#include <iostream>

template< typename T >
void f_by_value( T t )
{
t[ 0 ] = 1;
}

int main( )
{
int array[ ] = { 0 };

f_by_value< int[ 1 ] >( array );

std::cout << array[ 0 ] << '\n';
}
 
R

Rolf Magnus

Jeff said:
The name of an array used as a function call argument is always
converted to a pointer to its first element.

But you can pass an array to a function if it is enclosed in a struct
or class and you pass an instance of the struct or class by value.

Those conversions aren't always performed, because they're not always
necessary. Here's an example of passing an array by value. Without
the explicit template argument, the decay to a pointer type does take
place.

#include <iostream>

template< typename T >
void f_by_value( T t )
{
t[ 0 ] = 1;
}

int main( )
{
int array[ ] = { 0 };

f_by_value< int[ 1 ] >( array );

std::cout << array[ 0 ] << '\n';
}

Hmm, is that really standard conforming? Your program does work as one
would expect if the array were passed by value on gcc 3.3.2, but if I
modify the example to print the value of t[0] in f_by_value() before
modifying it, it turns out to be uninitialized and not 0 as expected.
Similar, if I use a class instead of int, my class's copy constructor
is not called. So which part is non-conforming here? The fact that it
accepts an array by value or the fact that the objects are not properly
copied? Or is there some other magic involved that just tricks us into
thinking it'S pass-by-value?
 
J

Jeff Schwab

Rolf said:
Jeff Schwab wrote:

The name of an array used as a function call argument is always
converted to a pointer to its first element.

But you can pass an array to a function if it is enclosed in a struct
or class and you pass an instance of the struct or class by value.

Those conversions aren't always performed, because they're not always
necessary. Here's an example of passing an array by value. Without
the explicit template argument, the decay to a pointer type does take
place.

#include <iostream>

template< typename T >
void f_by_value( T t )
{
t[ 0 ] = 1;
}

int main( )
{
int array[ ] = { 0 };

f_by_value< int[ 1 ] >( array );

std::cout << array[ 0 ] << '\n';
}


Hmm, is that really standard conforming? Your program does work as one
would expect if the array were passed by value on gcc 3.3.2, but if I
modify the example to print the value of t[0] in f_by_value() before
modifying it, it turns out to be uninitialized and not 0 as expected.
Similar, if I use a class instead of int, my class's copy constructor
is not called. So which part is non-conforming here? The fact that it
accepts an array by value or the fact that the objects are not properly
copied? Or is there some other magic involved that just tricks us into
thinking it'S pass-by-value?

That's interesting. I assumed the value was being copied properly, but
I see now that I was wrong. Thanks for correcting me! P. 92 of TC++PL
says:

... char v[] = "Annemarie";
... strlen(v); // implicit conversion of char[] to char*


... there is no way of declaring a function so that the
array v is copied when the function is called.

For the OP's benefit, someone should probably mention that std::vector
provides most benefits of arrays, and is easily passed by value.
 
J

Jumbo

Rolf Magnus said:
Jumbo said:
Rolf Magnus said:
jr wrote:

Sorry for this very dumb question, but I've clearly got a long way
to go! Can someone please help me pass an array into a function.

You cannot pass arrays into functions. Usually, a pointer to the
array's first element is passed instead.
Of course you pass arrays into functions:
#include <iostream>

void foo(char arr[]){

arr is not an array, but a pointer to its first element.
But that's just what an array is.
You can see
that it's not an array, because it doesn't have a size between its [],
and arrays _always_ have a size. The only place where this is allowed
is if you define an array and initialize it, so the size can be
determined from the initializer, like:

You could go into the guts of the computer and say everydata is the same as
it simply a picice of memory.
This is like the argument that a char is really an integer etc.

Just because an array happens to be turned into a pointer by the compiler
when you pass it to a function deoesn't mean to say that we're not passing
an array to a function. We're still passing an array to a function and it's
not a copy. So as we are passing the actually array and not a copy it even
more true to say we ARE passsing an array to a function.
char c[] = "Hello, world\n";
std::cout<< arr<<'\n';
arr[5]='!';
}

int main( )
{
char arr[10] = "hello";
foo(arr);
std::cout<< arr<<'\n';
}

Also if you alter the array inside the function the original is also
altered.

Yes, that's because you didn't pass the array. If you had done that, the
function would have a copy of it and the original couldn't be modified
by that function.
You seem to be meaning that passing an array to a function is only passing
the array if it passes a copy.
I would consider it to be the other way around where "passing the array"
would be passing by ref and passing a copy your aren't actally passing the
array your passing a copy..
 
R

Ron Natalie

Jumbo @uko2.co.uk> said:
Just because an array happens to be turned into a pointer by the compiler
when you pass it to a function deoesn't mean to say that we're not passing
an array to a function. We're still passing an array to a function and it's
not a copy. So as we are passing the actually array and not a copy it even
more true to say we ARE passsing an array to a function.

Which is to say that an array works differently in subroutine passing than
EVERY OTHER SINGLE DATA TYPE.

But you're still wrong. The language specifically says that the function parameter
types of type array are explicitly changed to pointer.

void foo(int []);
and
void foo(int*)

mean exactly the same thing.

Passing an array to such a function invokes an array-to-pointer conversion before
the function isn't called. What is passed is the pointer.
 
J

Jumbo

Ron Natalie said:
"Jumbo @uko2.co.uk>" <pcr1000011<nospam> wrote in message news:[email protected]...
Just because an array happens to be turned into a pointer by the compiler
when you pass it to a function deoesn't mean to say that we're not passing
an array to a function. We're still passing an array to a function and it's
not a copy. So as we are passing the actually array and not a copy it even
more true to say we ARE passsing an array to a function.

Which is to say that an array works differently in subroutine passing than
EVERY OTHER SINGLE DATA TYPE.

But you're still wrong. The language specifically says that the function parameter
types of type array are explicitly changed to pointer.

void foo(int []);
and
void foo(int*)

mean exactly the same thing.

Passing an array to such a function invokes an array-to-pointer conversion before
the function isn't called. What is passed is the pointer.
Yes we know this is true from the compilers point of view.
But from the programmers point of view your passing the array not a pointer
to an array.
The thing is that arrays are passed by ref as opposed to most other data
types, I wouldn't consider this as not passing an array.
Your still passing an array it's just that the behavior is different.
It's to do with your understanding of how arrays work under the hood.

Anyway putting our disagreements aside, what is going on here if arrays are
never passed by val:
#include <iostream>

void foo(const char p1[],const char p2[]){
p1="STUV";
p2="WXYZ";
std::cout<< "In foo():\t" << p1 << '\t' << p2 << std::endl;
}

int main(){
const char pch1[]= "ABCD";
const char* pch2= "EFGH";
foo(pch1,pch2);

std::cout<< "In main():\t" << pch1 << '\t' << pch2 << std::endl;
return 0;
}
 
J

Jeff Schwab

Jumbo
Jumbo wrote:

jr wrote:


Sorry for this very dumb question, but I've clearly got a long way
to go! Can someone please help me pass an array into a function.

You cannot pass arrays into functions. Usually, a pointer to the
array's first element is passed instead.


Of course you pass arrays into functions:
#include <iostream>

void foo(char arr[]){

arr is not an array, but a pointer to its first element.

But that's just what an array is.

No, it's not.
You can see
that it's not an array, because it doesn't have a size between its [],
and arrays _always_ have a size. The only place where this is allowed
is if you define an array and initialize it, so the size can be
determined from the initializer, like:


You could go into the guts of the computer and say everydata is the same as
it simply a picice of memory.
This is like the argument that a char is really an integer etc.

Just because an array happens to be turned into a pointer by the compiler
when you pass it to a function deoesn't mean to say that we're not passing
an array to a function. We're still passing an array to a function and it's
not a copy. So as we are passing the actually array and not a copy it even
more true to say we ARE passsing an array to a function.

char c[] = "Hello, world\n";

std::cout<< arr<<'\n';
arr[5]='!';
}

int main( )
{
char arr[10] = "hello";
foo(arr);
std::cout<< arr<<'\n';
}

Also if you alter the array inside the function the original is also
altered.

Yes, that's because you didn't pass the array. If you had done that, the
function would have a copy of it and the original couldn't be modified
by that function.

You seem to be meaning that passing an array to a function is only passing
the array if it passes a copy.
I would consider it to be the other way around where "passing the array"
would be passing by ref and passing a copy your aren't actally passing the
array your passing a copy..

"Pass" here means "pass by value," not by address.
 
K

Kevin Goodsell

Jumbo said:
But that's just what an array is.

Not true. An array is an array. A pointer is a pointer. There are some
syntactic similarities in how they are used*, but there are very
important differences between the two.

*Actually, the only reason for these similarities is the implicit
conversion of an array name to a pointer in most contexts.
Just because an array happens to be turned into a pointer by the compiler
when you pass it to a function deoesn't mean to say that we're not passing
an array to a function.

Of course it does. If you're passing a pointer then you aren't passing
an array. There's not some magic dual type that is simultaneously a
pointer and an array.
We're still passing an array to a function and it's
not a copy. So as we are passing the actually array and not a copy it even
more true to say we ARE passsing an array to a function.

This is simply not true, as you can demonstrate easily enough:

#include <iostream>

void pass_array(int a[])
{
std::cout << "sizeof(a) = " << sizeof(a) << std::endl;
}

int main()
{
int array[100];
std::cout << "sizeof(array) = " << sizeof(array) << std::endl;
pass_array(array);
return 0;
}

On my implementation I get this output:

sizeof(array) = 400
sizeof(a) = 4

How can you account for this if 'a' really is 'array'? It's quite easy
to account for if 'a' is actually a pointer (which it is). Also, you can
change the signature for pass_array to any of these:

void pass_array(int *a)
void pass_array(int a[100])
void pass_array(int a[7])

And you'll get the same results, because all four mean exactly the same
thing. 'a' is actually a pointer.
You seem to be meaning that passing an array to a function is only passing
the array if it passes a copy.

I doubt that's what he was trying to say.
I would consider it to be the other way around where "passing the array"
would be passing by ref and passing a copy your aren't actally passing the
array your passing a copy..

OK, but that's not what's happening, either. You *can* pass a reference
to an array to a function if you want to, but this is not done very
often because it's of limited usefulness - the function is specific to a
particular size of array (unless you make the size a template argument).

For example, if I change my previous example so that pass_array's
signature is this:

void pass_array(int (&a)[100])

Then I get the following output:

sizeof(array) = 400
sizeof(a) = 400

-Kevin
 
J

Jumbo

Kevin Goodsell said:
Jumbo said:
But that's just what an array is.

Not true. An array is an array. A pointer is a pointer. There are some
syntactic similarities in how they are used*, but there are very
important differences between the two.

*Actually, the only reason for these similarities is the implicit
conversion of an array name to a pointer in most contexts.
Just because an array happens to be turned into a pointer by the compiler
when you pass it to a function deoesn't mean to say that we're not passing
an array to a function.

Of course it does. If you're passing a pointer then you aren't passing
an array. There's not some magic dual type that is simultaneously a
pointer and an array.
We're still passing an array to a function and it's
not a copy. So as we are passing the actually array and not a copy it even
more true to say we ARE passsing an array to a function.

This is simply not true, as you can demonstrate easily enough:

#include <iostream>

void pass_array(int a[])
{
std::cout << "sizeof(a) = " << sizeof(a) << std::endl;
}

int main()
{
int array[100];
std::cout << "sizeof(array) = " << sizeof(array) << std::endl;
pass_array(array);
return 0;
}

On my implementation I get this output:

sizeof(array) = 400
sizeof(a) = 4

How can you account for this if 'a' really is 'array'? It's quite easy
to account for if 'a' is actually a pointer (which it is). Also, you can
change the signature for pass_array to any of these:

void pass_array(int *a)
void pass_array(int a[100])
void pass_array(int a[7])

And you'll get the same results, because all four mean exactly the same
thing. 'a' is actually a pointer.
You seem to be meaning that passing an array to a function is only passing
the array if it passes a copy.

I doubt that's what he was trying to say.
I would consider it to be the other way around where "passing the array"
would be passing by ref and passing a copy your aren't actally passing the
array your passing a copy..

OK, but that's not what's happening, either. You *can* pass a reference
to an array to a function if you want to, but this is not done very
often because it's of limited usefulness - the function is specific to a
particular size of array (unless you make the size a template argument).

For example, if I change my previous example so that pass_array's
signature is this:

void pass_array(int (&a)[100])

Then I get the following output:

sizeof(array) = 400
sizeof(a) = 400
Well then surely this clarifies that you *can* pass an array to a function ,
whatever way you look at it?
Yes it is important to understand how the array is passed by the compiler.
However at the end of the day whether you pass the array by ref, val , or by
pointer you're still passing the array to a function in some way or other.

Consider this:
#include <iostream>

void foo(const char arr1[]){
arr1="ZZZZ";
std::cout<< "In foo():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
}
int main(){
const char arr1[]= "ABCD";
foo(arr1);
std::cout<< "In main():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
return 0;
}

On my system this outputs
In foo(): sizeof array: 4 value: ZZZZ
In main(): sizeof array: 5 value: ABCD

So what's going on here then, Is this non compliant code?
 
K

Kevin Goodsell

Jumbo <pcr1000011 wrote:

Please trim your replies. There was no need to quote my entire message.
Well then surely this clarifies that you *can* pass an array to a function ,
whatever way you look at it?

Not at all. You can pass a pointer, or a reference, but not an array (at
least not directly - as already mentioned, it can be wrapped in a class).
Yes it is important to understand how the array is passed by the compiler.
However at the end of the day whether you pass the array by ref, val , or by
pointer you're still passing the array to a function in some way or other.

No, in all cases you are passing something that refers to the array in
some way. The effect is that you can access the array from the function,
but "passing" of arrays to functions is still significantly different
than passing other types, and the distinction is important for anyone
who wants to use the language effectively.
Consider this:
#include <iostream>

void foo(const char arr1[]){
arr1="ZZZZ";
std::cout<< "In foo():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
}
int main(){
const char arr1[]= "ABCD";
foo(arr1);
std::cout<< "In main():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
return 0;
}

On my system this outputs
In foo(): sizeof array: 4 value: ZZZZ
In main(): sizeof array: 5 value: ABCD

So what's going on here then, Is this non compliant code?

As far as I can tell it's compliant, but it doesn't provide any evidence
to back up your claim. You create an array 'arr1' in main, which is 5
characters long. You pass a pointer to that array to foo. The pointer is
passed by value, thus foo gets a copy. foo immediately modifies its
copy, making it point to a string literal. The first line of output
gives the size of a pointer and the value of the string literal to which
that pointer points. Back in main, 'arr1' is unmodified, and the second
line of output gives the size of the storage used for arr1 (5
characters) and the value stored there (as given in the initialization
of arr1).

-Kevin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top