When a function has a specific-size array parameter, why is it replaced with a pointer?
Yes it's inherited from C. The function:
void foo ( char a[100] );
Will have the parameter adjusted to be a pointer, and so becomes:
void foo ( char * a );
If you want that the array type is preserved, you should pass in a reference to the array:
void foo ( char (&a)[100] );
C++ '03 8.3.5/3:
...The type of a function is determined using the following rules. The type of each parameter is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type "array of T" or "function returning T" is adjusted to be "pointer to T" or "pointer to function returning T," respectively....
To explain the syntax:
Check for "right-left" rule in google; I found one description of it here.
It would be applied to this example approximately as follows:
void foo (char (&a)[100]);
Start at identifier 'a'
'a' is a
Move right - we find a )
so we reverse direction looking for the (
. As we move left we pass &
'a' is a reference
After the &
we reach the opening (
so we reverse again and look right. We now see [100]
'a' is a reference to an array of 100
And we reverse direction again until we reach char
:
'a' is a reference to an array of 100 chars
What is array to pointer decay?
It's said that arrays "decay" into pointers. A C++ array declared as int numbers [5]
cannot be re-pointed, i.e. you can't say numbers = 0x5a5aff23
. More importantly the term decay signifies loss of type and dimension; numbers
decay into int*
by losing the dimension information (count 5) and the type is not int [5]
any more. Look here for cases where the decay doesn't happen.
If you're passing an array by value, what you're really doing is copying a pointer - a pointer to the array's first element is copied to the parameter (whose type should also be a pointer the array element's type). This works due to array's decaying nature; once decayed, sizeof
no longer gives the complete array's size, because it essentially becomes a pointer. This is why it's preferred (among other reasons) to pass by reference or pointer.
Three ways to pass in an array1:
void by_value(const T* array) // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])
The last two will give proper sizeof
info, while the first one won't since the array argument has decayed to be assigned to the parameter.
1 The constant U should be known at compile-time.
Why does this code outputs two different results? [duplicate]
This is because ‘sizeof’ on array function parameter ‘arr’ will return size of ‘int*’..
c++ gets different array length when passing the array as a arguments to a fucntion [duplicate]
when passing the array as an argument to a function the array length becomes incorrect?
Despite appearances, the function parameter is a pointer (to the first array element), not an array. You get the ratio of the size of a pointer to the size of int
, which happens to be 2 on your platform.
There's no way to determine the size of an array given just a pointer.
How should I get the length of an array who is an argument of a function?
Arrays can't be passed by value to a function, and only arrays of known size can be passed by reference. So you'll need a template to infer the size of any array from the function argument:
template <typename T, size_t N>
size_t get_length(T (&)[N]) {return N;}
In C++14 or later, this function is available in the standard library, and is called std::size
. It's overloaded to work for both arrays and STL-style containers with a size
member function.
Alternatively, you might consider using std::array
(or std::vector
when you need a dynamic/resizable array), rather than a quirky built-in array.
How can we get the size of an array that is passed into the function? [duplicate]
Of course you can always use a template:
#include <iostream>
using namespace std;
template<typename T, std::size_t N>
void findFrequency (T(&input1)[N], int input2)
{
// input1 is the array
// N is the size of it
//int n = sizeof(input1) / sizeof(input1[0]);
int count = 0;
for(int i = 0; i < N; i++)
{
if(input1[i] == input2)
count++;
}
string ch;
if(count == 0)
ch = to_string(input2) + " not present";
else
ch = to_string(input2) + " comes " + to_string(count) + " times";
std::cout << ch << "\nn = " << N;
}
int main ()
{
int a[] = {1, 1, 3, 4, 5, 6};
findFrequency(a, 1);
}
Related Topics
Output Unicode Strings in Windows Console App
"Unpacking" a Tuple to Call a Matching Function Pointer
How to Determine Cpu and Memory Consumption from Inside a Process
Pointer to Class Data Member "::*"
Erasing Elements from a Vector
Why Can't C++ Be Parsed With a Lr(1) Parser
Conditions For Automatic Generation of Default/Copy/Move Ctor and Copy/Move Assignment Operator
Generating Random Integer from a Range
Why Doesn't Polymorphism Work Without Pointers/References
Fast Bignum Square Computation
How to Figure Out the Parameter Type and Return Type of a Lambda
Why Do I Need Strand Per Connection When Using Boost::Asio
Pass by Reference/Value in C++
What Happens If I Define a 0-Size Array in C/C++
Why Are C Character Literals Ints Instead of Chars
What Are the Advantages of List Initialization (Using Curly Braces)
Why Would We Call Cin.Clear() and Cin.Ignore() After Reading Input