Calling function in C with array and values are changed? - c

the code below changes the values of arr in function check and prints out values of "2", even though I didn't pass the array in check function in a pointer. How is that possible?
#include <stdio.h>
#include <stdlib.h>
void check(int n,int array[]);
int main()
{
int arr[]={1,2,3,4};
int i;
check(4,arr);
for(i=0;i<4;i++){
printf("%d\n",arr[i]);
}
return 0;
}
void check(int n,int array[])
{
int j=0;
while(j<n){
array[j]=2;
j++;
}
}

Keep in mind that
void check(int n,int array[]);
is the same as
void check(int n,int *array);
and so, when you use
check(4,arr);
you are actually doing
check(4,&arr[0]); /* This is called array "decay" */
and because array decays to a pointer which points to the address of its first element. So, it means that the "array" is passed by reference.

In C, arrays are converted ("decaying") automatically to pointers when sent to functions.

Related

Getting issues for redefinition of functions

I'm trying to scan numbers into 2 2D arrays, and I keep on getting the error of redefinition.
The code:
#include <stdio.h>
#define N 3
void getMatrix(double mat[N][N]);
/*
char getMenuOption();
void getCoordinates(int*, int*);
void sumMatrices(double mat1[][N], double mat2[][N]);
void changeMatrix(double mat[][N]);
void printMatrix(double mat[][N]);
*/
int main() {
double A[N][N], B[N][N];
/*
char option;*/
getMatrix( A[N][N]);
getMatrix( B[N][N]);
/*
option = getMenuOption();*/
return 0;
}
void getMatrix(double A[N][N]){
int i;
for(i=0;i<=N;i++){
for(i=0;i<N;i++)
{
scanf("%lf",&A[N][N]);
}
}
return;
}
void getMatrix(double B[N][N]){
int i;
for(i=0;i<=N;i++){
for(i=0;i<N;i++)
{
scanf("%lf",&B[N][N]);
}
}
return;
}
I guess the problem is that the same function is called twice, but im not so sure about it.
If anyone can help me point to the problem, it will be most welcome.
You don't need to define a function twice (to call it twice or more). One function can be called multiple times, that's the reason of having functions in first place. Get rid of
void getMatrix(double B[N][N]){
int i;
for(i=0;i<=N;i++){
for(i=0;i<N;i++)
{
scanf("%lf",&B[N][N]);
}
}
return;
}
Having said that, you should call the function like
getMatrix(A);
getMatrix(B);
To pass the array (the decay to pointer, anyway). The notation A[N][N] denotes a member of the array and for an array defined like
double A[N][N];
it's off-by-one, as array indexing in C starts from 0.
The function is defined twice
First definition
void getMatrix(double A[N][N]){
int i;
for(i=0;i<=N;i++){
for(i=0;i<N;i++)
{
scanf("%lf",&A[N][N]);
}
}
return;
}
Second definition
void getMatrix(double B[N][N]){
int i;
for(i=0;i<=N;i++){
for(i=0;i<N;i++)
{
scanf("%lf",&B[N][N]);
}
}
return;
}
Take into account that these calls of the function are invalid
getMatrix( A[N][N]);
getMatrix( B[N][N]);
The arguments have type double instead of arrays or pointers.
You should remove one definition of the function and declare the function correctly.
If the compiler allows to use Variable Length Arrays then the functiuon should be declared like
void getMatrix(size_t n, double A[n][n]);
if Variable Length Arrays are not supported by the compiler then N must be a constant and the function indeed can be declared like
#define N SOME_VALUE
//...
void getMatrix( double A[N][N] );
and call the function like
in the first case
getMatrix( N, A );
getMatrix( N, B );
and in the second case
getMatrix( A );
getMatrix( B );

Passing multidimensional arrays as arguments in functions in C

I am currently doing the fifteen exercise in CS50's Problem set 3. However, I am stuck in figuring out the syntax to pass a multi-dimensional array as an argument to a function. For instance, the following code (which prints out some numbers in an array) compiles and works:
#include <stdio.h>
void func(int array[], int size);
int main()
{
int size = 3;
int array[3] = {1,2,3};
func(array,size);
printf("Done\n");
}
void func(int array[], int size)
{
printf("%i %i %i\n", array[0],array[1], array[2]);
}
But this doesn't:
#include <stdio.h>
void func(int array[][], int size);
int main()
{
int size = 3;
int array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
func(array,size);
printf("Done");
}
void func(int array[][], int size)
{
printf("%i %i %i\n", array[0][0],array[1][1], array[2][2]);
}
This is the error provided by clang:
test.c:3:20: error: array has incomplete element type 'int []'
void func(int array[][], int size);
^
test.c:13:20: error: array has incomplete element type 'int []'
void func(int array[][], int size)
Can anyone explain to me what's wrong with my syntax? I don't quite understand the error messages given to me by clang.
The function func() expects a pointer to int but you are passing a pointer to an array. Hence, the errrors.
It's because an array gets converted into a pointer to its first element when you pass it to a function.
You can change the function prototype and definition to receive a pointer to an array:
void func(int (*array)[3], int size);
int main()
{
int size = 3;
int array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
func(array,size);
printf("Done");
}
void func(int (*array)[3], int size) {
...
}
Note that your array is initialized with size 3x3. So the array size has to 3x3 at least.
C99 allows to you pass dimensions. So you can write it like this too:
void func(int x, int y, int a[x][y]);
int main()
{
int size = 3;
int array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
func(3, 3, array);
printf("Done");
}
void func(int x, int y, int array[x][y])
{
printf("%i %i %i\n", array[0][0],array[1][1], array[2][2]);
}
An array is not a type in C! Internally, it is always handled as a pointer, hence, a pointer to the array is passed as argument and not the array itself.
If you intend to pass arrays as arguments (and not just pointers), you should rethink your design!
If you still need to do this wrap the array into a structure and pass the structure.
struct astruct
{
int size;
int array[3];
};
A declaration like int a[][] isn't sensible, since the compiler must know the size of all dimensions (except of the outermost) to calculate the memory address on access.
I.e. if an array is declared as
int array[][a][b];
The memory address for access to
array[2][1][3];
is calculated by
base_address + (2*a*b + 1*b + 3) * sizeof int
Without knowing a and/or b, this calculation would not be possible.
Simply tell the function to expect a multi-dimensional array:
void func (int array[3][3], int size);
Or if you want the function to be completely flexible:
void func (int x, int y, int array[x][y]);
You need to specify size of array when declaring prototype as well as while defining function . Right now it is of incomplete type .
Try this instead -
void func(int array[][3], int size)

passing 2d array to function with in c

Is there any way to pass 2D array to a function as function(arr,m,n)
and the function defenition as void function(int **p,int m,int n)
ie, Without explicitly specifying array size ??
Let us C has a good explanation about how to pass two D array as parameter.
I usually use these two ways for passing 2D array as parameter. But you need to specify the size explicitly.
void display1(int q[][4],int row,int col){
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
printf("%d",q[i][j]);
printf("\n");
}
}
void display2(int (*q)[4],int row,int col){
int i,j;
int *p;
for(i=0;i<row;i++)
{
p=q+i;
for(j=0;j<col;j++)
printf("%d",*(p+j));
printf("\n");
}
}
int main()
{
int a[3][4]={1,2,3,4,5,6,7,8,9,0,1,6};
display1(a,3,4);
display2(a,3,4);
}

Function which receives a 1 d array and print its value there?

I wanted to write a function which can receive a 1-D array and print its value there.Also wanted to know how 2-D array can be received by a function and print its value there.
In C you pass arrays by pointers, and usually a second parameter, which contains its length.
For Example: void printArray(char * arrayStart, int length) (for a char array)
and I assume you know how to write a simple for-loop to iterate over all elements of your array and print them. For 2D Arrays you would use char ** arrayStartinstead.
(When calling the function you pass the array in the following fashion:
char myArray[] = "some Text"
printArray(myArray, 9);
)
sample code here:
#include<stdio.h>
void print_1D(int *arr,int m)
{
int i;
for(i=0;i<m;i++)
printf("%d ",arr[i]);
putchar('\n');
}
void print_2D(int *arr[num],int m,int n) //<---observe here
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
printf("%d ",arr[i][j]);
putchar('\n');
}
}
int main()
{
int oneD[anySize1] = {2,5,67,23,32,....};
int twoD[anySize2][num] = { {23,17,..},{....},{....},....}; //<---and here
int m = anySize1,n = anySize2;
print_1D(oneD,m);
print_2D(twoD,m,n);
return 0;
}
if 2d is array is declared like this
int arr2D[10][20];
then function declaration must be,
void print_2D(int *arr[20],int m,int n)
or
void print_2D(int arr[][20],int m,int n)

removing duplicate values from an array in C

I am trying to create a program in C that removes duplicate values in an integer array. My strategy is to first sort the array via a selectionsort function, and then call a function removedup that removes any consecutive, duplicate values in the array.
My code:
#include <stdio.h>
#include "simpio.h"
#define n 10
void GetArray(int a[]);
void SelectionSort(int a[]);
int FindMax(int a[], int high);
void swap(int a[], int p1, int p2);
int removedup(int a[]);
void printArray(int a[]);
main()
{
int a[n];
GetArray(a);
SelectionSort(a);
printf("The original, sorted array is\n");
printArray(a);
printf("The array with removed duplicates \n");
printArray(removedup(a));
getchar();
}
void GetArray(int a[])
{
int i;
for(i=0;i<n;i++)
{
printf("Enter integer# %d", i+1);
a[i]=GetInteger();
}
}
void SelectionSort(int a[])
{
int i, max;
for(i=0;i<n;i++)
{
max=FindMax(a,n-i-1);
swap(a,max,n-i-1);
}
}
int FindMax(int a[], int high)
{
int i, index;
index=high;
for(i=0;i<high;i++)
{
if(a[i]>a[index])
index=i;
}
return index;
}
void swap(int a[], int p1, int p2)
{
int temp;
temp=a[p2];
a[p2]=a[p1];
a[p1]=temp;
}
int removedup(int a[])
{
int i, count, OutArray[count], j;
count=0;
for(i=0;i<n-1;i++)
{
if(a[i]==a[i+1])
{
a[i+1]=a[i+2];
count++;
}
}
count++;
for(j=0;j<count;j++)
{
OutArray[i]=a[i];
}
return OutArray;
}
I have two questions:
1) How do I fix the error the compiler in giving me in the main body when calling removedup inside the printarray function, saying "invalid conversion from int to int*"? (line 22)
2) How do I accurately define the size of OutArray[] in the removedup function? Currently I have it defined as the size variable, but the value of this variable isn't accurately defined until after the declaration of OutArray.
Notice your prototypes ...
int removedup(int a[]);
void printArray(int a[]);
And also notice you're calling printArray() with the result of removedup().
printArray(removedup(a));
The result of removedup() is an int; printarray() requires a int[].
int and int[] are not compatible.
I suggest you remove duplicates and print array in two distinct statements.
You should be able to fix the compiling problems after reading comp.lang-c FAQ on arrays and pointers.
After you get your array sorted, you can use the following function to remove the duplicates:
int dedup(int arr[], int size) {
int curr = 0, next = 0;
while (next < size) {
while (next < size && arr[next] == arr[curr])
next++;
if (next < size)
arr[++curr] = arr[next++];
}
return size ? curr+1 : 0;
}
It takes two arguments, the array and its size. The duplicates are removed in-place, which means that the array is modified, without allocating a new array to store the unique elements.
Remember that the dedup function expects the elements to be sorted! I've noticed you are using your own implementation of selection sort, which makes me think this is homework. In that case, I feel a little reluctant on giving you a complete solution, although understanding it should be a good exercise anyway.
EDIT: I should've explained the last line of code.
return size ? curr+1 : 0; is equivalent to:
if (size)
return curr+1;
else
return 0;
Just a shorter way of saying the same thing.

Resources