what the difference between a function and *function? - c

I am confused in C as i am newbie. i know 1.1 is giving me maximum value and 1.2 is giving me maximum value variable address [Picture].
My question is how do i call *findmax function in main?
int * findMax(int *a,int SIZE){
int i,max=*a,address,add;
for(i=0;i<SIZE;i++){
if(max<*(a+i)){
max=*(a+i);
}
}
//printf("maxium value is %d at index %x",max,&max);
return &max;
}

The * in the function definition is not a function pointer, it's the function's return type. The findMax function returns a pointer to integer. So you would call it just like any other functions in main:
int a[] = {1,2,3,4};
int *p = findMax(a, 4);
There is another problem, in your findMax function, you returned a pointer to a local variable, the storage of the variable will be no longer available when the function returns. Use it causes undefined behavior. So you can just return the max as an integer instead, if you really need to return a pointer, you should allocate it, or return a pointer that remains valid.
For example:
int* findMax(int *a,int SIZE){
int i;
int *max = a;
for(i=0;i<SIZE;i++){
if(*max<*(a+i)){
max=a+i;
}
}
return max;
}

#include<stdio.h>
int Max;
int* FindMax(int *a,int size)
{
int i;
Max=a[0];
for(i=0;i<size;i++)
{
if(Max<=a[i])
Max=a[i];
}
return &Max;
}
int main()
{
int a[10]={10,19,9,127,45,189,47,222,90,158};
printf("Address of Max Element:%p \n",FindMax(a,10));
printf("Max of Elements:%d \n",Max);
getchar();
return 0;
}

Related

Why address of the variable changes after passing the function

I need to find the smallest and biggest number in the array using pointers; in addition to that, I also need to output the address of these numbers in the main function.
The part I am struggling with is finding the address of the number. The problem is that there are different addresses for the same number. Why is it so?
This is what I get as output:
Please enter a value 0 - 4
Please enter a value 1 - 7
Please enter a value 2 - 2
0x7ffeefbff4fc,4
0x7ffeefbff500,7
0x7ffeefbff504,2
The min value is: 2
The max value is: 7
and address 0x7ffeefbff4f0
#define size 3
void Input (int arr[]);
void AdressOutput (int arr[]);
void MinAndMax (int arr[],int *min,int *max);
int main(void)
{
int arr[size];
int min=0,max=0;
Input(arr);
AdressOutput(arr);
MinAndMax(arr,&min,&max);
printf ("The min value is: %d\n",min);
printf ("The max value is: %d\n and address %p\n",max,&max);
return 0;
}
void Input (int arr[])
{
int i;
int *p=arr;
for (i=0;i<size;i++)
{
printf ("Please enter a value %d - ",i);
scanf ("%d",(p+i));
}
printf ("\n");
}
void AdressOutput (int arr[])
{
int i=0;
int *p=arr;
for (i=0;i<size;i++)
{
printf ("%p,%d\n",(p+i),*(p+i));
}
}
void MinAndMax (int arr[],int *min,int *max)
{
int i=0;
int *p;
p=arr;
*min=*p;
*max=*p;
for (i=0;i<size;i++)
{
if(*(p+i)>*max) //finding max
*max=*(p+i);
}
for (i=0;i<size;i++)
{
if(*(p+i)<*min)//finding min
*min=*(p+i);
}
}
I don't understand why the address changes and how can I create a function which will find addresses and will allow me to print them out in the main function?
In the function MinAndMax arr is your input parameter (parameter given to a function for input) and max and min are output parameters (parameter given to a function for storing output). the function would get the addresses of where to store output from output parameters. output parameters are always addresses, ie the value in these parameters point to the memory where you ultimately want to store your output.
What do you want to store? do you want to store an int OR do you want an address which points to int
you want to print the address of min and max values, so you want to store addresses which points to int
in main function you have declared int min=0,max=0;, these can't store addresses, thay can store only int. so lets change that to int *min_address, *max_address;
you have declared function MinAndMax as void MinAndMax (int arr[],int *min,int *max);. for parameters min and max this means addresses which point to int.
but as you want to store addresses, so what you want in your function is: addresses of memory cells which store the address which points to int. in other words you want a double pointer. so lets change the function declaration to void MinAndMax (int arr[], int **min_address, int **max_address);
here is the corrected code:
#include<stdio.h>
#define size 3
void Input (int arr[]);
void AdressOutput (int arr[]);
void MinAndMax (int arr[], int **min_address, int **max_address);
int main(void)
{
int arr[size];
int *min_address, *max_address;
Input(arr);
AdressOutput(arr);
MinAndMax(arr, &min_address, &max_address);
printf("The min value is: %d\n and adress %p\n", *min_address, min_address);
printf("The max value is: %d\n and adress %p\n", *max_address, max_address);
return 0;
}
void Input (int arr[])
{
int i;
int *p=arr;
for (i=0;i<size;i++)
{
printf("Please enter a value %d - ",i);
scanf("%d",(p+i));
}
printf ("\n");
}
void AdressOutput (int arr[])
{
int i=0;
int *p=arr;
for (i=0;i<size;i++)
{
printf("%p,%d\n",(p+i),*(p+i));
}
}
void MinAndMax (int arr[], int **min_address, int **max_address)
{
int i=0;
int *p;
p=arr;
*min_address=p;
*max_address=p;
for (i=0;i<size;i++)
{
if(*(p+i)>**max_address) //finding max
*max_address=(p+i);
}
for (i=0;i<size;i++)
{
if(*(p+i)<**min_address) //finding min
*min_address=(p+i);
}
}

Passing array to function using pointer

I'm trying to print array of pointer using pointer instead of array but I got this error Segmentation fault at runtime:
enter number of element:5
array[0]=1
array[1]=2
array[2]=3
array[3]=4
array[4]=5
Segmentation fault
This is the code:
#include <stdio.h>
#include <stdlib.h>
int *array;
int n;
void input(int *array,int n);
void display(int *array,int n);
int sum(int *array,int n);
int main (void) {
int result;
printf("enter number of element:");scanf("%d",&n);
input(array,n);
display(array,n);
result=sum(array,n);
printf("sum of array=%d",result);
return 0;
}
void input(int *array,int n){
int j;
array=(int *)malloc(n*sizeof(int));
for(j=0;j<n;j++){
printf("array[%d]=",j);scanf("%d",array+j);
}
}
void display(int *array,int n){
int j;
for(j=0;j<n;j++)
printf("%d\t",*(array+j));
printf("\n");
}
int sum(int *array,int n){
int sum=0,j;
for(j=0;j<n;j++)
sum+=*array+j;
return sum;
}
How can I fixed this code? please somebody explain me what's wrong with that code.
Variable array is a local variable in function input.
As such, it is pointless to set it with array = ..., because this assignment takes effect only inside the function. You should typically pass its address (&array) to any function that needs to change it.
In your specific example, you also have a global variable array, so a quick solution to your problem would be to simply call function input without passing variable array as an argument:
void input(int n)
{
...
array = (int*)malloc(n*sizeof(int));
...
}
int main()
{
...
input(n);
...
}
Note that this is a "dirty" workaround, and you should typically strive to avoid the use of global variables.
To add the clean version to barak's answer:
int input(int ** array, const size_t n)
{
int result = 0;
assert(NULL != array);
(*array) = malloc(n * sizeof(**array));
if (NULL == (*array))
{
result = -1;
}
else
{
size_t j;
for(j = 0; j < n; ++j)
{
printf("array[%zu]=", j);
scanf("%d", (*array) + j); /* still missing error checking here . */
}
}
return result;
}
And call it like this:
if (-1 == input(&array, n))
{
perror("input() failed");
exit(EXIT_FAILURE);
}
Try this input():
void input(int **array,int n){
int j;
*array=(int *)malloc(n*sizeof(int));
for(j=0;j<n;j++){
printf("array[%d]=",j);scanf("%d",*array+j);
}
}
Because C use pass-by-value, if you want to change the value of a variable in a function, you need to pass the address of that variable as the argument to that function.
In this case, you want to change the value of array in input() and the type of array is int *, therefore the prototype of input() should be something like void input (int **array, ...).
this should do..make sure you understand what the others have said..
#include <stdio.h>
#include <stdlib.h>
int *array;
int n;
void input(int **array,int n);
void display(int **array,int n);
int sum(int **array,int n);
int main (void) {
int result;
printf("enter number of element:");scanf("%d",&n);
input(&array,n);
display(&array,n);
result = sum(&array,n);
printf("sum of array= %d",result);
return 0;
}
void input(int **array,int n){
int j;
*array= malloc(n*sizeof(int));
for(j=0;j<n;j++){
printf("array[%d]=",j);
scanf("%d",(*array)+j);
}
}
void display(int **array,int n){
int j;
for(j=0;j<n;j++){
printf("%d\t",*((*array)+j)); // you can use array notation aswell
//array[0][j] will work
}
printf("\n");
}
int sum(int **array,int n){
int sum=0,j;
for(j=0;j<n;j++){
sum += *((*array)+j);
}
return sum;
}
What does *array + j do? Does it evaluate *array and add j to it? Or does it add j to array and then dereference it? Would you be willing to bet $100 on it if I told you you are wrong?
Make your life and the life of anybody reading your code easier by using parentheses, or even better, write array [j].

Why does this C code segfault?

I keep getting a segmentation fault in this code:
#include <stdio.h>
void FillArray(int *array, int);
#define MAX 256
int main()
{
int *array[MAX], size = 100;
FillArray(*array, size);
return 0;
}
void FillArray(int *array, int size)
{
int i, temp;
for (i = 0; i < size; i ++)
{
temp = (rand()%101);
*array = temp;
printf ("array[%d]. %d\n", i, *array);
array += i;
}
printf ("AJGIUEROGUSHFDJGJDFK/n");
}
I put the printf on the last line so that i could tell if it would reach that point, so far it hasn't.
Edit: I added code. I have to use pointer arithmetic instead of array indexes.
Your array in main is declared as an array of int * pointers. This array is not initialized, i.e. all elements contain garbage values.
Layer your FillArray call in main
FillArray(*array, size);
passes the value of *array to FillArray function. *array is the same as array[0] - it is an uninitialized garbage pointer that points nowhere.
Inside FillArray function you are attempting to access (and write) data through that uninitialized garbage pointer. Expectedly, the code crashes.
As is always the case with invalid code, there's no way to fix the error until you explain what you are trying to do.
I can only guess that all you needed is an array of int elements, not int * elements. I.e. your array in main was supposed to be declared as int array[MAX]. And FillArray should have been called as FillArray(array, size). Also, inside the cycle it is supposed to be array += 1 (or just ++array), not your array += i, which does not make any sense.
If wanna fill the array passed to your function, then change
array = &temp;
to
*array = temp;
And also change
array += i;
to
array++;
EDIT: OP edited his question and want to fill an array of integers. You need to chage the declaration of your array
int *array[MAX], size = 100; // Declare an array of pointers
to
int array[MAX], size = 100; // Declates an array of ints
Your loop should just be:
int i, temp;
for (i = 0; i < size; i ++)
{
temp = rand() % 101;
array[i] = temp;
printf ("array[%d] = %d\n", i, array[i]);
}
This will do what you want. There's no need to re-assign array inside the function, although you can. It's easier to just use the indexing operator []. Remember that
a[i]
is the same as
*(a + i)
regardless of the types involved (but generally a is a pointer type and i an unsigned integer) as long as the sum is a pointer of course.
There are errors in main(), too:
The array should just be int array[MAX];.
The call should just be FillArray(array, size);.
probably your want.
#include <stdio.h>
#include <stdlib.h>
void FillArray(int *array, int);
#define MAX 256
int main(){
int array[MAX], size = 100;
FillArray(array, size);
return 0;
}
void FillArray(int *array, int size){
int i;
for (i = 0; i < size; i++){
*array = rand()%101;
printf ("array[%d]. %d\n", i, *array);
++array;
}
}
int *array[MAX] is an array of MAX pointers to int, from which you pass the 1st to the function. There are no ints defined where the latter points to.
To fix this appliy the changes void FillArray(int *array, int size) provided by the other answers and then call it like this:
int main(void)
{
int array[MAX], size = 100;
FillArray(array, size);
return 0;
}
Code is fine except for your perception that *array = &array, which is wrong !!
Below points might help in understating pointers better:
*array = array[0]
array = &array[0]
*(array+i) = array[i]
Made changes to your code and it should work fine:
#include <stdio.h>
void FillArray(int *array, int);
#define MAX 256
int main()
{
int *array, size = 100;
array=(int *)calloc(MAX,sizeof(int));
if(array !=NULL)
{
FillArray(array, size); /* While calling send &array[0] but not array[0] */
}
return 0;
}
void FillArray(int *array, int size)
{
int i, temp;
for (i = 0; i < size; i ++)
{
temp = (rand()%101);
*(array+i) = temp;
printf ("array[%d]. %d\n", i, *(array+i));
/* array += i; <-- not necessary */
}
printf ("AJGIUEROGUSHFDJGJDFK/n");
}

Returning an integer array from a function in C

My program is as follows
#include<stdio.h>
int *intial(int);
int main (void)
{
int i, *b;
b=intial(5);
for(i=0;i<5;i++)
printf("%d\t",*(b+i));
getch();
}
int *intial(int t)
{
int i, *a;
for(i=0;i<t;i++)
a[i]=i;
return a;
}
But i am getting garbage values.
I also tried this
int *intial(int t)
{
int i, a[10];
for(i=0;i<t;i++)
a[i]=i;
return a;
}
But it is not working.
In order to work properly, your function should read
int *intial(int t)
{
int i;
int *a = malloc(t * sizeof(*a));
if (!a) return NULL; // error checking
for(i=0;i<t;i++) {
a[i]=i;
}
return a;
}
The "calling treaty" for this function is that the pointer returned is a malloc()ed one which the caller has the obligion for to free() it.
Of course, the caller as well should do proper error checking:
int main()
{
int i;
int *b;
b=intial(5);
if (!b) {
fprintf(stderr, "Malloc error.\n");
return 1;
}
for(i=0;i<5;i++) {
printf("%d\t",*(b+i)); // *(b+i) should be replaced with b[i] for readability
}
free(b); // free the memory
return 0;
}
You need to allocate memory for your array with malloc(). Otherwise a, and hence b, will not point to anything in particular.

Passing an array as an argument to a function pointer in C

I'm currently studying pointers to functions and have been practicing on sort array functions.
The point is I input a sequence of numbers into the function and the program will re arrange it in ascending order. It worked just fine when I do a call by value function (I think that's how you call it). However when I try to assign a pointer to function and try to use that pointer instead of the function itself, it returns a bunch of errors. I'm sure the problem is due to the fact that I'm passing an array as an argument to the function POINTER. Here is my code:
#include<stdio.h>
#define SIZE 10
void sort(int a[], int size);
void swap(int *elt1, int *elt2);
main()
{
int i; int array[SIZE]= {1,9,3,2,4,100,43,23,32,12};
void (*fptr)(int array, int SIZE);
fptr = &sort;
(*fptr)(array,SIZE);
/*sort(array, SIZE);*/
for(i=0;i<SIZE;i++)
{
printf("%d\n", array[i]);
}
return 0;
}
void sort(int a[], int size)
{
int pass, j;
for(pass = 0; pass<size;pass++)
{
for(j=0;j<size;j++)
{
if(a[j]>a[j+1])
{
swap(&a[j], &a[j+1]);
}
}
}
}
void swap(int *elt1, int *elt2)
{
int hold;
hold = *elt1;
*elt1 = *elt2;
*elt2 = hold;
}
The first argument of the function is a pointer to int (that is, int *), and not int.
void (*fptr)(int array, int SIZE);
should be
void (*fptr)(int *array, int SIZE);

Resources