passing values to function C [duplicate] - c

#include<stdio.h>
int main(){
int ret = 0;
ret = func(1.0,2.0);
printf("\n ret : %d \n",ret);
return 0;
}
func(int a,int b){
float m = 5.0;
float n = 6.0;
int sum = m + n;
printf("\n sum : %d \n",sum);
return a+b;
}
EDITED
sum : 11
ret : -877505847
why the float value passed to the integer throws a garbage value while the float value added and assigned to an integer inside the function gives the correct value 11 ?

You need to provide a declaration for func before calling it
int func(int a,int b);
int main() {
}
int func(int a,int b) {
// implementation
}
Your code presumably compiled with a warning something like warning: implicit declaration of function 'func'. If you'd fixed this warning, you'd also have fixed the error.
It'd be good practice to have the compiler warn you about as many potential problems as possible. You may also want to guard against the possibility of missing warnings by treating them as errors. You can do this by adding -Wall -Werror to your build command for gcc or /W4 /Wx for MSVC.
Note that the correct value is returned if you pass ints into func. At a guess, this may be because the calling code doesn't know that it needs to cast the arguments to int and passes float instead. func then either reads registers/stack locations that floats weren't copied to or receives the bit representations of float arguments and treats them as int. Either of these will result in incorrect values of a, b being received. You can check this yourself by adding a printf inside func to note the values of its arguments.

Related

After returning a float value from a method and trying to print it, the printed value is always wrong (although the method does works as intended)

I wrote a simple method to calculate an arithmetic mean like so:
float arithmetic_mean(int a[], int n)
{
float sum = 0;
int i;
for (i = 0; i < n; i++)
{
sum += a[i];
}
sum = sum / (float)n;
return sum;
}
I wanted to check it in main:
int main()
{
int a[] = { 1,3,5,1,6,7 };
float check = arithmetic_mean(a, 6);
printf("%f", check);
return 0;
}
even though the value the method returns is correct (=3.833333 as checked by printing it before returning it), when I try to print it in main I get 9 as the output.
I'm really new to C language and stuff like this always seems to happen with floats - I'll write a method that works and return a float - and the returned value would be something seemingly random. What am I missing here? What am I doing wrong?
The problem (which I can reproduce with MSVC) is that you are calling the arithmetic_mean function (from main) before you have defined it. Thus, the compiler uses a default definition of the function, which is that it returns an int type ... and the actual (float) value returned just happens to have a bit pattern that represents 9 when interpreted as an int.
You can leave the definition of the function where it is (after main) so long as you provide a forward declaration of the function, so that the compiler knows what the return type is:
float arithmetic_mean(int a[], int n); // Forward declaration of the function!
int main()
{
int a[] = { 1,3,5,1,6,7 };
float check = arithmetic_mean(a, 6);
printf("%f\n", check);
return 0;
}
// The actual DEFINITION (including the body) of the function can follow...
Turning on compiler warnings would have helped you spot this! For example, without the forward declaration, MSVC gives this:
warning C4013: 'arithmetic_mean' undefined; assuming extern returning
int

how to pass a condition as parameter to function in C?

I have created an array of function pointers to swap two variables.
pointer pointing to these functions namely: swap1, swap2. swap3 and swap4.
swap2 is swaping using pointer passed as arguments.
but while declaring the function pointer, only int and int are passed as arguments. after compiling this causes many warnings.
so do we have a better way of passing the argument, where we put condition in function call itself.
code is given below.
#include <stdio.h>
int swap1(int ,int );
int swap2(int* ,int* );
int swap3(int ,int );
int swap4(int, int);
int swap1(int a,int b)
{
int temp=a;
a=b;
b=temp;
printf("swapped with 3rd variable :%d, %d\n", a,b);
}
int swap2(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
printf("swapped with pointer :%d, %d\n", *a,*b);
}
int swap3(int a,int b)
{
a+=b;
b=a-b;
a-=b;
printf("swapped with 2 variable :%d, %d\n", a,b);
}
int swap4(int a,int b)
{
a=a^b;
b=a^b;
a=a^b;
printf("swapped with bitwise operation :%d, %d\n", a,b);
}
int main()
{
int ch;
int a=3;
int b=4;
printf("enter the option from 0 to 3\n");
scanf("%d",&ch);
int (*swap[4])(int, int) ={swap1,swap2,swap3,swap4};// function pointer
/*can we pass something like int(*swap[4]( condition statement for 'pointer to variable' or 'variable')*/
if (ch==1)// at '1' location, swap2 is called.
{
(*swap[ch])(&a,&b);//passing the addresses
}
else
{
(*swap[ch])(a,b);
}
return 0;
}
some warnings are as follows.
at line 36 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
Well yes. There are a number of problems with your code, but I'll focus on the ones to which the warnings you presented pertain. You declare swap as an array of four pointers to functions that accept two int arguments and return an int:
int (*swap[4])(int, int)
Your function swap2() is not such a function, so a pointer to it is not of the correct type to be a member of the array. Your compiler might do you a better favor by rejecting the code altogether instead of merely emitting warnings.
Having entered a pointer to swap2() into the array anyway, over the compiler's warnings, how do you suppose the program could call that function correctly via the pointer? The type of the pointer requires function arguments to be ints; your compiler again performs the dubious service of accepting your code with only warnings instead of rejecting it.
Since the arguments in fact provided are the correct type, it might actually work on systems and under conditions where the representations of int and int * are compatible. That is no excuse, however, for writing such code.
Because pointers and ints are unchanged by the default argument promotions, one alternative would be to omit the prototype from your array declaration:
int (*swap[4])() = {swap1,swap2,swap3,swap4};
That says that each pointer points to a function that returns int and accepts a fixed but unspecified number of arguments of unspecified types. At the point of the call, the actual arguments will be subject to the default argument promotions, but that is not a problem in this case. This option does prevent the compiler from performing type checking on the arguments, but in fact you cannot do this correctly otherwise.
Your compiler might still warn about this, or could be induced to warn about it with the right options, but the resulting code nevertheless conforms and does the right thing, in the sense that it calls the pointed-to functions with the correct arguments.
To deal with the warnings first: You declare an array of functions which take int parameters. This means that swap2 is incompatible with the type of element for the array you put it in. This will generate a diagnostic.
Furthermore, when you call one of the functions in the array, the same array declaration tells the compiler that the parameters need to be ints not pointers to int. You get two diagnostics here, one for each parameter.
To fix the above all your functions need to have compatible prototypes with the element type of the array. Should it be int or int*? This brings us to the other problem.
C function arguments are always pass by value. This means that the argument is copied from the variable onto the stack (or into the argument register depending on the calling convention and argument count - for the rest of this post, I'll assume arguments are placed on the stack for simplicity's sake). If it's a literal, the literal value is put on the stack. If the values on the stack are changed by the callee no attempt is made by the caller, after the function returns, to put the new values back in the variables. The arguments are simply thrown away.
Therefore, in C, if you want to do the equivalent of call by reference, you need to pass pointers to the variables you use as arguments as per swap2. All your functions and the array should therefore use int*. Obviously, that makes one of swap1 and swap2 redundant.
The correct array definition is
int (*swap[4])(int*, int*) = {swap1, swap2, swap3, swap4};
and the definition of each function should be modified to take int* parameters. I'd resist the temptation to use int (*swap[4])() simply because it circumvents type safety. You could easily forget the & in front of an int argument when the called function is expecting a pointer which could be disastrous - the best case scenario when you do that is a seg fault.
The others have done great work explaining what the problems are. You should definitely read them first.
I wanted to actually show you a working solution for that sort of problem.
Consider the following (working) simple program :
// main.c
#include <stdio.h>
void swap1(int* aPtr, int* bPtr) {
printf("swap1 has been called.\n");
int tmp = *aPtr;
*aPtr = *bPtr;
*bPtr = tmp;
}
void swap2(int* aPtr, int* bPtr) {
printf("swap2 has been called.\n");
*aPtr += *bPtr;
*bPtr = *aPtr - *bPtr;
*aPtr -= *bPtr;
}
int main() {
int a = 1, b = 2;
printf("a is now %d, and b is %d\n\n", a, b);
// Declare and set the function table
void (*swapTbl[2])(int*, int*) = {&swap1, &swap2};
// Ask for a choice
int choice;
printf("Which swap algorithm to use? (specify '1' or '2')\n>>> ");
scanf("%d", &choice);
printf("\n");
// Swap a and b using the right function
swapTbl[choice - 1](&a, &b);
// Print the values of a and b
printf("a is now %d, and b is %d\n\n", a, b);
return 0;
}
First of, if we try to compile and execute it:
$ gcc main.c && ./a.out
a is now 1, and b is 2
Which swap algorithm to use? (specify '1' or '2')
>>> 2
swap2 has been called.
a is now 2, and b is 1
As myself and others mentioned in answers and in the comments, your functions should all have the same prototype. That means, they must take the same arguments and return the same type. I assumed you actually wanted to make a and b change, so I opted for int*, int* arguments. See #JeremyP 's answer for an explanation of why.

Why do I get "clang: error: linker command failed with exit code 1"?

Doing K&R using Xcode, in the Functions section I entered the code for their example of the power function as follows.
#include <stdio.h>
int power(int m, int n);
int main()
{
int i;
for (i=0; 1<10; ++i)
printf("%d %d %d\n", i, power(2, i), power(-3, i));
return 0;
}
When I try to run it, the following error appears:
Undefined symbols for architecture x86_64:
"_power", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have read a lot of the answers to this question, but cannot see how it applies to my situation with such a little program. How can I fix this problem?
Why do I get "clang: error: linker command failed with exit code 1"?
You just declared the function. There is not any definition in the code. At the time of the linking process, the compiler (here Clang) cannot link power function to its definition, so the linker throws the error in this kind of situation. If you define
int power(int x, int y)
{
/* Do calculation */
}
Then the linker can link your declaration of power function to its definition, and you will not get any error.
For an integer number I have made a function:
#include <stdio.h>
int power(int base, int exp);
int main()
{
int i;
for (i=0; i<10; ++i)
printf("%d %d %d\n", i, power(2, i), power(-3, i));
return 0;
}
int power(int base, int exp)
{
int result = 1;
while (exp)
{
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
return result;
}
Compile this with gcc file.c.
You missed the definition of function int power (int base, int n) which is given after your main ends on the next page of the book.
When you declare prototype of a function you need to define what it should do you just declared the power function and never defined that, that's why you got error.
Include the following definition, your code will compile the way you wants it to be.
int power (int base, int n) {
int i, p;
p = 1;
for (i=1; i<=n; ++i)
p = p*base;
return p;
}
Pre-edit answer
Now this is not relevant, but useful
I think you want to use function pow() defined in math.h.
double pow(double a, double b)
The C library function pow(double a, double b) returns a raised to the power of b. This function returns a double value so to print that correct specifier will be "%lf".
In this case you just need to include header file
#include <math.h>
In your program.
There is no need to give function declaration int power(int m, int n);
The error you are having is due to giveing I as on of the parameter to pow()
because when you will compile your code (after including math.h and using pow() replacing i with any integer numbers will compile your code and will give proper output.
printf("%lf %lf %lf\n", i, pow(2, 3), pow(3, 2));
This will give you proper result but when you compile it with
for (i=0; i<10; ++i) {
printf("%lf %lf %lf\n", i, pow(2, i), pow(-3, i));
}
It throws same error so I think pow() takes only constants as input so it won't run in for loop.
And if you don't want to include math.h you can simply declare
extern double pow (double base, double exponent);
That will link correctly with the library code without using the math.h include file, here is an example.
int main() {
extern double pow (double base, double exponent);
printf("%lf", pow(8.0, 8.0));
return 0;
}
For more on pow() you can check man page on Linux i.e. man pow.
There is a standard library function which does just that...
#include <math.h>
double pow(double x, double y)
You have to link it explicitly because the default linker, that is ld invoked when no other options given, doesn't link with standard math library.
So you have to do it like...
gcc file.c -lm
You can define the power function
int power(int m, int n) {
// Implement the function body
}
And then your issue will get fixed.
You're getting an error, because there isn't any deceleration for the defined function. So add the deceleration as shown above.
First, you get the error because the compiler can not find the definition of the power function that you are using. Even if you write
int power(int m, int n);
There is an error because you are not defining the function. There is missing {} at the end of the definition and even if you are putting it at the end of the definition, you will get an error because you are not returning nothing for a int function. So, at least if you want to define a function, you have to proceed like this:
int power(int m, int n){return 0};
Then, you will be able to use your function power() in the main function. But, you are doing nothing in the power() function, so you will get nothing back of calling it. If you want to compute the power of a number, you can use the function pow() that is present in the cmath library. A straightforward way of doing it is something like this:
#include <stdio.h> // printf
#include <cmath> // pow()
#include <iostream> // cout
void main()
{
for (int i = 0; i < 10; i++)
std::cout << i << " " << pow(2, i) << " " << pow(-3, i) << std::endl;
}
I included the iostream to use a different way of printing out using the object cout defined in the std namespace. Note that the pow() function has some requirements for its definition, so be careful with the types you are using. You can take a look at pow for more details.
The function should be completed. I met the same question today only because I didn’t define function main in my code.

expected expression before double

Keeps saying that there is an expected expression before double int pt function
#include <stdio.h>
int pt (int a, int b)
{
int c, result;
c = (a * a) + (b + b);
result = double sqrt (double c);
return result;
}
int main (void)
{
int d, e, f;
int pt (int a, int b);
printf("type enter after input of the two legs");
scanf("%i", &d);
scanf("%i", &e);
f = pt (d,e);
printf("the hypotenuse is %i", f);
return 0;
}
Change
result = double sqrt (double c);
to
result = sqrt(c);
You don't have to cast c into a double when you pass it into the sqrt function because of implicit conversion. If you still wanted to do the cast, the correct way would be sqrt((double) c).
Also, #include <math.h> for use of the sqrt function.
Note: It's not required to cast the return type of sqrt to int (relevant since result is of type int) - however some compilers may give warnings about implicit conversion (Credit to #MattMcNabb). It can also be good practice to put the cast in to signal to other coders that the precision loss is intentional.
double sqrt (double c); is a function declaration. (It is also a function prototype). This is how you announce that a function exists, and what parameters it takes and what it returns. The word c here does not mean anything, it can be omitted.
When you want to call a function you do not repeat this info. You just give the function name, followed by a list of values, e.g. sqrt(c) .
In your code , sqrt has not been declared. Functions must be declared before they are called. It's not possible to simultaneously declare a function and call it; you have to declare it first.
(Historical note: this is true from C99 onwards; in C89 you could call an undeclared function, and the compiler would assume you wanted the function declared to return int ; this would cause undefined behaviour for any function that does not actually return int).
It is possible for you to provide your own declaration, so long as it matches the standard declaration:
double sqrt(double);
However it is a better idea to just use the standard declaration by going:
#include <math.h>
which works because the file math.h includes the line double sqrt(double); (or something equivalent).
Then you can write:
result = sqrt(c);
Note that you do not need to use any casts in relation to this function call. Since a function prototype exists, the compiler knows that even if you supply an int, it should convert that int to a double (which it knows how to do), and vice versa.
It is talking about the casting that you are doing?
your casting is complaining it should be like this:
your result is an integer, so you should be casting it to int..
but if you want to cast anything to double it should be as follow
result = (double)sqrt((double) c)
or another way is double(sqrt((double) c)
but if you want to cast it as int then
result = (int)sqrt((double) c)
or
result = int(sqrt((double) c))
hope this helps good luck

C language - calling functions without function prototype

I found here that function prototype is necessary before function call if the function is below function calling.
I checked this case in gcc compiler and it compile code without function prototype.
Example:
#include <stdio.h>
//int sum (int, int); -- it runs with this commented line
int main (void)
{
int total;
total = sum (2, 3);
printf ("Total is %d\n", total);
return 0;
}
int sum (int a, int b)
{
return a + b;
}
Could explain somebody this issue?
When you don't provide a function prototype before it is called, the compiler assumes that the function is defined somewhere which will be linked against its definition during the linking phase. The default return type is assumed to be int and nothing is assumed about the function parameter. This is called implicit declaration. This means that the assumed function signature here is
int sum();
Here, the empty parameter list means the function sum takes a fixed but unknown number of arguments all of which are of unknown types. It is different from the function declaration
int sum(void);
However, in C++, the above two declarations are exactly the same. If your function has a return type other than int, then the assumed function signature won't match and this will result in compile error. In fact, it's an error in C99 and C11. You should always provide function prototype before it is called.
It says on this page that: " You don't have to declare the function first, but if you don't, the C compiler will assume the function returns an int (even if the real function, defined later, doesn't)."
It is confirmed here.
As for arguments: "and nothing is assumed about its arguments."
I changed your code to #include
/* int sum (int, int); -- it runs with this commented line */
int
main (void)
{
int total;
total = sum (2, 3);
printf ("Total is %d\n", total);
return 0;
}
int
sum (int a, int b)
{
return a + b;
}
Then compile with:
gcc --std=c90 -ansi -pedantic node.c
Also i try with some standard but may be it's related to gcc version and C standard.

Resources