The function I'm making is supposed to return to the maximum value in a vector, and I'm stumped as to why it's not working, here is the code:
float max(float vec[], int len) {
int i;
float max;
for (i = 0; i < len; i++) {
if (vec[i] > max) {
max = vec[i];
}
}
return max;
}
max is uninitialized and using uninitialized variables leads to undefined behavior.
float max = vec[0];// Initialize max before using it
You did not initialize local variable
float max;
You could do it the following way
float max = vec[0];
Also the function has a problem when the second parameter is either equal to 0 or is a negative value.
The general approach is to return the index of the maximum element and in the caller to compare the returned index with the value of the second parameter. If they are equal then the array is empty. Otherwise the index points to the maximum element.
So the function could be written the following way
size_t max_element( const float vec[], size_t len )
{
size_t max = 0;
size_t i = 1;
for ( ; i < len; i++ )
{
if ( vec[max] < vec[i] ) max = i;
}
return max;
}
and in the caller you could write
float vec[] = { /* some initializers */ };
size_t max = max_element( vec, sizeof( vec ) / sizeof( *vec ) );
printf( "The maximum value is &f for element with index %zu\n", vec[max], max );
Related
I am studying the pointers and this question became interesting. I want it to be like this: we have two arrays of integers. Determine the value and number of the largest element of the first array that is not part of the second but I don't know how to make the second part of the code that will check if the largest number is not included in the second array
#include <stdio.h>
int main()
{
long array[100], * maximum, size, c, location = 1;
printf("Enter the number of elements in array\n");
scanf_s("%ld", &size);
printf("Enter %ld integers\n", size);
for (c = 0; c < size; c++)
scanf_s("%ld", &array[c]);
maximum = array;
*maximum = *array;
for (c = 1; c < size; c++)
{
if (*(array + c) > *maximum)
{
*maximum = *(array + c);
location = c + 1;
}
}
printf("Maximum element is present at location number %ld and it's value is %ld.\n", location, *maximum);
return 0;
}
For starters your incomplete code already is wrong. It changes the source array
maximum = array;
//...
*maximum = *(array + c);
More precisely it changes the first element of the array. It shall not do that.
As for your question then the code will look more clear and readable if to implement the algorithm as separate functions.
Here is a demonstration program.
#include <stdio.h>
int find( const int a[], size_t n, int value )
{
const int *p = a;
while (p != a + n && *p != value) ++p;
return p != a + n;
}
int * max_exclusive_element( const int a1[], size_t n1, const int a2[], size_t n2 )
{
const int *max = a1;
while (max < a1 + n1 && find( a2, n2, *max ) ) ++max;
if (max < a1 + n1)
{
for ( const int *p = max; ++p < a1 + n1; )
{
if ( *max < *p && !find( a2, n2, *p ) )
{
max = p;
}
}
}
return ( int * )( max == a1 + n1 ? NULL : max );
}
int main( void )
{
int a1[] = { 1, 3, 5, 6, 7, 8, 9 };
const size_t N1 = sizeof( a1 ) / sizeof( *a1 );
int a2[] = { 1, 3, 5, 7, 9 };
const size_t N2 = sizeof( a2 ) / sizeof( *a2 );
int *max = max_exclusive_element( a1, N1, a2, N2 );
if (max != NULL)
{
printf( "Maximum element is present at location number %td and it's value is %d.\n",
max - a1, *max );
}
}
The program output is
Maximum element is present at location number 5 and it's value is 8.
The function find determines whether a given value is present in an array. And the second function max_exclusive_element finds the maximum element according to the requirement.
As you can see all loops use pointers.
If you need to use arrays with elements of the type long int then it will be not hard to change the presented code.
I think you are doing this in the wrong order. If you find the maximum first and that is in the second array, you need to find the maximum again. You should first check each number in the first array against the second. If it is in the second, change the value to LONG_MIN. Then the maximum will be the right answer. Basically something like this:
#include <limits.h>
int i = 0;
for (; i < n; ++i) {
int j = 0;
for (; j < n; ++j) {
/* in both arrays? */
if (arr2[i] == arr1[j]) {
arr1[j] = LONG_MIN;
break;
}
}
}
At this point any numbers in arr1 that are in arr2 will be set to LONG_MIN. Now just calculate max like you already did.
Edit: changed INT_MIN to LONG_MIN. I didn't notice you were doing long int arrays.
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;
}
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
}
Can someone help me fixing the syntax errors in this code?
#include <stdio.h>
int result(int v, int size);
int main(void){
int arr[5], n;
for (n = -1; n < 4; n++){
arr[n] = n + 1;
printf("the product of entered values is %d", result(n, 5));
}
return 0;
}
int product(int a[]) {
int product, i;
for (i = 0; i <= sizeof(int); i++){
product *= a[i];
}
return product;
}
for (n = -1; n < 4; n++){
arr[n] = n + 1;
You start n at -1, then immediately use arr[n].
Negative indices are not allowed in C. Valid values are 0 to the size of the array-1.In otherwords, if you have an arr[5], then the valid indices are [0], [1], [2], [3], and [4].
int product(int a[]) {
int product, i;
You create a function named product and also a variable named product.
That makes it virtually impossible to refer to the proper object. Work on your name management, so that every item is unambiguous.
You are trying to call the result function, for which you have provided the forward declaration but not an actual implementation. You need to write an implementation for the result function. That is why the compiler complains about an undefined reference.
For starters the function result is declared
int result(int v, int size);
but not defined.
On the other hand, taking into account the message in this call of printf
printf("the product of entered values is %d", result(n, 5));
you mean a function that calculates a product of elements of an array like your function defined after main but that is not used
int product(int a[]) {
int product, i;
for (i = 0; i <= sizeof(int); i++){
product *= a[i];
}
return product;
}
So let's remove the declaration of the function result and declare before main a function with name product because the name result is not enough informative.
The function deals with an array. We need to pass to the function the number of elements in the array. As the array itself will not be changed within the function then it should be declared with the qualifier const
Also a product of integer numbers of the type int can be too big to be stored in an object of the type int.
So it is better to declare the return type of the function at least like long long int (or even like double or long double).
Thus the function declaration can look like
long long int product( const int a[], size_t n );
The function can be defined the following way
long long int product( const int a[], size_t n )
{
long long int result = n == 0 ? 0 : 1;
for ( size_t i = 0; i < n; i++ )
{
result *= a[i];
}
return result;
}
As for your function product then you forgot to initialize the variable product
int product, i;
The condition in the for loop
for (i = 0; i <= sizeof(int); i++){
does not make a sense because the expression sizeof( int ) does not yield the number of elements in an array.
Try to not use magic numbers like 5 in this declaration
int arr[5], n;
in your programs. Use named constants.
Indices of arrays always start from 0. So this loop
for (n = -1; n < 4; n++){
where the variable n is used as an index does not make sense.
Also this call of printf
printf("the product of entered values is %d", result(n, 5));
must be placed outside the for loop and in the the call of the function result that is used as an argument of the function printf
result(n, 5)
you even are not using the array.
Thus the program can look the following way
#include <stdio.h>
long long int product( const int a[], size_t n );
int main(void)
{
enum { N = 5 };
int a[N];
for ( size_t i = 0; i < N; i++ )
{
a[i] = i + 1;
}
printf( "The product of entered values is %lld", product( a, N ) );
return 0;
}
long long int product( const int a[], size_t n )
{
long long int result = n == 0 ? 0 : 1;
for ( size_t i = 0; i < n; i++ )
{
result *= a[i];
}
return result;
}
The program output is
The product of entered values is 120
// function t find the max value entered in the array
double max(double *n,int size)
{
int i,k=0;
double *maxi;
maxi=&k;
for(i=0;i<size;i++)
{
if(*maxi<n[i])
{
maxi=&n[i];
}
}
return *maxi;
}
//elements of array are added
main()
{
double a[10000],maxi;
int size,i;
printf("enter the size of the array");
scanf("%d",&size);
printf("enter the elements of array");
for(i=0;i<size;i++)
{
scanf("%lf",&a[i]);
}
maxi=max(&a,size);
printf("maximum value is %lf",maxi);
}
Why is the pointer not de-referenced in the function max? If I de-reference the pointer n it gives an error. If there is a better way to do this, please suggest.
n[i] is the very same thing as *(n + i). So the pointer is de-referenced, through the [] syntax.
As for why you are getting an error, it is impossible to tell without you posting the problematic code.
Passing the array/pointer as argument and dereferencing are both wrong.
maxi=max(&a,size); // passing address of the address
if(*maxi<n[i]) // k is compared to memory garbage
maxi=&n[i]; // maxi is assigned with memory garbage
Consider following:
double max( double * na, int size ) // n changed to na
{
int idx; // changed i to idx;
double max; // forget about k and maxi, just simply max
if( 0 < size )
{
max = na[0]; // init max to 1st elem
for( idx = 1; idx < size; ++idx ) // iterate from 2nd elem
{
if( max < na[idx] ) { max = na[idx]; } // check for larger
}
}
return max;
}
int main()
{
double an[10000],maxi; // a changed to an
// ..
maxi = max( an, size ); // pass an not &an
// ..
return 0;
}