10 Replies - 34030 Views - Last Post: 29 November 2008 - 10:46 AM Rate Topic: -----

#1 babypluto07  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 21
  • Joined: 19-November 08

Passing by reference with Arrays C++

Post icon  Posted 28 November 2008 - 02:45 PM

I have to write a program asking the user for ages of 5 people. Then i store the ages in an array. One the ages are entered, i need to pass the array to a function in order to determine how many voters are in the array. The function should return the number of elgible voters by reference. I am able to get this code to work, however i can't get it to pass by reference as i'm confused. I admit, passing by reference is my weakest topic in C++. Can anyone look at my code and advise me how i can fix this?

#include <iostream>
using namespace std;
const int array_=5;
const int ageToVote=18;
int Findeligible (int[], int);

int main()
{
	int iArray[array_];
	
	//first we will populate the array
	for(int i=0;i<array_;i++)
	{
		cout<<"Please enter your age:  ";
		cin>>iArray[i];
	}
	int index=Findeligible(iArray, array_);	
	cout<<index<<" out of the "<<array_<<" are eligible to vote."<<endl;
 
	system("PAUSE");
	return 0;
}

int Findeligible (int array[], int length)
{
	 int eligCount=0;
	for (int n=0; n<length; n++)
	{
	  if (array [n] >= ageToVote)
	  {
	   eligCount=eligCount +1;
	   }
	 
	 
	}
return eligCount;
}


Is This A Good Question/Topic? 0
  • +

Replies To: Passing by reference with Arrays C++

#2 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Passing by reference with Arrays C++

Posted 28 November 2008 - 02:46 PM

int Findeligible (int*, int);

//later down in code
//function call is the same
int index=Findeligible(iArray, array_);   


//function
int Findeligible (int* arr, int size)
{
    //access array using [] like normal
}




edited for clarity

This post has been edited by KYA: 28 November 2008 - 02:47 PM

Was This Post Helpful? 1
  • +
  • -

#3 babypluto07  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 21
  • Joined: 19-November 08

Re: Passing by reference with Arrays C++

Posted 28 November 2008 - 03:00 PM

Thank you for your input. Just so i understand, do i use a '*' when it comes to a reference in Arrays? Our teachersnever showed us this way and i have always used "&" for this.
Was This Post Helpful? 0
  • +
  • -

#4 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Passing by reference with Arrays C++

Posted 28 November 2008 - 03:06 PM

Not always. An array is a set of data with a pointer to its first object. Since we pass the array in, the function receives it as a pointer to the first element and thus we can access it like a normal array. When passing by reference for other variables and such we do

void increment(int&);

//in main
int theVal = 1;
increment(theVal);


//function

void increment(int& num) //passing by ref we affect the actual var
{
    num += 1;
}


This post has been edited by KYA: 28 November 2008 - 03:06 PM

Was This Post Helpful? 0
  • +
  • -

#5 janotte  Icon User is offline

  • code > sword
  • member icon

Reputation: 988
  • View blog
  • Posts: 5,135
  • Joined: 28-September 06

Re: Passing by reference with Arrays C++

Posted 28 November 2008 - 09:35 PM

View Postbabypluto07, on 28 Nov, 2008 - 02:00 PM, said:

Thank you for your input. Just so i understand, do i use a '*' when it comes to a reference in Arrays? Our teachersnever showed us this way and i have always used "&" for this.


Your teachers are using the reference '&' feature because they are teaching you C++.

The pointer '*' method of accessing arrays exists in both C and C++.

The reference '&' feature exists in C++ but not in C.

If the teacher is asking you to use 'reference' then I'd suggest you need to be sure to use '&' as they may mark you down if you use the pointer way.

Although it is valid to write C++ 'as a better C' I'm of the opinion that it is better to write C++ as C++ and use the appropriate headers (e.g. #include <cstdio> rather than #include <stdio.h>) and generally look forwards not backwards. But that's just an opinion.

Here's some more general reading if you are interested.
http://en.wikipedia....rence_(C%2B%2B)
Was This Post Helpful? 0
  • +
  • -

#6 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 854
  • View blog
  • Posts: 2,338
  • Joined: 20-August 07

Re: Passing by reference with Arrays C++

Posted 29 November 2008 - 03:59 AM

View Postbabypluto07, on 28 Nov, 2008 - 10:00 PM, said:

Thank you for your input. Just so i understand, do i use a '*' when it comes to a reference in Arrays? Our teachersnever showed us this way and i have always used "&" for this.

Whether you decide to use a * or a [] is entirely up to you (its a matter of personal choice/style - your compiler will treat them the same regardless). Personally, I would use [], just to document the fact that the function is expecting an array rather than a pointer. Passing an array using & (by reference) is different, and maybe preferable depending on your requirements.

Just to clarify, the following 3 declarations are identical as far as your C++ compiler is concerned
void func( int* arr ) {}
void func( int arr[] ) {}
void func( int arr[5] ) {}

Unlike passing in ordinary variables, arrays are never copied. So C++ has some alternative behaviour for passing arrays as function parameters instead; they're always passed "by pointer".
Please bear in mind - this does not mean that an array is a pointer (and a pointer is not an array), pointers are merely used as a means to referring to an array from within a function - conveniently, pointers and arrays are allowed to use the same syntax, but don't let this confuse you.
From the compiler's perspective, the only meaningful interpretation of a single array subscript operator in a function signature is a pointer.

In the last instance, the 5 is ignored by the compiler entirely. In fact, if you were to call that version of the function, you could pass an array of any size. Though of course, common sense to anyone reading it would suggest that the function is expecting an array with 5 elements. The reason this is allowed is most likely as a "hint" to anyone reading the code.

Just to prove that these 3 signatures are indeed identical, paste them into your C++ compiler - it will complain about redefinition of functions. If they had been different, your compiler would happily accept them as overloads.

The fact that the compiler shows these 3 declarations are identical has a number of implications -
- The above functions cannot tell the difference between an array argument and a pointer argument. Which means whoever calls the function must be somewhat cautious as to what exactly gets passed. If a pointer to something which is of an incorrect size gets passed, the function may fall over or behave unpredictably.
- The above functions cannot determine the sizeof these arrays at compile time because the data type is a pointer - sizeof will simply yield the size of a pointer on your system (The usual way to keep track of their size is to pass the size as a separate argument)
- Pointers can be null, so you should check for null in any function which accepts a pointer argument


The alternative method of passing arrays, by-reference uses slightly modified syntax
void func( int (&arr)[5] ) {} 

The extra pair of parenthesis are required because you are creating a reference-to-array rather than array-of-references (The latter is invalid anyway, but C++'s right-left syntax parsing rule would recognise it as such)

The main practical difference here is that the full type information of the array must be included in the function. Unlike passing-by-pointer, the reference parameter enforces the exact kind of argument which the function can accept. - You must pass a statically allocated array of 5 ints, else the compiler will complain.
The obvious main benefits of this are that the compiler can give you the size of the array using sizeof (Though this is somewhat less useful in normal circumstances, since its size will be fixed anyway).

with array by-reference You also don't need to worry about the function being called with a null pointer or an array of an incorrect size, since the compiler enforces the kind of array you can pass (Pointers disallowed, and statically allocated arrays cannot be 'null').


Neither of these solutions are at all perfect by any means. If this were a real-world C++ situation, or anything bigger than an exercise to learn about arrays and/or pointers, the better solution would be to pick one of the tools in C++'s STL, such as a vector (a vector is essentially a 'C++ array' )

This post has been edited by Bench: 29 November 2008 - 04:05 AM

Was This Post Helpful? 0
  • +
  • -

#7 robhilly  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 46
  • Joined: 26-May 08

Re: Passing by reference with Arrays C++

Posted 29 November 2008 - 04:27 AM

View PostBench, on 29 Nov, 2008 - 02:59 AM, said:

View Postbabypluto07, on 28 Nov, 2008 - 10:00 PM, said:

Thank you for your input. Just so i understand, do i use a '*' when it comes to a reference in Arrays? Our teachersnever showed us this way and i have always used "&" for this.

Whether you decide to use a * or a [] is entirely up to you (its a matter of personal choice/style - your compiler will treat them the same regardless). Personally, I would use [], just to document the fact that the function is expecting an array rather than a pointer. Passing an array using & (by reference) is different, and maybe preferable depending on your requirements.

Just to clarify, the following 3 declarations are identical as far as your C++ compiler is concerned
void func( int* arr ) {}
void func( int arr[] ) {}
void func( int arr[5] ) {}

Unlike passing in ordinary variables, arrays are never copied. So C++ has some alternative behaviour for passing arrays as function parameters instead; they're always passed "by pointer".
Please bear in mind - this does not mean that an array is a pointer (and a pointer is not an array), pointers are merely used as a means to referring to an array from within a function - conveniently, pointers and arrays are allowed to use the same syntax, but don't let this confuse you.
From the compiler's perspective, the only meaningful interpretation of a single array subscript operator in a function signature is a pointer.

In the last instance, the 5 is ignored by the compiler entirely. In fact, if you were to call that version of the function, you could pass an array of any size. Though of course, common sense to anyone reading it would suggest that the function is expecting an array with 5 elements. The reason this is allowed is most likely as a "hint" to anyone reading the code.

Just to prove that these 3 signatures are indeed identical, paste them into your C++ compiler - it will complain about redefinition of functions. If they had been different, your compiler would happily accept them as overloads.

The fact that the compiler shows these 3 declarations are identical has a number of implications -
- The above functions cannot tell the difference between an array argument and a pointer argument. Which means whoever calls the function must be somewhat cautious as to what exactly gets passed. If a pointer to something which is of an incorrect size gets passed, the function may fall over or behave unpredictably.
- The above functions cannot determine the sizeof these arrays at compile time because the data type is a pointer - sizeof will simply yield the size of a pointer on your system (The usual way to keep track of their size is to pass the size as a separate argument)
- Pointers can be null, so you should check for null in any function which accepts a pointer argument


The alternative method of passing arrays, by-reference uses slightly modified syntax
void func( int (&arr)[5] ) {} 

The extra pair of parenthesis are required because you are creating a reference-to-array rather than array-of-references (The latter is invalid anyway, but C++'s right-left syntax parsing rule would recognise it as such)

The main practical difference here is that the full type information of the array must be included in the function. Unlike passing-by-pointer, the reference parameter enforces the exact kind of argument which the function can accept. - You must pass a statically allocated array of 5 ints, else the compiler will complain.
The obvious main benefits of this are that the compiler can give you the size of the array using sizeof (Though this is somewhat less useful in normal circumstances, since its size will be fixed anyway).

with array by-reference You also don't need to worry about the function being called with a null pointer or an array of an incorrect size, since the compiler enforces the kind of array you can pass (Pointers disallowed, and statically allocated arrays cannot be 'null').


Neither of these solutions are at all perfect by any means. If this were a real-world C++ situation, or anything bigger than an exercise to learn about arrays and/or pointers, the better solution would be to pick one of the tools in C++'s STL, such as a vector (a vector is essentially a 'C++ array' )


Passing an integer array as a function argument is equivalent to passing an integer pointer. Arrays are pointers and can be treated the same way.

For example, if you decided to use pointer arguments to pass the array:

void func(int *iArr, int arrSize)
{
	...
}



Within the function, elements of the array can either be accessed through regular array notation:

void func(int *iArr, int arrSize)
{
	for(int i = 0; i < arrSize; i++)
	{
		cout << iArr[i];
	}
}



or through pointer notation using a method like this:

void func(int *iArr, int arrSize)
{
	int i = 0;
	while(i < arrSize)
	{
		//dereferencing the pointer will result in the current array element value
		cout << *iArr;
		//this will increment the pointer to point to the next integer element in the array
		iArr += 1;
		i += 1;
	}
}


Was This Post Helpful? 0
  • +
  • -

#8 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 854
  • View blog
  • Posts: 2,338
  • Joined: 20-August 07

Re: Passing by reference with Arrays C++

Posted 29 November 2008 - 05:28 AM

- Cut out alot of quoting for brevity

View Postrobhilly, on 29 Nov, 2008 - 11:27 AM, said:

View PostBench, on 29 Nov, 2008 - 02:59 AM, said:

<snip>

Please bear in mind - this does not mean that an array is a pointer (and a pointer is not an array), pointers are merely used as a means to referring to an array from within a function - conveniently, pointers and arrays are allowed to use the same syntax, but don't let this confuse you.

<snip>

Arrays are pointers and can be treated the same way.

<snip>

I think that statement is a bit misleading. as I mentioned in my earlier post, arrays are not pointers and you shouldn't treat them the same way. Only array function parameters are pointers; This is a special case born out of the requirement that arrays should not be copied, under normal circumstances, they are completely different.

as an illustration of this point, consider a program with a statically allocated array, and a pointer to the first element of that array (in the same block, without any function passing involved). From a syntax perspective, the two look rather similar, but the compiler will tell a different story when you try to use one as the other

Working example which shows pointer arithmetic and array subscript notation being used interchangeably to the same effect
#include <iostream>
int main()
{
	int array[] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
	int* pointer;

	pointer = array;

	std::cout << array[4] << " " << pointer[4] << std::endl;
	std::cout << *(array+6) << " " << *(pointer+6) << std::endl;
} 
Part of the reason that this works is down to the fact that modification of an entire array cannot happen with a single operation. Therefore, the only valid operations on array identifiers can be those which allow access or modification to that array's individual elements.


In the next snippet, the compiler throws out an error when performing the same operation as above, on an array instead of a pointer. to read, it appears as if it should copy array1 into array2, however, the action of modifying an entire array object in one operation is forbidden in C and C++.
int main()
{
	int array1[5] = { 1 , 2 , 3 , 4 , 5 };
	int array2[5];

	array2 = array1;  // Error!
} 
Similarly, the compiler will disallow any attempts to initialise a pointer using an array initialiser
int* pointer = { 1 , 2 , 3 , 4 , 5 };


Here, the sizeof operator shows that arrays and pointers are different - sizeof forces the compiler to yield the size, in bytes, of an object. the difference in size for this array object and a pointer object should be striking.
#include <iostream>

int main()
{
	int array[5] = { 1 , 2 , 3 , 4 , 5 };
	int* pointer = array;

	std::cout << sizeof array << " " << sizeof pointer << std::endl;
} 



In short, whenever there's any reference made to the 'equivalence' between arrays and pointers, the only equivalence is that of the syntax. the reasoning behind this is rather subtle at times, however if you approach pointers and arrays with a mindset that both are distinctly different, then you'll run into a-lot less trouble than simply assuming that they're 'nearly the same'.

This post has been edited by Bench: 29 November 2008 - 05:41 AM

Was This Post Helpful? 0
  • +
  • -

#9 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Passing by reference with Arrays C++

Posted 29 November 2008 - 08:24 AM

However, couldn't we all agree that an array has a pointer to its initial index?
Was This Post Helpful? 0
  • +
  • -

#10 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 854
  • View blog
  • Posts: 2,338
  • Joined: 20-August 07

Re: Passing by reference with Arrays C++

Posted 29 November 2008 - 09:20 AM

View PostKYA, on 29 Nov, 2008 - 03:24 PM, said:

However, couldn't we all agree that an array has a pointer to its initial index?

Not really, that would imply that there is some additional 'hidden' pointer involved, which there isn't. arrays only occupy exactly enough memory to hold each of their elements.

Arrays know the start address of their first byte in exactly the same way that any other object or variable knows the start address of their first byte. (the details of which are down to the implementation of the compiler and the platform which you're running on)

The main difference between a regular variable and an array identifier is a semantic one - the default behaviour for a normal variable is direct access to the object which it names. However, since an array can be considered to be a sequence of multiple objects, direct access to all at once wouldn't make much sense, so instead the default behaviour of an array identifier is just to return the address of its first byte in memory (You could perhaps consider all array identifiers to have an implicit &'address-of' operator in front of them).

ultimately it was a language decision to let C (and subsequently C++) behave in this way - its a trade-off between consistency and convenience.
- One alternative could perhaps have been to disallow arrays from being addressed without an & in front of them (meaning that you'd need an & each time you wished to use subscript notation). but that might have been ugly, and certainly less convenient.
- Another alternative could have been to allow all variables to return their address by default (This is how many assembly languages behave), access to a variable would use a de-referencing operator - again this would have been ugly and inconvenient, but it would have been more consistent.

This post has been edited by Bench: 29 November 2008 - 09:23 AM

Was This Post Helpful? 0
  • +
  • -

#11 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Passing by reference with Arrays C++

Posted 29 November 2008 - 10:46 AM

Quote

(You could perhaps consider all array identifiers to have an implicit &'address-of' operator in front of them).


That's what i was getting at. i worded it poorly.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1