How to read variadic function parameters? - c

This is my code:
#include <stdio.h>
void add(int num, ...);
int main(void)
{
int a=100, b=200, c=300;
add(1, a);
add(2, a, b);
add(3, a, b, c);
return 0;
}
void add(int num, ...)
{
int *p=NULL;
p=&num+1;
printf("%x \n", p);
if(num==1)
{
printf("%d \n", p[0]);
printf("num is: %d \n", num);
}
else if (num==2)
{
printf("%d \n", p[0]+p[1]);
printf("num is: %d \n", num);
}
else
{
printf("%d \n", p[0]+p[1]+p[2]);
printf("num is: %d \n", num);
}
}
From my understanding, p initially points to a, which is 10. Thus, it should print 10, 30, 60, respectively. Nonetheless, it prints
6786db50
1736891264
num is: 1
6786db50
1736924031
num is: 2
6786db50
1867401241
num is: 3
Is p pointing to a wrong address? How can I correctly read the arguments passed as ...?

That's not how you use variadic function calls, you need to use the va_* function calls to extract the parameters.
See http://unixhelp.ed.ac.uk/CGI/man-cgi?stdarg+3 or http://en.wikipedia.org/wiki/Variadic_function#Variadic_functions_in_C.2C_Objective-C.2C_C.2B.2B.2C_and_D

Your particular example may or may not work (Works as you expected on my system). You do p=&num+1; to access the next element. This holds good under the assumption that the stack is ascending which may not be the case with your architecture. And on many systems, variables upto some limit, are passed on registers than on stack! So your assumption goes wrong totally. Also note the variables can be pushed on to the stack either from left to right or the other way. It is unspecified by the standard.
Hence you shouldn't work on assumptions and instead use functions designed for this particular use.

Related

Function returns different numbers when called in another function

\
I've created a practice project for my test and I can't seem to get around this problem. I need a function that grabs the input and when called in another function, the input will be used to solve a problem.
\
here is my code
#include <stdio.h>
int get()
{
int one,two,three,four;
scanf("%d %d %d %d", &one, &two, &three, &four);
return one,two,three,four;
}
int add()
{
int one,two,three,four;
int result1, result2, result3;
get();
result1 = one + two;
if (result1 == three)
{
result2 = four - three;
result3 = result2 + four;
printf("Added %d, 5th number is %d", result2, result3);
}
else
{
printf("error, %d %d %d %d", one, two, three, four);
}
}
int main()
{
add();
return 0;
}
When I put the scanf statement inside the function, it works. But when I use the function to get the input, I get different numbers
In the return statement of the function get
return one,two,three,four;
there is an expression with the comma operator. Its value is the value of the last operand. That is the function returns the value of the variable four.
And moreover the returned value is not used in the caller. So you are dealing with uninitialized variables within the function add.
If you need to return four values then return them trough parameters by reference. For example
void get( int *one, int *two, int *three, int *four;)
{
scanf("%d %d %d %d", one, two, three, four);
}
and call the function like
get( &one, &two, &three, &four );
Or the function can return an integer that will signal whether the input was successful as for example
int get( int *one, int *two, int *three, int *four;)
{
return scanf("%d %d %d %d", one, two, three, four) == 4;
}
You can check the return value in the function add before performing calculations.
Pay attention to that the function add returns nothing. So declared its return type as void.
void add( void );
In the function get() the variables one,two,three,four are stored on the stack and are not available outsite of this function.
You can return only one value with get()
You have to store the return value to the specific variable result1= get()
If you want return more information at once, you should work with struct

Unexpected value by using printf (Call by reference in C)

#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;
}

Too few arguments to call

My teacher isn't willing to help me with my error so I don't know where else to go. On line 19, addition();, the error says that there are too few arguments in the function call and I'm not sure why this is. I am a beginner programmer, but I have called functions before so I'm not sure why I am getting a problem now.
#include <stdio.h>
int addition(int *change);
int main(void)
{
int num = 10;
printf("Name \t Address \t Value\n");
printf("%s \t %p \t %d\n", "num", &num, num);
int *change = &num;
printf("Change: %p\n", change);
*change = 100;
printf("The value of num is %d \n", num);
printf("The value of change is %d \n", *change);
addition();
return 0;
}
int addition(int *change)
{
int input;
int result = input + *change;
printf("Input a value ");
scanf("%d", &input);
printf("The result will be change (%d) + input (%d)\n", *change, input);
printf("Result: %d", result);
return 0;
}
Perhaps this would be better suited to a comment, but I lack the required reputation to post comments...
When you're calling a function, you often have to supply some information. If I walked up to you and commanded "Add!" you might reply "what should I add?" This is essentially what your error message is telling you. You're issuing a command, but you're not giving it enough information to complete that command.
You can find what additional information is required by a function by glancing at its declaration. In this case, your function declaration is:
addition(int *change)
meaning that, in order to function properly, the function requires a pointer to an integer (int *). Every time you call the addition function, you have to supply this argument so that the function knows the number to which it is expected to add.

UVa Online Judge ANSI C Runtime Error with scanf but Accepted with gets combined with sscanf

I will omit the whole code but these tests so far can be quite disturbing:
This get Accepted with ANSI C, C++ and C++ 11
#include <stdio.h>
#include <stdlib.h>
int main()
{
int p, q, r, s, t, u;
char* str = malloc(1000);
while(gets(str) != NULL) {
sscanf(str, "%d %d %d %d %d %d", &p, &q, &r, &s, &t, &u);
printf("%d %d %d %d %d %d\n", p, q, r, s, t, u);
}
}
The disturbing fact comes now, this code get Runtime Error in ANSI C but Accepted in C++ and C++ 11:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int p, q, r, s, t, u;
//== 6 instead of != EOF also gives me a runtime error
while(scanf("%d %d %d %d %d %d", &p, &q, &r, &s, &t, &u) != EOF) {
printf("%d %d %d %d %d %d\n", p, q, r, s, t, u);
}
}
You forgot to return 0; - in C this means that main() returns a garbage status to the shell. In C++ omitting the return 0; is allowed, and a default status of 0 (== EXIT_SUCCESS) will be returned. In C however both of your programs will return an undefined status. In the first case you happen to get lucky and 0 is returned. In the second case something other than 0 is being returned (probably -1). Try and get into the habit of always returning a valid status from main regardless of whether you're working with C or C++.
See this excellent question and answer for further details.
Note also that compiling with warnings enabled (e.g. gcc -Wall ...) would have alerted you to this mistake immediately and saved you some time.

Please, can you help me with this recursive function?

#include <stdio.h>
int fun (int x)
{
if (x<1)
return(1);
else
printf("%d %d \n", x, fun(x-1));
}
int main()
{ int x,y;
x = 5;
y = fun(x);
printf("\n x = %d f(x) = %d \n", x, y);
return 0;
}
This program contains a recursive function that count some numbers. There is something in the output I cannot understand.
There is a screenshot of the output at the following link:
https://onedrive.live.com/redir?resid=BE4862D617298D2C!886&authkey=!AA03bF8dQ5W4S9Y&v=3&ithint=photo%2cpng
Why the right column (red circuled) is as shown? I thought that this column will be all ones instead of that.
Because the function fun didn't have a return value when x >= 1.
And the 5 is the return value of printf("%d %d \n", x, fun(x-1)); because it has output 5 characters.
You are not returning anything if x>=1, causing undefined behaviour when the execution reaches the end of the function. That means the value could be anything, you got 5 by chance.
6.9.1. p12:
If the } that terminates a function is reached, and the value of the function call is used by
the caller, the behavior is undefined.
The return value is used in your example.
int fun(int x)
{
if (x<1)
return(1);
else
printf("%d %d \n", x, fun(x-1));
return x ;//just return something
}
You probably want to return something relevant to what you function does.

Resources