"I wanted to know if I was wrong about using the pointers or my mistake was in logic".
Certainly in the use of pointers, or in the non-use in the comparisons. And the logic I have not yet understood. It may be right but it is incredibly complicated.
And you were wrong not to test the return of scanf()
. There’s no point in following if you haven’t read the 3 values.
It’s just about classifying 3 elements. It involves 3 comparisons. So I don’t understand why using recursion instead of just writing that
example
void _sort (float* x, float* y, float* z)
{
float temp;
if( *x > *y )
{
temp = *x;
*x = *y;
*y = temp;
};
if( *y > *z )
{
temp = *y;
*y = *z;
*z = temp;
};
if( *x > *y )
{
temp = *x;
*x = *y;
*y = temp;
};
return;
}; // _sort()
I think that would do. The Bubble Sort no loop. Two comparisons leave the highest value at z. A comparison then takes the lowest to x. And returns.
PS C:\src\ifdef> gcc -o tsort3 -Wall -std=c17 tsort3.c
PS C:\src\ifdef> ./tsort3
PS C:\src\ifdef> ./tsort3
Entre com 3 valores [numeros reais] : 1 2 3
Em ordem crescente: 1.0 2.0 3.0
PS C:\src\ifdef> ./tsort3
Entre com 3 valores [numeros reais] : 3 2 1
Em ordem crescente: 1.0 2.0 3.0
PS C:\src\ifdef> ./tsort3
Entre com 3 valores [numeros reais] : 1 3 2
Em ordem crescente: 1.0 2.0 3.0
PS C:\src\ifdef> ./tsort3
Entre com 3 valores [numeros reais] : -3.1 -3.22 -3.333
Em ordem crescente: -3.3 -3.2 -3.1
PS C:\src\ifdef>
is the way out of this program
#include<stdio.h>
void _sort (float*,float*,float*);
int main (void)
{
void _sort (float *x, float *y, float *z);
float a, b, c;
printf("Entre com 3 valores [numeros reais] : ");
int res = scanf("%f %f %f", &a, &b, &c);
if (res != 3) return -1;
_sort (&a, &b, &c);
printf("Em ordem crescente: %.1f %.1f %.1f", a, b, c);
return 0;
};
void _sort (float* x, float* y, float* z)
{
float temp;
if( *x > *y )
{
temp = *x;
*x = *y;
*y = temp;
};
if( *y > *z )
{
temp = *y;
*y = *z;
*z = temp;
};
if( *x > *y )
{
temp = *x;
*x = *y;
*y = temp;
};
return;
}; // _sort()
I get it, thank you. I had never thought about testing the return of the scanf, but it seems an excellent practice. Just a curiosity, the Return -1; serves to return to some point?
- scanf() test the return. Simple as that. It is very naive to let the program go without knowing if you read what you intended. And
scanf()
not written for what you’re doing: reading from the keyboard. scanf()
was written to read formatted input. See name: scanformatted input. The keyboard is free-form: 105 keys of freedom, or more.
- return -1, or anything else for you to know where your program left off, when you have a simple program and don’t want to be treating the possible 400 error conditions with 400 cute messages. You go back -1, -2, -3, 4000, 5000, anything. And when the program finishes you go there and see what the return code is and know where it came out. Laziness only.
"As much as I tried to put more or less than 3 values, the
system was either ready waiting for the remaining values or just
computed the 3 first"
maybe the more you used is not enough. : ) with 3 specifiers scanf()
can return -1, 0, 1, 2 or 3. -1 will indicate an error and will be difficult with the keyboard. If you pass more than 3 values in the input the rest will of course be in the input buffer available to the program. It will never return more than the number of specifiers because it would make no sense.
scanf() has a mission. In the program
int res = scanf("%f %f %f", &a, &b, &c);
Then there are 3 %f
and the function will consume the input until it reads this. Only it has rules. Spaces, TABS and newlines will be consumed silently. When reading what was requested the function returns. It is not possible to return more than 3.
Consider this code
printf("Entre com 3 valores [numeros reais] : ");
int res = scanf("%f %f %f", &a, &b, &c);
if (res != 3)
{
switch(res)
{
case 1: return -1;
case 2: return -2;
case 0: return -3;
default:
return -4; // so pode ser -1
} // switch()
}; // if()
So:
- if the program does not read anything will return -3
- if you read a value returns -1
- if read two values returns -2
- if wrong
scanf()
returns -1 and the switch()
will return -4. when error gives you can test the value of errorno
in the program and use perror()
to show the reason for the error, in a serious program. Here the only probable reason for error is file end, what happens if you hit control-Z on reading.
Anyway on Mac/Linux you test $? after running the program and have the error code.
Windows is more boring: on the console you test %ERRORLEVEL% but on Windows Terminal or Powershell is different... In PS you run as in Linux echo $?
but comes true if the last program finished OK and False gave error. Giving error means not returning zero. In C has the constant EXIT_SUCCESS
and sister EXIT_FAILURE
just reserved for that. It’s a silent convention.
And if it was wrong you can see in $LASTEXITCODE what was the return value. Don’t blame me. I also hated it.
a recursive _Sort()
Sort algorithms like Mergesort, Heapsort and Quicksort make more sense to be implemented via recursion. Anyway
void _sortR (float* x, float* y, float* z)
{
float temp;
if( *x > *y )
{
temp = *x;
*x = *y;
*y = temp;
_sortR( x,y,z );
};
if( *y > *z )
{
temp = *y;
*y = *z;
*z = temp;
_sortR( x,y,z );
};
if( *x > *y )
{
temp = *x;
*x = *y;
*y = temp;
_sortR( x,y,z );
};
return;
}; // _sort()
This _Sort() version is recursive if you wanted to see an example.
a scanf() test on windows
C:\src\ifdef>gcc -o tsort3 -Wall -std=c17 tsort3.c
C:\src\ifdef>tsort3
Entre com 3 valores [numeros reais] : 1 2 3
Em ordem crescente: 1.0 2.0 3.0
C:\src\ifdef>tsort3
Entre com 3 valores [numeros reais] : 3 2 1
Em ordem crescente: 1.0 2.0 3.0
C:\src\ifdef>tsort3
Entre com 3 valores [numeros reais] : ^Z
C:\src\ifdef>echo %ERRORLEVEL%
-4
C:\src\ifdef>tsort3
Entre com 3 valores [numeros reais] : 1x
C:\src\ifdef>echo %ERRORLEVEL%
-1
C:\src\ifdef>tsort3
Entre com 3 valores [numeros reais] : 1 2asda
C:\src\ifdef>echo %ERRORLEVEL%
-2
C:\src\ifdef>tsort3
Entre com 3 valores [numeros reais] : fim
C:\src\ifdef>echo %ERRORLEVEL%
-3
C:\src\ifdef>
Wow, thanks. I don’t know why, but I thought I could compare without the asterisks. On the recursive part I had tried to paste '&x, &y, &z' or put '*x, *y, *z' and took error from "incompatible type for argument", I think "Return" was missing, but this did not return what I expected, I will need to study a little more of recursion.
– Timafejn Yuri
power can, but will compare the address of pointers, not the values
– vmp
Regarding recursion, changing the last condition
if ((x < y) && (y < z)) {_sort (x, y, z);}
forif (*x < *y) { _sort(x,y,z);}
the algorithm works– Timafejn Yuri