I have a question regarding passing address of first element of an array to a (recursive) function:
selectionSort( &b[1], size-1);
When address is passed to a function, function parameter must be a pointer as I know. selectionSort method gets int b[] as argument. Not a pointer.
But code works without any problems. Also this code generates subarrays. When we pass the 1st element does it become the subarray's zeroeth element?
void selectionSort(int b[], int size)
{
int temp,i;
if (size>=1)
{
for (i = 0; i < size; i++)
{
if (b[i]<b[0])
{
temp=b[0];
b[0]=b[i];
b[i]=temp;
}
}
selectionSort( &b[1], size-1 );
}
}
Whenever you have a function like:
void f(int b[]);
this is the same as
void f(int *b);
The [] syntax for function parameters is just a special syntax to let the reader know that you intend to use the parameter like an array, but it is actually just a pointer. You can't pass an actual array to a function. Pointers and arrays work very similarly in C, so for the most part you can work with a pointer as if it were an array (but be careful -- there are important exceptions).
For example, when you access an element of an array like this:
array[index]
this is the same as
*(array+index)
and it doesn't matter whether array is a real array or just a pointer.
So &b[1] is the same as &*(b+1), which is the same as b+1.
If we were to write the code so that we see the b parameter as a pointer, it would look like this:
void selectionSort(int *b, int size){
.
.
.
selectionSort( b+1, size-1 );
.
.
.
}
Now, you can see that selectionSort is being passed a pointer to an int, and it calls itself with a pointer to the next int.
Yes, the code will create 'sub arrays' you should use:
A pointer to an array of integers
selectionSort(int (*b)[], int size)
And call the function using:
selectionSort( &b[1], size-1 );
Related
I have a function that simply takes 2d char array write on first element [0][0] to n and m element and in main I like to print what has been written. I only need to pass the address of entire two dimensional array and use it in calling function.
This is what I tried so far with multiple variations of tries but nothing seems to work
folloing code cause segFault
I got segFault at array[0][0]='c'; in the called function. please note I need to pass only the address of 2d array so I can easily move around and populate the array in called function.
void bps(char **array,int m, int n)
{
array[0][0]='c';
}
I also tried like this *array[0]='c'; but no luck so far
I am passing array like bps(array,x,y); in main
this is the code in main
int main()
{
int x=3,y=3;
char array[3][3]={"ab","ax"};
// Or should I use like this
// char array[3][3]=(char [3][3]){"ab","ax"};
bps(array,x,y);
printf("%c",array[0][0]);
return 0;
}
or should I use like this in bps(..)
void bps(char *array,int m, int n )
{
*(*(array))='c';
}
please clarify
char** may be used for 1D arrays of pointers, such as pointing in the first item in an array of strings. But it cannot be used to point at a 2D array. Forget that you ever heard of type** in relation to 2D arrays.
Change void bps(char **array,int m, int n) to:
void bps (int m, int n, char array[m][n])
Access individual items with array[i][j], not with obscure and unreadable pointer arithmetic like *(*(array))='c';.
Detailed explanation:
The reason why char array[m][n] works is that arrays, whenever used as a function parameter, get implicitly adjusted ("decays") to a pointer to their first element by the compiler.
Given an array char array[m][n], it is an array of arrays. The first item is therefore an array of type char[n]. A pointer to that first item type is written as char (*)[n]. Therefore
void bps (int m, int n, char array[m][n])
is 100% equivalent to
void bps (int m, int n, char (*array)[n])
And in either case the array is passed "by reference", not by value as one might incorrectly suspect.
Is there any difference between two function in C?
void f1(int arr[]) {
//some code...
}
void f2(int arr[10]) {
//some code
}
What will be the size of first array in f1 function?
Is there any difference between two function in c?
No difference here. Both will be interpreted as int *arr by the compiler as arrays are converted to a pointer to its first element when used as a function parameter.
what will be the size of first array in f1 function?
Strictly speaking, there is no array here. Its only pointer to an int. If you will use sizeof(arr), then you will get the value equal to sizeof(int *).
The array size in parameters are needed when the type of parameter is a pointer to an array. in this case you need to have specify the size of array as each size makes the pointer to point to different type.
void f3(int (*arr)[10]); // Expects a pointer to an array of 10 int
When an array is passed to a function, it decays into a pointer to the first element of the array.
So this:
void f1(int arr[])
And this:
void f1(int arr[10])
And this:
void f1(int *arr)
Are all equivalent.
In fact if you passed int a[20] to a function declared to take int arr[10], gcc won't complain.
I tried something like :
typedef struct vec{
int sz;
int v[];
} ff;
int sum(struct vec z){
int o=0,i;
for(i=0;i<z.sz;i++)
o+=z.v[i];
return o;
}
int main(){
int test[]={10,1,2,3,4,5,6,7,8,9,10};
return sum((struct vec)test);
}
But this example code can't compile. How to send array by value (not ref throw pointer) to function?
You can't send an array by value in C. Every time you try to pass an array to a function, you'll pass the pointer to the first value.
To pass an array by value, you can cheat a little and encapsulate it in a struct, and send it by value (so it will be copied)... It's a dirty hack, as explained here, but well, if you really want that, it works.
Another way is to copy the array inside the function, with the pointer given.
In your example, you will need to specify the exact size of the array in the definition of struct vec, for example int v[10]. Also your initialization can be written better. Try this:
#define MAX_SIZE 50
struct vec {
int sz;
int v[MAX_SIZE];
};
int sum(struct vec z){
int i, o;
o = 0;
for(i=0; i<z.sz; i++) o += z.v[i];
return o;
}
int main(){
struct vec test = {10, {1,2,3,4,5,6,7,8,9,10}};
return sum(test);
}
While it's true that an array in C has a size, that size can only be accessed through the sizeof operator, and then only on the original array. You can't cast an array to a structure in the hopes that the compiler will fill in all fields.
In fact, it's actually impossible to pass an array to a function "by value". All arrays decays to pointers, so when you pass an array to a function that function receives a pointer. This decay to pointers is also why you can only use the sizeof operator on the original array, once it decays to a pointer the compiler have no idea that it's actually pointing to an array, so using the sizeof operator (even on something that points to an array) will return the size of the pointer and not what it points to.
In your case, it would be simpler to change your function to take two arguments, the pointer to the array and the number of entries in the array:
/* `array` is an array containing `elements` number of `int` elements. */
int sum(const int *array, const size_t elements)
{
...
}
int main(void)
{
...
printf("Sum = %d\n", sum(test, sizeof(test) / sizeof(test[0]));
}
Arrays are always passed by reference in C, you can't change that.
What you can do is make a copy of array and pass the new array in the function
As the others noted, the only way in C to pass an array by value is to use a struct with a fixed size array. But this is not a good idea, because the array size will be hardcoded into the struct definition.
However, you really should not try to pass arrays by value. Instead, what you should do is simply to declare your pointer parameter as const, like this:
int sum(size_t count, const int* array) {
While this does not pass the array by value, it clarifies the intent not to change the array, i. e. you can now treat sum() as if you were passing the array by value.
If your function does indeed not change the array (like your sum() function), using a const pointer comes for free, copying the array to pass it by value would just waste time.
If your function really wants to change a private copy, do so explicitely within the function. If the array won't get too large, you can simply allocate it on the stack, like so:
int doSomethingWithPrivateCopy(size_t count, const int* array) {
int mutableCopy[count];
memcpy(mutableCopy, array, sizeof(mutableCopy));
//Now do anything you like with the data in mutable copy.
}
Can I do this in C:
void myFunc(int *vp) {
// do some stuff with vp
}
int main() {
int v[5] = {1,2,3,4,5};
myFunc(v);
return 0;
}
I mean, what would be the correct? myFunc(&v); ?
Thanks!!
Arrays decay to pointers when you pass them as arguments. However, array decay is not the same as taking the address of an array.
"Decay" is how some types are transformed when passed as function arguments. Even though v's type is int [5], it becomes int* when you pass it to a function. This is a behavior a lot of people don't like, but there's nothing to do about it.
Note that, on the other hand, the type of &v is int (*)[5], that is, a pointer to an array of 5 integers. This type doesn't decay, that is, it doesn't transform automatically into another type if you pass it as a function parameter (and that's also why it wouldn't work if you used it in your example, since you need a pointer to integers, not a pointer to an array of integers).
The "correct" thing to do (assuming decay is OK) is to do myFunc(v), just as you're doing in your snippet. Keep in mind that you lose array bounds information when you do it.
Yes ... Your code is correct.
Here v==&v[0] array name is equal to address of first element of array
myFunc(v);
passing array name as argument that means you are passing address of first element in array.
void myFunc(int *vp)
Here you are using pointer. which store the address of first element of array which is passed so you can access the block which is covered with the array.by incrementing the pointer location.
And
myFunc(&v);
&v==&&v[0];
&v is address of address of array first element.
Now
void myFunc(int *vp)
Here You got address of address of array first element, This is not pointing to array. Instead pointing some memory location.Now You can't access the array by incrementing the pointer.
Your code is correct It will work....
But you should take extra care to check the boundary condition.
Please look through the code.
void myFunc(int *vp) {
vp[5] = 30;
}
int main() {
int v[5] = {1,2,3,4,5};
int a = 10;
printf("Value of a before fun call %d\n", a);
myFunc(v);
printf("Value of a before fun call %d\n", a);
return 0;
}
similarly
void myFunc(int *vp) {
vp[5] = 30;
myFunc2(vp);
}
void myFunc2(int *vp) {
vp[6] = 30;
}
int main() {
int v[5] = {1,2,3,4,5};
int a = 10;
printf("Value of a before fun call %d\n", a);
myFunc(v);
printf("Value of a before fun call %d\n", a);
return 0;
}
This will result in segmentation fault due to stack curruption. Since local variables are in stack.
I had to write a program which has a function that sums all positive number in an array, but using function parameter array as an pointer. There in main function a problem occurs, when i try to call sum function. here is my source code:
#include <stdio.h>
#include <conio.h>
int posit(int *x[], int n){
int s=0;
for(int i=0; i<n; i++){
if(*x[i]>0){
s=s+*x[i];
}
}
return s;
}
int main(){
int k;
scanf("%d",&k);
int a[k];
for(int i=0; i<k; i++){
scanf("%d",&a[i]);
}
int b=posit(&a,k);
printf("%d\n", b);
getch();
return 0;
}
When an array is passed to a function it decays to a pointer to its first element. Change the signature of the function to:
int posit(int* x, int n){ /* Equivalent to 'int posit(int x[], int n)' */
and change the element access syntax of the array in the function from *x[i] to just x[i]. The invoke the function:
int b=posit(a,k);
Another point worth mentioning is to check the return value of scanf(), which returns the number of assignments made, to ensure &a[i] is actually being assigned and the program is subsequently not using uninitialized variables.
You may find the Arrays and Pointers section of the C FAQ useful.
Actually in your example you are passing to function pointer to pointer (please note that similar notation is very often used with main argument char *argv[]).
As mentioned in hmjd post while passing array to function this is converted to address of its first element. Instead of explicitly using pointer (int *x) you can also use array notation (int[] or even int[k]) but those are the same.
Please also note that in second method (int[k]) size provided doesn't matter and inside function it will be not known. This is only important to include size when you are dealing with multiple dimension arrays, but this is other story...
From K&R2
When an array name is passed to a function, what is passed is the
location of the initial element. Within the called function, this
argument is a local variable, and so an array name parameter is a
pointer, that is, a variable containing an address.
So you will be passing only the first element to the function.
Once this is understood your source can be modified as follows
int posit(int *x, int n)
and to call this function from main you can use
int b=posit(a,k); //Note only the location of the first element is being passed