Pass array by reference and modify values C++ - c++

I want to write a function which takes inArray[3] = {1,2,3,4} and an outArray[3], and modifies outArray[3] within the function to now contain values = {3,4,1,2}.
int main{
int inArray[4] = {1,2,3,4};
int outArray[4];
myFunction(&inArray, &outArray);
}
void myFunction(&inArray, &outArray){
outArray[0] = inArray[2];
outArray[1] = inArray[3];
outArray[2] = inArray[0];
outArray[3] = inArray[1];
}
I'm doing something wrong here, and I don't precisely understand how to pass an array by reference and manipulate the values inside the function.

The fiunction and its call can look the following way
const size_t N = 4;
void myFunction( int ( &inArray )[N], int ( &outArray )[N] )
{
outArray[0] = inArray[2];
outArray[1] = inArray[3];
outArray[2] = inArray[0];
outArray[3] = inArray[1];
}
int main()
{
int inArray[N] = {1,2,3,4};
int outArray[N];
myFunction( inArray, outArray );
}
Take into acccount that your definition of an array
int inArray[3] = {1,2,3,4};
contains a typo and will not be compiled. There must be at least like
int inArray[4] = {1,2,3,4};
or
int inArray[] = {1,2,3,4};

You arrays have size 3, but you try to store 4 elements in them and access the fourth element at [3] (which has undefined behaviour).
Make them bigger, either hardcoding 4 or making everything automatically adjust to the current length of the list of numbers you use to initialise inArray:
int inArray[] = {1,2,3,4}; // automatically sized
int outArray[sizeof inArray / sizeof *inArray];
Then, your function signature should specify the array-of-int of the arguments. There are many ways to do that:
void myFunction(const int inArray[], int outArray[]) // 1
void myFunction(const int* inArray, int* outArray) // 2
void myFunction(const int (&inArray)[4], int (&outArray)[4]) // 3
template <size_t N>
void myFunction(const int (&inArray)[N], int (&outArray)[N]) // 4
The first is clearly the simplest.
The second is equivalent, as when a caller passes array arguments they're allowed to decay to pointers, and that happens even for 1) as the array dimension can only be captured or enforced when accepting arrays by reference, as in the following cases...
The third additionally ensures the array parameters have exactly 4 elements (so suddenly you can't (easily) pass say an array of 10 elements and have it copy over only the first 4).
The fourth accepts any sizes of array, but if used from different calling code on different sized arrays it may create multiple copies of the myFunction code, potentially using more memory for a larger program.
As you're function body hardcodes operations on elements [0] to [3], it won't adjust to do things on elements further into larger arrays, but you have the option of using the N value inside the function body to work out how many elements to operate on.

Array are always passed by reference no need to pass it by reference manually.

Related

Is it possible to typedef array of function pointer in c++? [duplicate]

Arrays of function pointers can be created like so:
typedef void(*FunctionPointer)();
FunctionPointer functionPointers[] = {/* Stuff here */};
What is the syntax for creating a function pointer array without using the typedef?
arr //arr
arr [] //is an array (so index it)
* arr [] //of pointers (so dereference them)
(* arr [])() //to functions taking nothing (so call them with ())
void (* arr [])() //returning void
so your answer is
void (* arr [])() = {};
But naturally, this is a bad practice, just use typedefs :)
Extra:
Wonder how to declare an array of 3 pointers to functions taking int and returning a pointer to an array of 4 pointers to functions taking double and returning char? (how cool is that, huh? :))
arr //arr
arr [3] //is an array of 3 (index it)
* arr [3] //pointers
(* arr [3])(int) //to functions taking int (call it) and
*(* arr [3])(int) //returning a pointer (dereference it)
(*(* arr [3])(int))[4] //to an array of 4
*(*(* arr [3])(int))[4] //pointers
(*(*(* arr [3])(int))[4])(double) //to functions taking double and
char (*(*(* arr [3])(int))[4])(double) //returning char
:))
Remember "delcaration mimics use". So to use said array you'd say
(*FunctionPointers[0])();
Correct? Therefore to declare it, you use the same:
void (*FunctionPointers[])() = { ... };
Use this:
void (*FunctionPointers[])() = { };
Works like everything else, you place [] after the name.
I've been building a game engine and have found that I needed dynamically allocated arrays of function pointers.
To address this simply, I've opted for encapsulating the function pointers inside a class.
Here's a simple example:
class Function{
private:
public:
int (*sampleFunction)(int);
};
static int returnInt(int val){
int ret = 20 * i;
return ret;
}
int main(void){
Function *functions; /* V put yours here V */
size_t functionCount = getFunctionCount();
functions = new Function[functionCount];
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction = &returnInt;
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction(i);
return 0;
}
Where can this be useful?
Say that you have a graphical application that you're building that creates buttons out of an undefined number of files in a directory.
Each button has a unique "hitbox" coordinate relative to it's position in an array, and you need to be able to uniquely handle a mouse click for each button.
The Functions class is meant to be placed inside another, more complex, class. Where the point of the function pointer is to make it easier to redefine the button click event when different algorithms are required for the same "form element".

Why does a two-dimensional array become a one-dimensional array after passing it to a function?(C++

I'm making a simple Snake game. When making a map, my definition of the map is as follows
int map[25][25] = { 0 };
for (int i = 0; i < 25; i++)//Set the boundary to - 2
{
map[0][i] = -2;
map[24][i] = -2;
}
for (int i = 1; i < 25; i++)//Set the boundary to - 2
{
map[i][0] = -2;
map[i][24] = -2;
}
Then I made a function to simulate the motion of the snake。(The first parameter is the class I created: snake,The second is its moving direction. The key is the third parameter, the map array I put in.)
void snake_move(Snake snake1, int direction, int map[][25])
Then I made a call to the function.(The third parameter is the two-dimensional array pointer I passed in)
snake_move(snake1, direction, map);
Then the following figure appears
I found that it was a two-dimensional array before the function call,which is as follows
Why does this happen and how to solve this problem? I look forward to your reply・v・
You cannot pass built-in arrays like this to functions. snake_move(), even though it appears to have an argument that looks like a 2D array, it actually takes a pointer to a 1D array. This:
void func(int map[][25]);
Is actually equivalent to:
void func(int (*map)[25]);
map is a pointer to an array of 25 int elements. When you call that function:
func(map);
The map array "decays" to a pointer that points to its first element.
This is an unfortunate consequence of C++'s compatibility with C.
To avoid issues like this, use std::array (for fixed-size, static allocation of elements), or std::vector (for dynamically allocated elements.)
To get a 2D array, you need to use an array of arrays or a vector of vectors. For an array, that means:
std::array<std::array<int, 25>, 25>
This means "an array containing 25 arrays of 25 int elements.
It's a good idea to make snake_move take a const reference to avoid an unnecessary copy of the whole array. So:
#include <array>
void snake_move(
Snake snake1, int direction,
const std::array<std::array<int, 25>, 25>& map);
// ...
std::array<std::array<int, 25>, 25> map{};
for (int i = 0; i < 25; i++) {
map[0][i] = -2;
map[24][i] = -2;
}
for (int i = 1; i < 25; i++) {
map[i][0] = -2;
map[i][24] = -2;
}
snake_move(snake1, direction, map);
If snake_move() needs to modify the passed array, then remove the const.
To reduce the need to write the type over and over again, you can use an alias (with the using keyword):
using MapType = std::array<std::array<int, 25>, 25>;
void snake_move(Snake snake1, int direction, const MapType& map);
// ...
MapType map{};
// ...
The {} in the map declaration will initialize all values to zero. You can also use:
MapType map = {};
which does the same.
You can actually keep the dimension without using std::array
void snake_move(Snake snake1, int direction, int (&map)[25][25]);
https://godbolt.org/z/EYz7hzjTj
Also note it's not a 1D array (i.e. map[0] is not -2), the debug window does recognize and shows it's a int[25]*, it probably just have some bug that fail to display it in the correct format.
Why does this happen
Because of type decay. In particular, in many contexts (including when appearing as a parameter to a function), an array decays to a pointer to its first element. For example:
The type int [6] decays to int*
The type int *[6] decays to int**.
The type double [10] decays to double*.
The type int [5][6] decays to int (*)[6].
Thus, in you example, the third parameter int map[][25] is actually a pointer to an array of size 25 with elements of type int, ie int (*)[25].
how to solve this problem?
You can use std::array, as shown below:
void snake_move(Snake snake1, int direction,
//----------------------------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv------->std::array used
std::array<std::array<int, 25>,25> map)
{
}
std::array<std::array<int, 25>,25> map; //sta::array used
If the function snake_move() doesn't change the passed std::array, and to avoid unnecessary copying, you can take the std::array as a reference to const:
void snake_move(Snake snake1, int direction,
const std::array<std::array<int, 25>,25>& map)
//----------------------------^^^^^-----------------------------------^----->lvalue reference to non-const std::array<std::array<int, 25>,25>
{
}

C++ determine size of array [duplicate]

I am trying to write a function that prints out the elements in an array. However when I work with the arrays that are passed, I don't know how to iterate over the array.
void
print_array(int* b)
{
int sizeof_b = sizeof(b) / sizeof(b[0]);
int i;
for (i = 0; i < sizeof_b; i++)
{
printf("%d", b[i]);
}
}
What is the best way to do iterate over the passed array?
You need to also pass the size of the array to the function.
When you pass in the array to your function, you are really passing in the address of the first element in that array. So the pointer is only pointing to the first element once inside your function.
Since memory in the array is continuous though, you can still use pointer arithmetic such as (b+1) to point to the second element or equivalently b[1]
void print_array(int* b, int num_elements)
{
for (int i = 0; i < num_elements; i++)
{
printf("%d", b[i]);
}
}
This trick only works with arrays not pointers:
sizeof(b) / sizeof(b[0])
... and arrays are not the same as pointers.
Why don't you use function templates for this (C++)?
template<class T, int N> void f(T (&r)[N]){
}
int main(){
int buf[10];
f(buf);
}
EDIT 2:
The qn now appears to have C tag and the C++ tag is removed.
For C, you have to pass the length (number of elements)of the array.
For C++, you can pass the length, BUT, if you have access to C++0x, BETTER is to use std::array. See here and here. It carries the length, and provides check for out-of-bound if you access elements using the at() member function.
In C99, you can require that an array an array has at least n elements thusly:
void print_array(int b[static n]);
6.7.5.3.7: A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. If the keyword static also appears within the [ and ] of the
array type derivation, then for each call to the function, the value of the corresponding
actual argument shall provide access to the first element of an array with at least as many
elements as specified by the size expression.
In GCC you can pass the size of an array implicitly like this:
void print_array(int n, int b[n]);
You could try this...
#include <cstdio>
void
print_array(int b[], size_t N)
{
for (int i = 0; i < N; ++i)
printf("%d ", b[i]);
printf("\n");
}
template <size_t N>
inline void
print_array(int (&b)[N])
{
// could have loop here, but inline forwarding to
// single function eliminates code bloat...
print_array(b, N);
}
int main()
{
int a[] = { 1, 2 };
int b[] = { };
int c[] = { 1, 2, 3, 4, 5 };
print_array(a);
// print_array(b);
print_array(c);
}
...interestingly b doesn't work...
array_size.cc: In function `int main()':
array_size.cc:19: error: no matching function for call to `print_array(int[0u])'
JoshD points out in comments below the issue re 0 sized arrays (a GCC extension), and the size inference above.
In c++ you can also use a some type of list class implemented as an array with a size method or as a struct with a size member(in c or c++).
Use variable to pass the size of array.
int sizeof_b = sizeof(b) / sizeof(b[0]); does nothing but getting the pre-declared array size, which is known, and you could have passed it as an argument; for instance, void print_array(int*b, int size). size could be the user-defined size too.
int sizeof_b = sizeof(b) / sizeof(b[0]); will cause redundant iteration when the number of elements is less than the pre-declared array-size.
The question has already some good answers, for example the second one. However there is a lack of explanation so I would like to extend the sample and explain it:
Using template and template parameters and in this case None-Type Template parameters makes it possible to get the size of a fixed array with any type.
Assume you have such a function template:
template<typename T, int S>
int getSizeOfArray(T (&arr)[S]) {
return S;
}
The template is clearly for any type(here T) and a fixed integer(S).
The function as you see takes a reference to an array of S objects of type T, as you know in C++ you cannot pass arrays to functions by value but by reference so the function has to take a reference.
Now if u use it like this:
int i_arr[] = { 3, 8, 90, -1 };
std::cout << "number f elements in Array: " << getSizeOfArray(i_arr) << std::endl;
The compiler will implicitly instantiate the template function and detect the arguments, so the S here is 4 which is returned and printed to output.

how can I have a function with a 2D array as an argument whereas the array has a parameter/dimension that I want to change?

(I'm a student and this is my first time posting so go easy on me.)
I want to create a function that takes a 2D array as an argument and in that array, I'd like to have a variable that I want to modify later in the code. This is the closest thing to an example of what I want:
int size; //the variable I want to change later
void function(int[][size]);
int main(){
cin >> size;
int array[size][size]; //the array I'm using with the variable as a parameter
function(array)
}
void function(int array[][size]){
//Do thing....
}
The code above does give me an error (array bound is not an integer constant) so if I make the variable a constant it will compile as seen here:
const int size = 10;
void function(int[][size]);
int main(){
int array[size][size];
function(array)
}
void function(int array[][size]){
//Do thing....
}
This does compile like I said, but now I can't modify the variable and need to declare its value in the code beforehand. I assume that the variable needs to be global so that I can use it in the function, and with that said, I can't get pointers to work either most likely because it's a global variable and not a local one. Here's an example of something I tried, but got an error (invalid conversion from ‘const int*’ to ‘int*’):
const int size = 10;
void function(int[][size]);
int main(){
int *other = &size;
*other = 5;
}
Any help would be appreciated, thanks.
Plain ol' arrays aren't resizeable in C++. Even more frustrating, their size has to be a constant - you can't make the size a variable that gets set at runtime. Ever more frustrating, the size you put in an array that's a function parameter is a constraint, and it's not even enforced. It's just decor.
As it was hinted in the comments, std::vector<TYPE> is the go-to "resizeable array" in C++. You can create a vector like this:
#include <vector>
int main() {
std::vector<int> my_int_array;
}
And you can resize it like this:
int new_size = 42;
my_int_array.resize(new_size);
And you can pass it to a function by reference(see the &) so that changes to myint_array inside the function affect it outside the function.
void my_awesome_function(std::vector<int>& int_array);
my_awesome_function(my_int_array);
So let's say you have a 2D matrix, implemented as a vector of vectors:
std::vector<std::vector<int>> matrix = { { 1,2,3 }, { 4,5,6 } }
If you want to change the number of columns, you have to resize each row array:
int new_column_count = 10;
for (auto& row : matrix) {
row.resize(new_column_count );
}
You can pass around matrix by reference (e.g. std::vector<std::vector<int>>&) and resize it when you need to.

What's the syntax for declaring an array of function pointers without using a separate typedef?

Arrays of function pointers can be created like so:
typedef void(*FunctionPointer)();
FunctionPointer functionPointers[] = {/* Stuff here */};
What is the syntax for creating a function pointer array without using the typedef?
arr //arr
arr [] //is an array (so index it)
* arr [] //of pointers (so dereference them)
(* arr [])() //to functions taking nothing (so call them with ())
void (* arr [])() //returning void
so your answer is
void (* arr [])() = {};
But naturally, this is a bad practice, just use typedefs :)
Extra:
Wonder how to declare an array of 3 pointers to functions taking int and returning a pointer to an array of 4 pointers to functions taking double and returning char? (how cool is that, huh? :))
arr //arr
arr [3] //is an array of 3 (index it)
* arr [3] //pointers
(* arr [3])(int) //to functions taking int (call it) and
*(* arr [3])(int) //returning a pointer (dereference it)
(*(* arr [3])(int))[4] //to an array of 4
*(*(* arr [3])(int))[4] //pointers
(*(*(* arr [3])(int))[4])(double) //to functions taking double and
char (*(*(* arr [3])(int))[4])(double) //returning char
:))
Remember "delcaration mimics use". So to use said array you'd say
(*FunctionPointers[0])();
Correct? Therefore to declare it, you use the same:
void (*FunctionPointers[])() = { ... };
Use this:
void (*FunctionPointers[])() = { };
Works like everything else, you place [] after the name.
I've been building a game engine and have found that I needed dynamically allocated arrays of function pointers.
To address this simply, I've opted for encapsulating the function pointers inside a class.
Here's a simple example:
class Function{
private:
public:
int (*sampleFunction)(int);
};
static int returnInt(int val){
int ret = 20 * i;
return ret;
}
int main(void){
Function *functions; /* V put yours here V */
size_t functionCount = getFunctionCount();
functions = new Function[functionCount];
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction = &returnInt;
for(int i=0; i<functionCount; i++)
functions[i].sampleFunction(i);
return 0;
}
Where can this be useful?
Say that you have a graphical application that you're building that creates buttons out of an undefined number of files in a directory.
Each button has a unique "hitbox" coordinate relative to it's position in an array, and you need to be able to uniquely handle a mouse click for each button.
The Functions class is meant to be placed inside another, more complex, class. Where the point of the function pointer is to make it easier to redefine the button click event when different algorithms are required for the same "form element".