Passing an Array by reference in C
This is caused by the fact that arrays tend to decay into pointers.
int a[] = { 1, 2, 3 };
int* p = a; // valid: p is now the address of a[0]
a = p; // NOT valid.
printf("a = %p\n", a);
printf("p = %p\n", p); // prints same address as a
a
and p
will print the same value.
Contrary to what others have said, a
is not a pointer, it can simply decay to one. http://c-faq.com/aryptr/aryptrequiv.html
In your first function()
what gets passed is the address of the array's first element, and the function body dereferences that. Infact, the compiler is treating the function prototype as this:
void function(int* array /*you wrote int array[]*/){
array[0] = 4;
array[1] = 5;
array[2] = 6;
}
function(&array[0]);
This has to happen because you said "array of unknown size" (int array[]). The compiler could not guarantee to deduce the amount of stack required to pass by value, so it decays to a pointer.
---- Edit ----
Lets combine both your examples and use more distinctive names to make things clearer.
#include <stdio.h>
void func1(int dynArray[]) {
printf("func1: dynArray = %p, &dynArray[0] = %p, dynArray[0] = %d\n",
dynArray, &dynArray[0], dynArray[0]);
}
void func2(int* intPtr) {
printf("func2: intPtr = %p, &intPtr[0] = %p, intPtr[0] = %d\n",
intPtr, &intPtr[0], intPtr[0]);
}
void func3(int intVal) {
printf("func3: intVal = %d, &intValue = %p\n",
intVal, &intVal);
}
int main() {
int mainArray[3] = { 1, 2, 3 };
int mainInt = 10;
printf("mainArray = %p, &mainArray[0] = %p, mainArray[0] = %d\n",
mainArray, &mainArray, mainArray[0]);
func1(mainArray);
func2(mainArray);
printf("mainInt = %d, &mainInt = %p\n",
mainInt, &mainInt);
func3(mainInt);
return 0;
}
Live demo at ideone: http://ideone.com/P8C1f4
mainArray = 0xbf806ad4, &mainArray[0] = 0xbf806ad4, mainArray[0] = 1
func1: dynArray = 0xbf806ad4, &dynArray[0] = 0xbf806ad4, dynArray[0] = 1
func2: intPtr = 0xbf806ad4, &intPtr[0] = 0xbf806ad4, intPtr[0] = 1
mainInt = 10, &mainInt = 0xbf806acc
func3: intVal = 10, &intValue = 0xbf806ad0
In func1
and func2
"dynArray" and "intPtr" are local variables, but they are pointer variables into which they receive the address of "mainArray" from main.
This behavior is specific to arrays. If you were to put the array inside a struct, then you would be able to pass it by value.
C++ pass an array by reference
Arrays can only be passed by reference, actually:
void foo(double (&bar)[10])
{
}
This prevents you from doing things like:
double arr[20];
foo(arr); // won't compile
To be able to pass an arbitrary size array to foo
, make it a template and capture the size of the array at compile time:
template<typename T, size_t N>
void foo(T (&bar)[N])
{
// use N here
}
You should seriously consider using std::vector
, or if you have a compiler that supports c++11, std::array
.
pass array by reference in golang
As others have mentioned in comments, you probably want to use a slice rather than an array. Slices are passed by reference already, so no need to specify pointers. The make
statement below creates a slice of ints (backed by an array). In the code below, I gave it a length of 2 and a capacity of 100 in order to satisfy your goal of assigning to index 1.
import (
"fmt"
)
func f(a []int) {
fmt.Println(a[1])
}
func main() {
a := make([]int, 2, 100)
a[1] = 100
f(a)
}
C++ Pass a reference to an array to function
There are many different options here depending on what you want to do here.
If you have a raw array of byte
objects, you can pass it into a function like this:
void hello(byte arr[]) {
// Do something with arr
}
int main() {
byte arr[4];
hello(arr);
}
The mechanism by which the array is passed into the function (a pointer to the first element of the array is passed to the function) functions similarly to pass-by-reference: any changes you make to arr
in hello
will stick in main
even though you didn't explicitly pass in a reference to it. However, the hello
function won't check whether the array has size four or not - it'll take in as input an array of any number of bytes.
You can also write
void hello(byte (&arr)[4]) {
// ...
}
int main() {
byte arr[4];
hello(arr);
}
The syntax byte (&arr)[4]
means "a reference to an array of four bytes." This explicitly passes the array by reference into hello
, and it will check the size of the array to make sure it's correct. However, this is very unusual syntax and rarely seen in practice.
But perhaps the best idea is to not use raw arrays and to use std::array
instead:
void hello(std::array<byte, 4>& arr) {
// Do something with arr
}
int main() {
std::array<byte, 4> arr;
hello(arr);
}
Now, there's no weirdnesses about strange parentheses in the syntax for arrays of bytes and there's no worries about size checking. Everything is handled properly because std::array
is an object type that has all the advantages of regular object types. I'd recommend going with this last approach above all the other ones.
Passing an array by reference in C?
In C arrays are passed as a pointer to the first element. They are the only element that is not really passed by value (the pointer is passed by value, but the array is not copied). That allows the called function to modify the contents.
void reset( int *array, int size) {
memset(array,0,size * sizeof(*array));
}
int main()
{
int array[10];
reset( array, 10 ); // sets all elements to 0
}
Now, if what you want is changing the array itself (number of elements...) you cannot do it with stack or global arrays, only with dynamically allocated memory in the heap. In that case, if you want to change the pointer you must pass a pointer to it:
void resize( int **p, int size ) {
free( *p );
*p = malloc( size * sizeof(int) );
}
int main() {
int *p = malloc( 10 * sizeof(int) );
resize( &p, 20 );
}
In the question edit you ask specifically about passing an array of structs. You have two solutions there: declare a typedef, or make explicit that you are passing an struct:
struct Coordinate {
int x;
int y;
};
void f( struct Coordinate coordinates[], int size );
typedef struct Coordinate Coordinate; // generate a type alias 'Coordinate' that is equivalent to struct Coordinate
void g( Coordinate coordinates[], int size ); // uses typedef'ed Coordinate
You can typedef the type as you declare it (and it is a common idiom in C):
typedef struct Coordinate {
int x;
int y;
} Coordinate;
Pass Array by Reference in C
Arrays are always passed by reference in C. The name of the array is pointer to the first element of it. So, you just do this :-
void function (int arr[]){
// Some Code.....
}
int main(){
// Some Code...
int name[5];
function(name);
// Some Code...
}
And that would work, you can modify the values of elements in the array and the changes would be reflected in the calling function.
Edit: You know that you have to add a semi-colon after your for loop? Otherwise the next one line will also be iterated. See -
Corrected Code
and
Output
Passing an array by reference isn't working
As has been mentioned, javascript uses pass-by-value, you can modify the objects elements/properties but not replace the object itself. slice
returns a new array to the object. You will have to something like this instead.
slice does not alter the original array, but returns a new "one level
deep" copy that contains copies of the elements sliced from the
original array.
function callMeMaybe(i, board, boardCopy) {
if (board[i] == 1) {
//boardCopy = board.slice(0);
var length = board.length,
j = 0;
boardCopy.length = 0;
while (j < length) {
if (Object.prototype.hasOwnProperty.call(board, j)) {
boardCopy[j] = board[j];
}
j += 1;
}
boardCopy[i] = 0;
console.log(board);
console.log(boardCopy);
}
}
Related Topics
Sfinae Working in Return Type But Not as Template Parameter
Why Does Cout Print Char Arrays Differently from Other Arrays
Uninitialized Variable Behaviour in C++
Capturing Function Exit Time With _Gnu_Mcount_Nc
When I Change a Parameter Inside a Function, Does It Change For the Caller, Too
What Happens When I Print an Uninitialized Variable in C++
Difference Between Static and Shared Libraries
How to Implement the Factory Method Pattern in C++ Correctly
Range Based Loop: Get Item by Value or Reference to Const
Officially, What Is Typename For
What Happens to a Detached Thread When Main() Exits
Why Should the Copy Constructor Accept Its Parameter by Reference in C++
C++ Deprecated Conversion from String Constant to 'Char*'
Reading and Writing Binary File
Which Iomanip Manipulators Are 'Sticky'
How to Emulate C Array Initialization "Int Arr[] = { E1, E2, E3, ... }" Behaviour With Std::Array