Sort three pointers without using selection sort - c

I'm new to C and am having a lot of trouble understanding how to utilize pointers in my code. I need to sort the addresses of three user-input integers in ascending order, using a separate sort function. I can't include any sort of selection sort or general-purpose sort, however.
EDIT: When I run the program, it gives me the addresses in descending order for some reason. I need to fix that.
Here's my code thus far:
#include <stdio.h>
#include <stdlib.h>
void sortThree(int * a, int * b, int * c);
int main(void)
{
int x, y, z;
printf("Please enter three variables: ");
scanf("%i %i %i",&x,&y,&z);
void sortThree(int * x, int * y, int * z);
printf("%u %u %u",&x, &y, &z);
return 0;
}
void sortThree(int * a, int * b, int * c)
{
int min, mid, max;
if (*a <= *b)
{
if (*a <= *c)
{
min = *a;
}
if (*b <= *c)
{
mid = *b;
max = *c;
}
else
{
mid = *c;
max = *b;
}
}
}
I'm sure it's something I'm overlooking or something but my brain just doesn't see it. Thanks in advance!

There are so many errors in this code it is hard to comment without re-writing it for you, and I won't. In addition to those mentioned above, you are using printf() to show integers by address instead of by value. You can't want to sort the addresses, or you would not have bothered to input any values. Also, why do you switch the format specifier bewteen int and unsigned int? It might not cause an error but it's plain sloppy.
In the sort function, you aren't even changing anything, you are throwing away the results on return. The reason it has given you the addresses in descending order, is because you haven't even sorted them, they are the order they were declared and pushed onto the stack. You are passing the pointers to printf() but telling it they are unsigned integers. The actual variable values are ignored.

Related

Function pointers and callbacks in c/c++

I was trying to remind how pointers worked in c and c++ and I found this very interesting video (Pointers in C/C++). In minute 3:14:00, he begins to talk about pointer functions and callbacks, and I ended a bit confused about the real application of them.
The example case he provides consists of a sorting algorithm that takes a function pointer as argument, which defines the comparison "rule" to follow (order from geater to smaller, order from smaller to greater, from greater to smaller given the absolute values...). He eventually ends with something like this:
#include<stdio.h>
int compare(int a, int b){
if(a > b) return -1;
return 1;
}
void MyBubbleSort(int A[], int n, int (*compare)(int,int)){
int i,j,temp;
for(i=0; i<n; i++){
for(j=0; j<n-1; j++){
if(compare(A[j], A[j+1]) > 0{
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
}
}
}
int main(){
int i, A[] = {3,2,1,5,6,4};
MyBubbleSort(A,6,compare);
for(i=0; i<6; i++) printf("%d ",A[i]);
}
When he wants to change the comparison rule, he changes the compare(int, int) content and that's all. My question is, why would he do that, instead of just having a separate function called compare(int, int) that just does the same as the one showed in the code snippet, and just call that function from within MyBubbleSort(int[], int). Wouldn't it just have the same behaviour? What are the benefits then? Are there any other interesting use cases?
Thank you very much for answers!
If I understand your question correctly, the main point is something that he mentions in the narration but does not include in the sample code: you could have several different comparison functions in your program, and use them at different times as appropriate, while still having just one MyBubbleSort function.
An example might look like:
int compare_increasing(int a, int b){
if(a > b) return -1;
return 1;
}
int compare_decreasing(int a, int b){
if(a < b) return -1;
return 1;
}
void MyBubbleSort(int A[], int n, int (*compare)(int,int));
}
int main(){
// ...
// sort in increasing order
MyBubbleSort(A,6,compare_increasing);
// sort in decreasing order
MyBubbleSort(A,6,compare_decreasing);
}
Calling a function by a pointer in this case makes the sorting function universal.
If you hardcode the comparison in that function it will work only for that condition.
C does not have lambda expressions and anonymous functions so the compare function has to be written separately and the pointer passed.

I want to return multiple values from function using pointers but it's returning one value

I want to return multiple values from user defined function but it's returning only one variable. Here's the code:
#include <stdio.h>
double sum_n_avg(double, double, double, double*, double*);
int main()
{
double n1, n2, n3, sump, avgp;
printf("enter numbers:");
scanf("%lf%lf%lf", &n1, &n2, &n3);
printf("sum and average is %lf",sum_n_avg(n1, n2, n3, &sump, &avgp));
return 0;
}
double sum_n_avg(double n1, double n2, double n3, double *sump, double *avgp)
{
*sump = n1 + n2 + n3;
*avgp = *sump / 3;
}
your code having undefined behavior as sum_n_avg() doesn't return anything but printf("sum and average is %lf", ??); expects one value.
But you are expecting something like this
void sum_n_avg(double n1,double n2,double n3,double *sump,double *avgp) {
*sump=n1+n2+n3;
*avgp=*sump/3;
}
int main() {
double n1,n2,n3,sump,avgp;
printf("enter numbers:");
scanf("%lf%lf%lf",&n1,&n2,&n3);
sum_n_avg(n1,n2,n3, &sump,&avgp); /* call like this */
printf("sum and average is %lf and %lf\n",sump,avgp);/*sump and avgp gets updated from sum_n_avg() function */
return 0;
}
You can only return one thing from a function. There are several ways around your specific problem though.
First you can declare two functions, each of which does it's own separate task. This is the recommended design pattern, as it makes your code more logical to the reader.
For this double function, I will take in three doubles, since that is how you have yours set up.
double sum(double a, double b, double c) {
return (a + b + c);
}
To call this function from main, you would say:
double s = sum(n1,n2,n3);
For your average function, all you then have to do is get the result of the sum function and divide by the number of elements you have, in this case three, of course.
double average(double sum, double n) {
return (sum / n);
}
Again, to use this function from main, you could do something like this:
double avg = average(s, 3);
Your functions should ideally be more generic to be more useful, but this is a pretty contrived toy example, so I think you get the point.
Now, if you really were absolutely set on returning multiple values from a single function, there are ways to do that as well, although again, recommended programming practices dictate this is a pretty lame idea, but I think you should still know how it would work.
You could declare a struct:
struct descriptiveStatistics {
double sum;
double avg;
};
You should keep in mind that you have to instantiate this struct in order to be able to use it, which we would do from main like this:
int main()
{
double n1, n2, n3;
struct descriptiveStatistics stats;
...
Now to actually return both the average and the sum from a single function, we would combine our two previous functions, like this:
struct descriptiveStatistics analyzeData(double a, double b, double c) {
struct descriptiveStatistics results;
results.sum = a + b + c;
results.avg = sum / 3;
return results;
}
In this basic example, we're just returning a copy of the struct descriptiveStatistics results struct for simplicity's sake. We could also return a pointer, like this:
struct descriptiveStatistics* analyzeData(double a, double b, double c) {
struct descriptiveStatistics* results = malloc(sizeof(struct descriptiveStatistics));
// Remember to check for NULL in case there was an error during dynamic memory allocation
if (results == NULL) { /** Handle error ... */ }
results->sum = a + b + c;
results->avg = sum / 3;
return results;
}
Then, from main you would just create the struct and set it like this:
int main()
{
struct descriptiveStatistics* stats = analyzeData(n1,n2,n3);
...
I purposefully didn't use a typedef when I declared the struct because I wanted to deal with one thing at a time, but it might be helpful -and a relief- to know that you don't have to keep typing this super long name over and over. You could do this in the declaration:
typedef struct descriptiveStatistics {
double sum;
double avg;
} *Statistics;
This is my preferred way of using typedef. Now, rather than having to type struct descriptiveStatistics* every time, we can now just use Statistics. Note that I made it a pointer to struct descriptiveStatistics, but you could also do typedef struct descriptiveStatistics { ... } Statistics; and this will work exactly the same, except it won't be a pointer obviously.
You can return two values via pointer-to-output-parameters, as you implemented.
To clean up your code:
do not declare a return value if you do not return anything:
double sum_n_avg( -> void sum_n_avg(, in prototype and definition.
call the function before printing, to get the values in the pointed-to variables:
sum_n_avg(n1,n2,n3, &sump,&avgp); printf(
give the variables as values to printf:
printf("sum is %lf and average is %lf", sump, avgp);
Just noticed that Steve Summit has had the basic know how in his earlier comment. I did not use it (got distracted by missing return), but still
credits to him.

C - Function which takes 2 floats and returns their difference after the block using pointers

I'm trying to write a function which takes two generic floats (make it 'a' and 'b') and returns their difference assigned to the variables, so a=a-b and b=b-a.
It should print the values with 2 decimal places and it must work after I exit the block... What is wrong with my code?
#include <stdio.h>
float diff_abs (float *a, float *b) {
*a= *a-*b;
*b= *b-*a;
}
int main(void) {
float c, d;
scanf("%f", &c);
scanf("%f", &d);
printf("%.2f\n%.2f", diff_abs(&c, &d));
return 0;
}
I would appreciate your suggestions, thank you.
First, you are changing a value then using it to the next calculation so simplify change your function to:
void diff_abs (float *a, float *b) {
*a= *a-*b;
*b = -*a
}
Second, since you can't return multiple variables in a C function, one of the solution is to use void returning function but change variables while using pointers (like you're somehow doing)
Finally, since your function returns void you can't use it as floats in the printf function so just use c and d
like this:
printf("%.2f\n%.2f",c,d);
of course don't forget to call:
diff_abs(&c, &d)
before trying to print
you can refer to this topic for returning multiple variables in C

Procedure and pointers C

im trying to make a procedure to find a maximum numbers out of 3, which i will assign later to another variable pointer in main program
int Maximum (int *a, int *b, int *c)
{
if (*a>=*b)
{
if (*a<*c)
{*a=*c;}
}
else
{
*a=*b;
if (*a<*c)
{*a=*c;}
}
return a;
}
compiler giving me error that "expected 'int*' but argument is of type 'int' "
so i changes that part to
int * Maximum (int *a, int *b, int *c)
but error sentence still same ?
First off, your original function is designed to return an int and you're returning a, which is an int pointer. Either return the int (*a), or change the function so it returns an int *.
However, based on your actual message:
expected 'int*' but argument is of type 'int'
and the fact you state you've made that change and still have the problem (note the word "argument" in the message), this indicates that the problem lies not with the return value but with the way you're passing the arguments to it.
You are actually passing int where the function expects int * and that's probably caused by you using something like:
int one = 3;
int two = 7;
int three = 42;
int maxOfThree = Maximum (one, two, three);
If you wanted to pass pointers to the function, you would need:
Maximum (&one, &two, &three);
(passing the pointers to the variables, not the values of them).
A better solution (more readable and with correct data types both going in to, and coming out of, the function) to your problem would probably be:
int Maximum (int a, int b, int c) {
if ((a > b) && (a > c))
return a;
if (b > c)
return b;
return c;
}

Passing a multidimensional array of variable size

I'm trying to understand what "best practice" (or really any practice) is for passing a multidimensional array to a function in c is. Certainly this depends on the application, so lets consider writing a function to print a 2D array of variable size. In particular, I'm interested in how one would write the function printArry(__, int a, int b) in the following code. I have omitted the first parameter as I'm not exactly sure what that should be.
void printArry(_____, int a, int b){
/* what goes here? */
}
int main(int argc, char** argv){
int a1=5;
int b1=6;
int a2=7;
int a2=8;
int arry1[a1][b1];
int arry2[a2][b2];
/* set values in arrays */
printArry(arry1, a1, b1);
printArry(arry2, a2, b2);
}
The easiest way is (for C99 and later)
void printArry(int a, int b, int arr[a][b]){
/* what goes here? */
}
But, there are other ways around
void printArry(int a, int b, int arr[][b]){
/* what goes here? */
}
or
void printArry(int a, int b, int (*arr)[b]){
/* what goes here? */
}
Compiler will adjust the first two to the third syntax. So, semantically all three are identical.
And a little bit confusing which will work only as function prototype:
void printArry(int a, int b, int arr[*][*]);
This is not really an answer, but extended comment to the OP's comment question, "well you can pass the array without knowing the number of rows with this, but then how will you know when to stop printing rows?"
Answer: generally, you can't, without passing the array size too. Look at this 1-D example, which breaks the array size.
#include <stdio.h>
int procarr(int array[16], int index)
{
return array[index];
}
int main (void)
{
int arr[16] = {0};
printf("%d\n", procarr(arr, 100));
return 0;
}
Program output (although all elements initialised to 0):
768
That was undefined behaviour and there was no compiler warning. C does not provide any array overrun protection, except for array definition initialisers (although such initialisers can define the array length). You have to pass the array size too, as in
#include <stdio.h>
int procarr(int array[16], size_t index, size_t size)
{
if (index < size)
return array[index];
return -1; // or other action / flag
}
int main (void)
{
int arr[16] = {0};
printf("%d\n", procarr(arr, 100, sizeof arr / sizeof arr[0]));
return 0;
}
Program output:
-1

Resources