This is my first question here, so I apologize in advance.
Whenever it executes it just takes one number as input and then terminates. Can't, we use this logic to find out the greatest and smallest number among any numbers??
#include<stdio.h>
void main()
{
int *p,n,i,max,min;
printf("How many numbers?= ");
scanf("%d",&n);
printf("\nStart entering numbers\n");
for(i=0;i<n;i ){
scanf("%d",(p i));
}
max=*(p 0);
for(i=0;i<n;i )
{
if(*(p i)>max)
{max=*(p i);}
}
printf("Maximum number = %d\n",max);
min=*(p 0);
for(i=0;i<n;i )
{
if(*(p i)<min)
min=*(p i);
}
printf("Minimum number = %d",min);
}
Whenever it executes, it just takes one number as input and then terminates.
Can't,we use this logic to find out the greatest and smallest number among any numbers?
CodePudding user response:
In your code you have a pointer to a int
called p
that points to nothing, it is empty.
Then you call scanf()
and read into the empty pointer p
.
scanf("%d",(p i));
This will not work since p
points to nothing and when scanf()
tries to store something inside it, it will most likely lead to a segmentation fault or undefined behaviour.
To fix it you could allocate memory for p
with malloc()
:
int *p = malloc(sizeof(int) * n);
if (p == NULL)
{
fprintf(stderr, "malloc failed");
// error procedure
}
This will create an array capable of storing n
elements of type int
.
Notes:
Your code uses a lot of
*(p i)
s, this could cause confusion and lead to error prone code, it is best that you usep[i]
instead.Your
main
function has return typevoid
, instead you should useint
so you can return a error code of some sort if something fails.You should test the return value of
scanf
to see if it failed to read something from the user.
CodePudding user response:
You have undefined behaviour here: You're declaring a pointer p
and start assigning values not only to the memory location of p
but also of subsequent pointers p 1
, p 2
etc. But you've never checked if the system allocated available memory to you. You may be lucky and get a pointer to a memory address that has sufficient contiguous memory available to hold all the values that follow, but you can't rely on that.
A better way would be:
int n,i,max,min;
if (!(scanf("%d",&n))) return;
printf("\nStart entering numbers\n");
int *p = malloc(sizeof(int)*n);
if (p == NULL) return;
Essentially, you want to use malloc()
(for which you will have to #include <stdlib.h>
to allocate as much memory as you need for the numbers. For good practice, you also want to check whether the scanf
and the malloc
worked out right, which is the job of the two if
statements that terminate the program in case something went wrong. If not, you can be sure to have the memory you need, and the program can go on.
In terms of notation, you can use *(p 1)
etc if you want to, but it's more common (and more readable) to use p[1]
, and in fact the C standard requires the two to be equivalent.
CodePudding user response:
An array is not necessary to get the maximum and minimum values from a series of numbers.
Check the return from scanf
. When scanning an integer it can return 1, 0, or EOF. 1 is an integer was scanned, 0 is an integer could not be scanned from the input and EOF indicates End Of File.
The scanset %*[^\n]
scans and discards everything up to an newline to clean the input stream.
#include<stdio.h>
#include<string.h>
#include<limits.h>
int scanfint ( int *value);
int main ( void)
{
int min = INT_MAX; // set min to maximum value for an integer
int max = INT_MIN; // set max to minimum value for an integer
int number = 0;
int howmany = 0;
int count = 0;
printf ( "How many numbers? ");
fflush ( stdout);
if ( 1 == scanfint ( &howmany)) {
printf("\nStart entering numbers\n");
while ( howmany && 1 == scanfint ( &number)) {
if ( number < min) {
min = number; // store new minimum
}
if ( number > max) {
max = number; // store new maximum
}
count;
--howmany;
printf ( "\t%d numbers entered\n", count);
if ( howmany) {
printf ( "\tenter another number\n");
}
}
if ( count) { // at least one number entered
printf ( "%d numbers entered\n", count);
printf("Maximum number = %d\n",max);
printf("Minimum number = %d\n",min);
}
}
}
int scanfint ( int *value) {
int result = 0;
while ( 1) {
if ( 1 == ( result = scanf ( "%d", value))) {
scanf ( "%*[^\n]"); // clean input stream
return 1;
}
if ( EOF == result) {
return -1;
}
// did not scan an integer
scanf ( "%*[^\n]"); // clean input stream
printf ( "\tproblem scanning\n\ttry again\n");
}
return 0;
}
CodePudding user response:
If the number of p members is very small, I (personally) wouldn't do the job with malloc(), and then (one souldn't forget!) free();
I would just do something like int p[100]; instead of *p, and to refer like p[0] or p[i] to them instead of using pointers.
CodePudding user response:
your code is working as it should. After each input, you have to press enter to make the input stream flow as you want.
As experienced people say, there can be ub here, which is the most dangerous about catching the error.