views:

247

answers:

5

I am practice the function in c and come across to the program ....

#include<stdio.h>

int main()
{
    float a=15.5;
    char ch ='C';
    printit(a,ch);
    return 0;
}

printit(a,ch)
{
    printf("%f\n%c",a,ch);
}

I want to know that why the above program compile and not give the error as i understood so for is ...

  1. The function in c must be declared with the specific prototype (but this program does not contain the prototype)

  2. why the program give the output 'x'for the char variable ?

  3. can the function in c are capable of accepting the value without being declared about type in parameters like what has done in the function declaration ?

A: 
  1. When you call printit() from main, main needs to know about printit. One way to fix this is to define printit above main.
  2. The printf should print "15.5", then a newline, then "C."
  3. I'm confused about the question. The declaration for printit() should be void printit(float a, char ch);

    void printit(float a, char ch) {
        printf("%f\n%c",a,ch);

    }

    int main()
    {
        float a=15.5;
        char ch ='C';
        printit(a,ch);
        return 0;
    }

WhirlWind
"I'm confused about the question. Functions need to have parameters defined." No, they don't in C. C's default to int rule means that `printit` inherently takes ints.
Billy ONeal
You're right. I'll fix it. Seems like bad practice though...
WhirlWind
A: 

That code should almost definitely read:

#include <stdio.h>

void printit(float a, char ch);

int main()
{
    float a=15.5;
    char ch ='C';
    printit(a,ch);
    return 0;
}

void printit(float a, char ch)
{
    printf("%f\n%c\n",a,ch);
}

If you want to write it neatly. However, to address the above:

1) You should include a prototype, yes. However, as you're only compiling one unit (.c file) the compiler can pretty easily work out where your function is and therefore what you meant. I get this:

test.c:11: warning: conflicting types for ‘printit’
test.c:7: note: previous implicit declaration of ‘printit’ was here

I highly recommend compiling using -Wall -Werror -pedantic to convert warnings like this to errors and abort compilation, forcing you to write correct code and so reducing bugs later on.

2) I get 15.5 then a C on a new-line. I'm not sure where the Z is coming from.

3) You don't have to specify types - however, if you don't, you won't benefit from the compiler warning you if the types are incompatible. One really common case of this is in passing data to assembly. It isn't strictly needed, but it is probably a violation of Standard C and is definitely not best practice.

Ninefingers
+2  A: 
  1. In C, if you don't define a function before using it, the compiler infers an implicit definition
  2. If you don't specify a type for a function argument or its return value, it defaults to int
  3. You get the 'x' because the compiler uses the ch argument as an integer.
Yassin
A: 

Problem 1: The printit is defined after the main, The solution is to put a function prototype on the top. Problem 2: Declare the function prototype properly, (you didn't write return and argument types) Solution:

#include <stdio.h>

void printit(float a, char ch);

int main()
{
    float a=15.5;
    char ch ='C';
    printit(a,ch);
    return 0;
}

void printit(float a, char ch)
{
    printf("%f\n%c",a,ch);
}
SHiNKiROU
+4  A: 

Firstly, there's no requirement in C language to provide a prototype for a function before it is called. In C99 version of the language there's a requirement to declare a function before it is called, but still there's no requirement to provide a prototype.

Since your compiler did not complain, you must be using a C89/90 compiler, not a C99 compiler.

Secondly, in C89/90, when you call an undeclared function wile passing arguments of type float and char as you do in

printit(a,ch);

the compiler will perform default argument promotions and actually pass values of type double and int. Your function must be defined accordingly for the code to work. You defined your function as

printit(a, ch)  
{
   ...

That definition means that both parameters have type int. This violates the above requirement. The behavior of your code is undefined. It no longer makes any sense to analyze the code any further or guess why it prints something the way it prints it. The behavior of your code is, once again, undefined.

The proper definition for your (undeclared) function might look as follows

int printit(double a, int ch)  
{
   ...

Alternatively, it can be defined in K&R style as

printit(a, ch)  
float a;
{
   ...

That would probably make your code to work correctly. However, the much better approach would be to provide a prototype for printit before calling it. Which prototype you want to use - void printit(double a, int ch) or void printit(float a, char ch) or something else - is for you to decide.

AndreyT
I think your "it not longer makes any sense to analyze the code further..." is a bit strong; that's true from the point of view of the standard since the behaviour is undefined, but if you're doing some non-portable stuff you might need to now the low-level details of calling conventions and so on (especially if it *is* homework :))
Mike Dinsdale
@Mike Dinsdale: Yeah, but that would require a whole lot of additional information, like which compiler was used, what hardware/OS platform and so on.
AndreyT
Yeah, you're absolutely right. In this case it's quite easy to guess why the 15.5 seems to print correctly, but I've no idea how to answer the OP's question about why he gets an 'x' as the char without a lot more information!
Mike Dinsdale