multi pointers in function in c - c

i'm not good at english.
i declare array and two pointers.
the maxPtr pointer should have array arr's maximum number adress.
and minPtr pointer should have array arr's minimum number adress.
so i declare the function and this has two double-pointer to give maxPtr and minPtr proper adress.
but whenever i run this code, the program is not fully run.
it doesn't output the result( printf("%d",*maxPtr) ,printf("%d", *minPtr, printf("Hi");
this program is run at vscode in mac.
what make it error?
#include <stdio.h>
void MaxAndMin(int* str,int** max, int** min)
{
int i;
int maxnum=0,minnum=0;
for(i=0; i<5; i++)
{
if(maxnum< str[i])
{
maxnum =str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
}
int main(void)
{
int i,len;
int* maxPtr;
int* minPtr;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("%d번째 정수입력 입니다.",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr,&maxPtr,&minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}
the result is
> Executing task: ./test <
1번째 정수입력 입니다.1
2번째 정수입력 입니다.2
3번째 정수입력 입니다.3
4번째 정수입력 입니다.4
5번째 정수입력 입니다.5
Terminal will be reused by tasks, press any key to close it.

For starters this initialization of an array
int arr[5]={};
is incorrect in C. You have to write
int arr[5]={ 0 };
Secondly using the magic number 5 within the function makes the function useless in general. You need to pass to the function the size of the array.
The initial value 0
int maxnum=0,minnum=0;
of these variables makes the function even more less useful. In general the array can contain either all elements positive or all elements negative.
And you need to flush the output buffer using for example the new line character '\n' in calls of printf.
The function can be declared and defined the following way as it is shown in the demonstration program below.
#include <stdio.h>
void MaxAndMin( const int a[], size_t n, int **max, int **min )
{
*max = ( int * )a;
*min = ( int * )a;
for ( size_t i = 1; i < n; i++ )
{
if ( **max < a[i] )
{
*max = ( int *)( a + i );
}
else if ( a[i] < **min )
{
*min = ( int * )( a + i );
}
}
}
int main( void )
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
int *maxPtr = NULL;
int *minPtr = NULL;
MaxAndMin( a, N, &maxPtr, &minPtr );
printf( "The maximum value is %d at position %tu\n",
*maxPtr, maxPtr - a );
printf( "The minimum value is %d at position %tu\n",
*minPtr, minPtr - a );
}
The program output is
The maximum value is 9 at position 9
The minimum value is 0 at position 0
Pay attention to that the first parameter of the function should have the qualifier const because passed arrays to the function are not changed within the function.

The main issue is that the minnum is set at zero, which would only work if array had a negative value.
Setting minimum = star[0] also would not work!!! Because in the case of str[0] having negative value, *min never gets changed.
Also, I recommend to always initialize all variables in the declaration, especially pointers (because they may theoretically cause accidental access to memory).
Full solution:
#include <stdio.h>
int MaxAndMin(int* str, int** max, int** min)
{
int i;
int maxnum = 0;
int minnum = str[0] + 1;
for(i=0; i<5; i++)
{
if(maxnum < str[i])
{
maxnum = str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
return 0;
}
int main(void)
{
int i = 0;
int len = 0;
int* maxPtr = NULL;
int* minPtr = NULL;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("Enter number %d: ",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr, &maxPtr, &minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}

Related

empty pointers as an argument in C - problem with asterisks

The task is to fill an array with numbers by user input and then use our stats() function to calculate average etc. of each row of this array. The header of stats() function looks as follows:
int stats(int (*ptr)[5], int width, int height, int row_id, int* max, int* min, float *avg)
where ptr is a pointer to the matrix,width and height are its size, row_id is the index of analysed row and max, min and avg are pointers to variables storing each statistics.
When calling a function with such line:
stats(*ptr, 5,5,2, *max = NULL, *min = NULL, *avg=NULL);
the following error appears:
error: invalid type argument of unary '*' (have 'int')
I tried different approaches but there is always a mistake, how can I fix that? Thank you for any clues.
edit:
Here's the whole code:
#include <stdio.h>
int stats(int (*ptr)[5], int width, int height, int row_id, int* max, int* min, float *avg)
{
int j, vmax,vmin;
int max = &vmax;
int min = &vmin;
int i = row_id;
int m = *ptr;
for(j = 0; j<5; j++){
if(m[i][j]>max)
{
max = m[i][j] ;
j++;
else
j++;
}
}
printf("%d", max);
return 0;
}
int main(void){
int n, i, j, vmin, vmax; // vmax - value of the maximum
int min = &vmin; // min - pointer to the minimum
int max = &vmax;
float vavg;
int avg = &vavg;
int m[5][5];
for(i = 0; i<5; i++)
{
for(j = 0; j<5; j++)
{
printf("ENTER A NUMBER: ");
scanf("%d", &n);
m[i][j] = n;
}
}
int ptr = &m;
stats(*ptr, 5,5,2, *max = NULL, *min = NULL, *avg=NULL);
return 0;
}
Your code full of bugs.
For example min and max are not declared as pointers
int min = &vmin; // min - pointer to the minimum
int max = &vmax;
Also it is unclear why the variable avg has the type int and is initialized by a pointer expression of the type float *.
float vavg;
int avg = &vavg;
Or the variable ptr of the type int is initialized by the address of the two-dimensional array.
int ptr = &m;
As for the function then if the function operates only on one row then there is no any sense to pass to the function the whole two-dimensional array.
Also the return type and the returned value of the function do not make a sense.
And the function shall not output any message. It is the caller of the function that will decide output a message or not.
And also the function contains bugs where you are redeclaring its parameters like for example
int max = &vmax;
that again does not make a sense.
Using your approach the function can be declared and defined the following way
#include <assert.h>
//...
void stats( const int *a, size_t n, int *max, int *min, float *avg )
{
assert( n != 0 );
*max = a[0];
*min = a[0];
float sum = a[0];
for( size_t i = 1; i < n; i++ )
{
sum += a[i];
if ( *max < a[i] )
{
*max = a[i];
}
else if ( a[i] < *min )
{
*min = a[i];
}
}
*avg = sum / n;
}
And called like
int min = 0;
int max = 0;
float avg = 0.0f;;
//...
stats( m[2], 5, &max, &min, &avg );
printf( "max = %d\n", max );
printf( "min = %d\n", min );
printf( "average = %f\n", avg );
When you are using pointers as function parameters be carefull. If you have something like this:
int func(int *max){
}
max ,here, is a pointer which needs to hold an address. So inside this function when you need use it, you need to dereference it by using *. For example:
int func(int *max){
*max = $someAddress
}

Two sum leetcode clang

I practice in c language, here is the exercise:
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example :
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].
Here my attempt:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
static int r[2];
for(int i=0;i<numsSize;i++){
for(int j=0;j<numsSize;j++){
if(i!=j&&(nums[i]+nums[j])==target){
r[0]=i;
r[1]=j;
}
}
}
return r;
}
But Irecieve a wrong answer:
enter image description here
The function definition does not satisfies the requirement specified in the comment
Note: The returned array must be malloced, assume caller calls free()
Moreover the parameter
int* returnSize
is not used within your function definition.
It seems the function should be defined the following way as it is shown in the demonstration program below. I assume that any element in the source array can be present in the result array only one time.
#include <stdio.h>
#include <stdlib.h>
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int *twoSum( int *nums, int numsSize, int target, int *returnSize )
{
int *result = NULL;
*returnSize = 0;
for (int i = 0; i < numsSize; i++)
{
for (int j = i + 1; j < numsSize; j++)
{
if (nums[i] + nums[j] == target)
{
int unique = result == NULL;
if (!unique)
{
unique = 1;
for (int k = 1; unique && k < *returnSize; k += 2)
{
unique = nums[k] != nums[j];
}
}
if (unique)
{
int *tmp = realloc( result, ( *returnSize + 2 ) * sizeof( int ) );
if (tmp != NULL)
{
result = tmp;
result[*returnSize] = i;
result[*returnSize + 1] = j;
*returnSize += 2;
}
}
}
}
}
return result;
}
int main( void )
{
int a[] = { 2, 7, 11, 15 };
int target = 9;
int resultSize;
int *result = twoSum( a, sizeof( a ) / sizeof( *a ), target, &resultSize );
if (result)
{
for (int i = 0; i < resultSize; i += 2 )
{
printf( "%d, %d ", result[i], result[i + 1] );
}
putchar( '\n' );
}
free( result );
}
The program output is
0, 1
Though as for me then I would declare the function like
int *twoSum( const int *nums, size_t numsSize, int target, size_t *returnSize );
The brute force approach is very simple to this problem.
int* twoSum(int* arr, int n, int t, int* returnSize){
int *res=malloc(2*sizeof(int));
*returnSize=2;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if((arr[i]+arr[j])==t)
{
res[0]=i;
res[1]=j;
goto exit;
}
}
}
exit:
return res;
}

To perform insert operation in a sorted array

What is wrong with this code and where is the problem?
I ran this code many times but it's showing that the code is running but I am not getting any output.
Can you tell me where is the mistake?
#include <stdio.h>
int print_arr(int *arr, int n)
{ for(int i=0; i<=n; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
int insert_ele(int *arr_a, int *arr_b, int n, int Key)
{
int i,j;
for(i=0, j=0; i<n; i++, j++)
{
if(arr_a[i]>Key)
{
arr_b[j] = Key;
arr_b[j+1] = arr_a[i];
j++;
}
else
{
arr_b[j] = arr_a[i];
}
}
return 0;
}
int main()
{
//code
int arr_a[] = {12, 16, 20, 40, 50, 70};
int arr_b[10];
int Key = 26;
int n = sizeof(arr_a)/sizeof(arr_a[0]);
int indx = insert_ele(arr_a, arr_b, n, Key);
print_arr(arr, n);
return 0;
}
For starters there is a typo in this statement
print_arr(arr, n);
It seems you mean
print_arr( arr_b, n + 1 );
The return type int of the function print_arr does not make a sense and is useless.
The first parameter of the function should have the qualifier const because the passed array is not being changed within the function.
The second parameter should have the type size_t.
This for loop
for(int i=0; i<=n; i++)
can invoke undefined behavior if the user of the function will pass the number of elements in the array in the second parameter n because in this case there will be an attempt to access memory beyond the array.
Again the return type int of the function insert_ele does not make a sense and is useless.
The first parameter should have the qualifier const because the source array is not being changed within the function. The parameter n should have the type size_t.
The function has a logical error.
Let's assume that the value of the variable Key is less than values of all elements of the array arr_a.
In this case the index j will be incremented twice and as a result you will have
b[0] = Key; b[2] = Key; b[4] = Key; and so on.
The logic of the function will be much clear if to split the for loop in two for loops.
The program can look the following way.
#include <stdio.h>
size_t insert_ele( const int *a, size_t n, int *b, int key )
{
size_t i = 0;
for ( ; i < n && !( key < a[i] ); i++ )
{
b[i] = a[i];
}
b[i] = key;
for ( ; i < n; i++ )
{
b[i+1] = a[i];
}
return i;
}
FILE * print_arr( const int *a, size_t n, FILE *fp )
{
for ( size_t i = 0; i < n; i++)
{
fprintf( fp, "%d ", a[i] );
}
return fp;
}
int main(void)
{
int a[] = { 12, 16, 20, 40, 50, 70 };
const size_t N = sizeof( a ) / sizeof( *a );
int b[10];
int key = 26;
size_t m = insert_ele( a, N, b, key );
fputc( '\n', print_arr( b, m, stdout ) );
return 0;
}
The program output is
12 16 20 26 40 50

How can I print the number of unique elements instead of show the elements itself in my code?

I want to print the number of unique elements instead of show the elements For example show 4. Means we have 4 unique elements
#include<stdio.h>
#define max 100
int ifexists(int z[], int u, int v)
{
int i;
for (i=0; i<u;i++)
if (z[i]==v) return (1);
return (0);
}
void main()
{
int p[max], q[max];
int m;
int i,k;
k=0;
printf("Enter length of the array:");
scanf("%d",&m);
printf("Enter %d elements of the array\n",m);
for(i=0;i<m;i++ )
scanf("%d",&p[i]);
q[0]=p[0];
k=1;
for (i=1;i<m;i++)
{
if(!ifexists(q,k,p[i]))
{
q[k]=p[i];
k++;
}
}
printf("\nThe unique elements in the array are:\n");
for(i = 0;i<k;i++)
printf("%d\n",q[i]);
}
https://onlinegdb.com/Bk3tvQMpw
Sort the array then iterate through the elements and print out if the current element is different than the last:
int cmpint(const void *a, const void *b) {
return *(int *) a) < *(int *) b :
-1 ?
(
*(int *) b) < *(int *) a ?
1 :
0
);
}
int main() {
/* ... */
qsort(p, m, sizeof(*p), cmpint);
int n = 0;
for(int i = 0; i < m; i++) {
if(!i || p[i-1] != p[i]) n++;
}
printf("Number of unique elements: %d\n", n);
}
where p is your now sorted array and length is m as per example code. As qsort is expected O(m *log(m)) so will this aglorithm. If you don't sort the array it will be O(m^2) due to m linear searches.
If I have understood the question correctly what you need is to count unique elements in an array using a function and without defining an auxiliary array. That is there is no need to output the unique elements themselves.
In this case the corresponding function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
int is_unique( const int a[], size_t n, int value )
{
while ( n != 0 && a[ n - 1 ] != value ) --n;
return n == 0;
}
int main(void)
{
int a[] = { 1, 2, 3, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t count = 0;
for ( size_t i = 0; i < N; i++ )
{
count += is_unique( a, count, a[i] );
}
printf( "There are %zu unique elements in the array.\n", count );
return 0;
}
The program output is
There are 3 unique elements in the array.
If you do not want to define one more function to count unique elements in an array then just move the loop in the function shown in the above demonstrative program inside main.
Here you are.
#include <stdio.h>
int main(void)
{
int a[] = { 1, 2, 3, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t count = 0;
for ( size_t i = 0; i < N; i++ )
{
size_t j = i;
while ( j != 0 && a[j - 1] != a[i] ) --j;
count += j == 0;
}
printf( "There are %zu unique elements in the array.\n", count );
return 0;
}
The program output is the same as shown above that is
There are 3 unique elements in the array.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
instead of
void main()

how to put numbers from interval to array? (C language)

I am looking for this for a while.
Can anyone tell me how can I create interval array?
Example:
interval = < 4;9 >
int array[9-4+1] = {4,5,6,7,8,9}
I would like to insert number from interval to array and than I can work with values in array.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int size_Of_Interval;
int a;
int b;
printf("Please specify the starting interval value: ");
scanf("%d", &a);
printf("Please specify the ending interval value: ");
scanf("%d", &b);
size_Of_Interval = (b-a+1);
printf("Interval from %d to %d. Interval has %d numbers\n", a, b, size_Of_Interval);
return 0;
}
If your compiler supports variable length arrays (VLAs) then you can just write
int arr[size_Of_Interval];
for ( int i = 0; i < size_Of_Interval; i++ )
{
arr[i] = a + i;
}
Otherwise you should dynamically allocate an array. For example
int *arr = malloc( size_Of_Interval * sizeof( int ) );
for ( int i = 0; i < size_Of_Interval; i++ )
{
arr[i] = a + i;
}
In this case you will need also to free the array when it will not be needed any more
free( arr );
Before to return from the main:
int *array = malloc(size_of_interval * sizeof(int));
This dynamically allocates the needed amount of memory, returning a pointer to the firts element of an array with size_of_interval length. Afterward you can go through a loop and fill that array:
for(int i = 0; i < size_Of_Interval; i++) {
array[i] = a + i;
}
When you end the job with your array, as commented above, you need to free the resource:
free(array);

Resources