I need to write a function that gets num1, num2 and num3 as parameters. Once the function is done running, the parameters(num1, num2 and num3) sent to the main function should change so that num1 contains the smallest value, num2 contains the second biggest value and num3 the biggest value. I also need to write a swap function and use it.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void SmallBig(int* num1, int* num2, int* num3);
void swap(int* x, int* y);
void main()
{
int *num1, *num2, *num3;
*num1 = 1;
*num2 = 69;
*num3 = 22;
printf("%d %d %d\n", *num1, *num2, *num3);
SmallBig(*num1, *num2, *num3);
printf("%d %d %d\n", num1, num2, num3);
system("PAUSE");
}
void SmallBig(int* num1, int* num2, int* num3)
{
if (*num1 > *num3 && *num2 > *num3 && *num1 > *num2)
{
swap(num1, num3);
swap(num2, num2);
swap(num3, num1);
}
}
void swap(int* x, int* y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
These are the errors I get:
Warning 1 warning C4047: 'function' : 'int *' differs in levels of indirection from 'int'
Warning 2 warning C4024: 'SmallBig' : different types for formal and actual parameter 1
Warning 3 warning C4024: 'SmallBig' : different types for formal and actual parameter 2
Warning 4 warning C4024: 'SmallBig' : different types for formal and actual parameter 3
Error 5 error C4700: uninitialized local variable 'num1' used
Error 6 error C4700: uninitialized local variable 'num2' used
Error 7 error C4700: uninitialized local variable 'num3' used
Please help me fix the program!
Thank you. - Amnon.
The errors and problems
About your errors:
int *num1, *num2, *num3; // you define 3 pointers to int but let them unitinialised !
*num1 = 1; // you write something to the poinded adress, which might be random !!
*num2 = 69;
*num3 = 22;
As you use the pointers without initializing them (you only initialize the values that are pointed to), you get this error message
Then your second printf() prints the pointers and not the pointed values.
And finally, SmallBig() will work only in a small number of cases !
Solution
Use integers in main(), not pointers:
int num1, num2, num3;
num1 = 1;
num2 = 69;
num3 = 22;
printf("%d %d %d\n", num1, num2, num3);
SmallBig(&num1, &num2, &num3); // use the address
printf("%d %d %d\n", num1, num2, num3);
I almost forgot your SmallBig() function ! There, continue to use pointers as you did. But you have to foresee more cases:
if (*num1 > *num3)
swap (num1, num3);
if (*num1 > *num2)
swap (num1, num2);
if (*num2 > *num3)
swap(num2, num3);
The first problem you have is here
SmallBig(*num1, *num2, *num3);
You are passing the deferenced pointers as arguments - these have type int not int*. Your SmallBig function is expecting pointers so call it as such
SmallBig(num1, num2, num3);
Your code should at least now compile with this change.
The second main problem is that you are writing values to uninitialised memory when you do this
int *num1, *num2, *num3;
*num1 = 1;
*num2 = 69;
*num3 = 22;
Writing to uninitialised memory is undefined behaviour and at best will result in a segfault. A safer approach would be
int num1,num2,num3;
num1 = 1;
num2 = 69;
num3 = 22;
and then pass the addresses of these int variables to the functions expecting int* arguments. If you don't like this way you will need to dynamically allocate your pointers. You cannot write to what is pointed at by an uninitiliased pointer without expecting trouble.
Finally, this line
swap(num2, num2);
does nothing useful
Related
#include <stdio.h>
int main()
{
int num1;
int *p;
p=&num1;
printf("Give a value\n");
scanf("%d", &num1);
printf("\n%d", num1);
f2(&num1);
printf("%d", *p);
return 0;
}
void f2(int *p)
{
*p *= *p;
}
A call by reference program just to return the square of a value
Well, the problem is that if I do not use printf the expected output is correct (e.g. 2*2=4)
However, if I include:
printf("\n%d", num1);
and run the programm I will take a non expected value (e.g. 2*2=24)
These two calls of printf result of outputting two values in the same line without a space.
printf("\n%d", num1);
f2(&num1);
printf("%d", *p);
If you want to make the output less confusing then for example write
printf("\n%d", num1);
f2(&num1);
printf("\n%d\n", *p);
There are two problems in your code.
You need to declare void f2(int* p) before using it. Depending on your platform you might get away with it. But a sane compiler should give you at least a warning (which should be considered as an error).
Sloppy format strings in your printfs make the output look wrong.
Try this:
#include <stdio.h>
void f2(int* p); // you need to declare this, otherwise you'll get a
// warning you should always conside as an error
int main()
{
int num1;
int* p;
p = &num1;
printf("Give a value\n");
scanf("%d", &num1);
printf("\nnum1 = %d\n", num1); // format string more explicit
f2(&num1); // warnig here if f2 is not declared as above
printf("*p = %d\n", *p); // format string more explicit
return 0;
}
void f2(int* p)
{
*p *= *p;
}
There are several problems with this code.
You need to either:
a. declare a prototype for f2. You can do this by putting the following code before your main
void f2(int *p);
b. put the entire f2 function before main (and this is the route that I'd probably choose - but questions of style are the cause of countless pointless wars.
The output is unclear. By not putting \n in your printf statement you're running the output of the two print statements together. Use this instead:
printf("\n%d\n", num1);
Pretty printing greatly improves readability. And don't be afraid of giving functions meaningful names.
On balance, I think I'd write your code like so:
#include <stdio.h>
void square(int *p) {
*p *= *p;
}
int main(int argc, char *argv[]) {
int num1;
int *p;
p = &num1;
printf("Give a value: ");
scanf("%d", &num1);
printf("\n%d squared is equal to: ", num1);
square(&num1);
printf("%d\n", *p);
return 0;
}
#include <stdio.h>
#include <math.h>
void f2 (int *p)
{
*p = pow(*p, 2); // equal with *p *= *p;
}
int main ()
{
int num1;
int *p; // p is pointer variable that points to num1
// type of num1 and p must be the same (int).
p = &num1; // p is address of num1
printf ("Give a value: ");
scanf ("%d", p); // p is address of num1
printf ("\nnum1 before: %d", *p); // *p is num1 (content of p)
f2 (p);
printf ("\nnum1 after: %d", *p); // missing \n in here
return 0;
}
#include <stdio.h>
void gcdFinder(int num1, int num2, int *result);
int main()
{
int n1, n2, result;
printf("Enter 2 numbers: \n");
scanf("%d %d", &n1, &n2);
gcdFinder(n1, n2, &result);
printf("rGcd2(): %d\n", result);
return 0;
}
void gcdFinder(int num1, int num2, int *result)
{
printf("Initial : %d %d \n",num1,num2);
*result=num1;
if(num2 ==0 ){
return;
}else{
gcdFinder(num2,(num1%num2),&result);
}
}
I am trying to find the GCD the 2 inputs and storing the result into the result variable. However my code does not seem to work as it only stores one time.
As the output suggest my final value for num1 should be 1 however it is not stored and it remains as 4.
In the function gcdFinder change
gcdFinder(num2,(num1%num2),&result);
to
gcdFinder(num2,(num1%num2), result);
^
No & as result is already a pointer here
Notice:
In main it's correct to use &result because result in main is an int
I am trying to make a program that scans 3 ints and then passes them through a function that sort them by this way- the biggest number will be at 'num3', the second will be at 'num2' and the lowest one will be at 'num1' but for some reason the program crashes when it gets to the sort function.
#include <stdio.h>
#include <stdlib.h>
void swap(int* a, int* b);
void changer(int* num1, int* num2, int* num3);
int main()
{
int num1 = 0;
int num2 = 0;
int num3 = 0;
printf("Please enter your value for 'num1': ");
scanf("%d", &num1);
getchar();
printf("Please enter your value for 'num2': ");
scanf("%d", &num2);
getchar();
printf("Please enter your value for 'num3': ");
scanf("%d", &num3);
printf("\nYour nums before- \n");
printf("num1 == %d\n", num1);
printf("num2 == %d\n", num2);
printf("num3 == %d\n", num3);
changer(&num1, &num2, &num3);
printf("\nYour nums after- \n");
printf("num1 == %d\n", num1);
printf("num2 == %d\n", num2);
printf("num3 == %d\n", num3);
system("PAUSE");
return 0;
}
void changer(int* num1, int* num2, int* num3)
{
if (*num1 > *num3)
{
swap(*num3, *num1);
}
else if (*num1 > *num2)
{
swap(*num1, *num2);
}
if (*num2 > *num3)
{
swap(*num3, *num2);
}
}
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
You should not dereference the pointers when you pass them to swap() since it takes int * and you would be passing int thus causing undefined behavior and in your case a crash. The compiler should warn about incompatible parameters.
Change every occurrence of
swap(*num1, *num2);
/* ^ ^ remove these */
with
swap(num1, num2);
swap(int*, int*) expects the integer pointer to be passed in, assume the value of num1 = 0 and num2 = 2 and when you pass these values to swap(), by dereferencing you are invoking like this swap(0, 2) or on 32 bit system
swap(0x00000000, 0x00000002)
Inside swap(int* a, int* b) you dereference the memory location 0x00000000 (not the memory pointed to by a) at the line,
int temp = *a;
and then you dereference 0x00000002 b at this line and trying to assign it to 0x00000000 (by dereferencing *a)
*a = *b;
You are generating
Memory access violation condition.
which is causing the crash. Summarizing, please do not ignore compiler warnings. Compiler raises warning on the line where you are making swap() calls.
'int *' differs in levels of indirection from 'int'
Both functions take integer pointers (i.e., memory addresses of integers) as arguments. So, the values of the arguments a, b, num1, num2, and num3 must ALWAYS be memory addresses of integers. In the function changer, values of the variables num1, num2, and num3 are ALREADY memory addresses. When you write *num1, value of *num1 is integer but not the memory address of an integer. So, you need to call the function swap as follows:
swap(num3, num1);
swap(num1, num2);
swap(num3, num2);
So I made a function that returns a value which is the connection (sum) of 2 numbers that the user gives. But everytime I enter these 2 numbers, the result is somehow always 0.
float connection(int num1, int num2, float result)
{
result= num1 + num2;
return (result);
}
int main()
{
int num1= 0;
int num2= 0;
float result= 0.0;
printf("\nChoose the first number you'd like to connect: ");
scanf("%d", &num1);
getchar();
printf("choose the second number you'd like to connect: ");
scanf("%d", &num2);
connection(num1, num2, result);
printf("The result is: %f", result);
}
The problem here is (I believe) that you expect the argument result you pass to the function to change value. That's not how C works, instead all arguments are passed by value and the variable result inside the called function is a local variable which has no connection to the result variable in the calling function. Changing one variable will not affect the other.
Instead use the value the function returns:
result = connection(num1, num2, result);
Of course, this means passing result as an argument is totally meaningless, and you don't even need it in the function:
int connection(int num1, int num2)
{
return num1 + num2;
}
Also note that I changed the return-type, as adding two integers will never result in a floating-point number.
On a side-note to modify the argument means you have to pass it by reference, which is not supported by C. It can be emulated though, by using pointers:
void connection(int num1, int num2, int *result)
{
*result = num1 + num2;
}
Then call it as
int result;
connection(num1, num2, &result);
You are mixing up two possibilities: returning a value and changing a variable by passing it to a method as a reference.
This is how to return a value (in this case, you don't need the result parameter):
float connection(int num1, int num2)
{
float result= num1 + num2;
return result;
}
...
result = connection(num1, num2);
This is how to pass a variable as a reference (in this case you don't need a return value):
void connection(int num1, int num2, float *result)
{
*result= num1 + num2;
}
...
connection(num1, num2, &result);
I think forgot to assign your result back to your variable:
connection(num1, num2, result); // returned value is missed
result = connection(num1, num2, result); // returned value saved
If, instead, you want your function to modify the variable, C is passed by value so you need some pointers:
void connection(int num1, int num2, float *result)
{
*result = num1 + num2;
}
connection(num1, num2, &result);
Simply make your function call pass by reference
#include<stdio.h>
float connection(int *num1, int *num2, float *result)
{
*result= *num1 + *num2;
return (*result);
}
int main()
{
int num1= 0;
int num2= 0;
float result= 0.0;
printf("\nChoose the first number you'd like to connect: ");
scanf("%d", &num1);
getchar();
printf("choose the second number you'd like to connect: ");
scanf("%d", &num2);
connection(&num1, &num2, &result); //Function Called by reference
printf("The result is: %f", result);
}
For further details on function calls Read It
When I run the following code, I always get a floating-point exception. How can I fix it?
#include <stdio.h>
//Global Variables
int num, denom, num1, denom1;
void simplify(int *numerator, int *denominator);
int main () {
//Prompt User as to what program is
printf("Fraction Simplifier\n");
printf("===================\n");
//Ask User for Numerator and Denominator
printf("Numerator: ");
scanf("%d", &num);
printf("Denominator: ");
scanf("%d", &denom);
//Call Function
simplify(&num1, &denom1);
//Display final output
printf("%d / %d = %d / %d", num, denom, num1, denom1);
return 0;
}
//Simplify function
void simplify(int *numerator, int *denominator)
{
num = num1;
denom = denom1;
num1 = num1 / num1;
denom1 = denom1 / num1;
num1 = *numerator;
denom1 = *denominator;
}
It looks as if num1 is never initialized. It will be zero, which will result in a division by zero.
Your simplify function is flawed. Here's what it means when you are calling simplify:
call simplify, passing the address of num1 and denom1
And here's what your code inside of simplify means:
num = num1; /* Assign the value of num1 to num, meaning set num to 0. */
denom = denom1; /* Assign the value of denom1 to denom, meaning set denom to 0. */
num1 = num1 / num1; /* Divide num1 (which is 0) by num1 (which is 0). Error! */
You can simplify your program and make it easier to understand by eliminating your global variables. This will also help you to correct your errors. Here's a rewrite:
#include <stdio.h>
void simplify(int numerator, int denominator, int* newNumerator, int* newDenominator);
int main () {
int num, denom, num1, denom1;
/* Do your input code */
//Call Function
simplify(num, denom, &num1, &denom1);
//Display final output
printf("%d / %d = %d / %d", num, denom, num1, denom1);
return 0;
}
//Simplify function
void simplify(int numerator, int denominator, int* newNumerator, int* newDenominator)
{
int simplifiedNumerator;
int simplifiedDenominator;
/* Calculate your results.. left out your original code, which calculates incorrectly */
/* You will refer to the ints numerator and denominator */
/* Assign your results */
*newNumerator = simplifiedNumerator;
*newDenominator = simplifiedDenominator;
}
Notice that simplify now has four parameters. The first two are the values you want to use in the calculation (we don't need pointers), and the pointers are only used to assign the results to the addresses passed in.