Member Avatar for I_m_rude

hi..

#define loop()    for(;b<c;b++)
#define print(a)  printf("%d ",a);


int main()
{

     ............
     ...........
     ............
     ..............

    int i=0,j=0;


     loop(i,15)
     {
               loop(j,15)
               {
                           print(z[l][m])
               }
               printf("\n");
     }
}

This code print some integers , but isn't printing all in the desired way.

But, when I change the #define statement in this way,

#define loop(b,c)  for(b=0;b<c;b++)

then, it is working correctly means it is giving o/p as desired. just difference is the

b=0

in the #define, lthoguh i have initialized i and j in the main loop, then why is it expecting me to initalize in the preprocessor directive ?

thanks. waiting for reply.

Recommended Answers

All 21 Replies

b=0 isn't the only difference, you also added the for keyword and an argument list to the macro which assigns i to b and 15 to c instead of expecting b and c to already exist as variables. It's actually a miracle that the original code compiles at all (I suspect it really doesn't though, and you're just paraphrasing).

You set j to 0 once before the outer loop starts. So when the inner loop is run for the first time, j goes from 0 to 15. On the second iteration of the outer loop, j will still be 15 because you never reset it to 0 after the first iteration. If you add j=0 to the inner loop, j will be reset to 0 at each iteration of the outer loop.

PS: The fact that you used macros here instead of typing the loop out, makes no difference.

commented: yoo! great! +0
Member Avatar for I_m_rude

@decptikon sorry for that. actually I worte the code wrongly. I have corrected it. Please check it now. SEE it now please.
thanks.

Your corrections are irrelevant because the problem is the same as in my speculation about how the code really looked. b and c aren't parameters to the macro, they're expected to be declared and initialized as named variables:

#include <stdio.h>

#define loop() for (; b < c; b++)

int main(void)
{
    int i = 0;
    int b = 0, c = 15;

    loop(i, 15)
    {
        printf("%d\n", i);
    }

    return 0;
}

The argument list is actually wrong, and you should at least get a warning about having too many arguments in a parameter list expecting none. As you already know, the correction is to add those parameters to the macro:

#include <stdio.h>

#define loop(b, c) for (; b < c; b++)

int main(void)
{
    int i = 0;

    loop(i, 15)
    {
        printf("%d\n", i);
    }

    return 0;
}

What you can't do is remove the empty parameter list, like this:

#define loop for (; b < c; b++)

The reason is because when you say loop(i, 15), what actually happens is for (; b < c; b++)(i, 15), and that's a syntax error unless the next token is a semicolon to turn (i, 15) into a do nothing statement.

Member Avatar for I_m_rude
#include<stdio.h>
#define SWAP(a, b, c)(c t; t=a, a=b, b=t)
int main()
{
    int x=10, y=20;
    SWAP(x, y, int);
    printf("%d %d\n", x, y);
    return 0;
}

please tell me why we will this code not compile? Reason : t cannot be defined in parentheses. Why cant we ? please explain me this ?

thanks in advance.

Why cant we ? please explain me this ?

Copy and paste the text yourself to see:

/* SWAP(x, y, int); */
(int t; t=x, x=y, y=t);

Yea, that looks like it'll compile...not. Why? Because there's a mismatch between the parentheses and the semicolons. You want the last part to be a smiley, not an upside down frowny:

(int t; t=x, x=y, y=t;)

Here's a trick for when you want to end a function macro instantiation with a semicolon:

#include<stdio.h>

#define SWAP(a, b, type) do { \
    type t = a;               \
    a = b;                    \
    b = t;                    \
} while (0)

int main(void)
{
    int x = 10, y = 20;

    SWAP(x, y, int);
    printf("%d %d\n", x, y);

    return 0;
}

The magic is in the do..while(0). You probably already know that do..while ends with a semicolon, and by setting the condition to 0 you ensure that the body runs only one time. The end result is that instead of the awkward looking instantiation that looks like a syntax error:

SWAP(x, y, int)
printf("%d %d\n", x, y);

You have the more conventional semicolon terminated function "call":

SWAP(x, y, int);
printf("%d %d\n", x, y);

Also, the braces of the do..while ensure that you have a nested block, and the declaration of variables local to that block don't step on variables of the same name in the calling block (which isn't a problem here, but can happen for some of the more complex macros).

Member Avatar for I_m_rude

So, the correct way to do is

#define SWAP(a,b,c) (c t; t=a,a=b,b=t;)

Now, is this right ?

And what exacltly do you want to tell after giving the do..while example? I understand what u said. But, What exaclty you want to tell me ?

thanks.

So, the correct way to do is

No, remove the parentheses entirely. But that's still problematic because now you'll have to contend with the requirement that declarations be at the beginning of a block (unless you're compiling as C99 or later).

And what exacltly do you want to tell after giving the do..while example? I understand what u said. But, What exaclty you want to tell me ?

I want to tell you the right way to accomplish what you're trying to do.

Member Avatar for I_m_rude

I didn't get that. Sir, Why is it neccassary to remove the parenthesis ? What happen when i remove parenthesis? And what is meant by "have to be contend with requirement that declarations be the begining of a block" ?

thanks

What happen when i remove parenthesis?

Allow me to make the problem more obvious:

if (int temp = x; x = y; y = temp;)

Wrapping parentheses results in taking those three statements and wrapping them in an expression, much like putting them in the condition expression of an if statement, which is syntactically illegal in this case.

And what is meant by "have to be contend with requirement that declarations be the begining of a block" ?

This is legal C99, but illegal C89:

#include <stdio.h>

int main(void)
{
    puts("Starting main...\n");

    int i; /* Declaration after a statement in the block */

    for (i = 0; i < 10; ++i)
        printf("%d\n", i);

    return 0;
}
Member Avatar for I_m_rude

Sir, Why is it illegal. Seriously , Will you please explain it more clearly.

SWAP(a,b,c);

this will be replaced by

(int t; t=a, a=b,b=a);

or

 (int t; t=a, a=b,b=a;);

what is problem with these expressions ? will it not swap the values ? what is the problem ? in my answer book, it is written "t can't be dclared in parentheses". what are they trying to say with this ? please it's a request , clear my doubt. I am damn confused with this. please .

thanks in advance.

what is problem with these expressions ?

They're syntax errors. Wrapping a statement in parentheses makes it an expression, and a statement isn't allowed inside an expression. You can simplify the error like so:

int main(void)
{
    int x;

    /* Adding a semicolon after 10 makes it a statement */
    (x = 10;);

    return 0;
}

So what you have is a statement x = 10; inside an expression (x = 10;) which itself is a statement (x = 10;);, and this is illegal. That's just the way the syntax of C works. If the inner semicolon weren't there, ie. (x = 10);, this example would work just fine because now you're wrapping parens around an expression, which is perfectly legal.

However, if you have declarations then you have absolutely no choice but to terminate the declaration with a semicolon, which makes it a statement, which means you can't nest it inside an expression.

in my answer book, it is written "t can't be dclared in parentheses".

That's true, though it's not the entirety of the problem because even if you move the declaration outside of the parens you'd still have an error due to there being statements inside the parens. However, in that case you can fix it with the comma operator:

int t; (t = a, a = b, b = t);

This will work, but I don't recommend it for your macro because there are still problems that I've already mentioned.

Member Avatar for I_m_rude

why can't we declare t inside the parenthesis ? is the reason that expression changed into statement , that one is the reason for this ?

is the reason that expression changed into statement , that one is the reason for this ?

Yes, that's the reason.

Member Avatar for I_m_rude

okay ! i got it now after too much effort of you and me .;)

Can you tell me the exact difference between statement and expression ?

I know statement ends with ; ans expression doesn't. () in this, expression is there. Iknow these things only. So what is exact difference ?

Can you tell me the exact difference between statement and expression ?

The C99 standard defines an expression as "a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof".

A statement is defined as "specifies an action to be performed". That's obviously not very helpful because it seems the same as an expression just described with fewer words, but the standard goes on to explain about an expression statement which has grammar like so:

expression-statement:
    expression(optional) ;

So an expression statement is an optionally empty expression followed by a semicolon. The case of an empty expression followed by a semicolon is called a null statement. And the point of the expression statement is a statement used solely for its side effect (ie. the effect of the expression). This distinction is made because there are other statement types that do their own work, such as conditional statements and looping statements, or that collect statements as in the compound statement (also known as a block).

If you're feeling especially daring, you can read the standard here. But be warned, you're not expected to find much of it useful at this point in your education, it's written to be ultra precise for people who are writing compilers.

Member Avatar for I_m_rude

@james sir, whole post goes above my mind. I sisn't get anything. please explain me in more simple language . thanks alot but please answer my doubt in more simple way(may be using examples or some links or in more simple way , u like). thanks in advance.

At this point I'll just say that there's a difference, but it's not important that you understand it yet. Understanding nuances of the C grammar isn't necessary to write code in C.

Member Avatar for I_m_rude

@james sir, i Know i dnt needd to. but, Companies always ask these tricky-defination type questions. So i want to know this please. please can u tell me the same thing which u said just in a simpler way ? please!

thanks.

Companies always ask these tricky-defination type questions.

They do? How many job interviews have you been on?

Paraphrasing for ease of understanding:
An expression is that portion of a statement that has operators (*+-<> etc).
A statement ends in ;

There's more to it but that's what you can grasp at this moment.

Member Avatar for I_m_rude

okay sir. so in this sufficient for time being ?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.