Thread: Multi line macro help

  1. #1
    Registered User
    Join Date
    Oct 2009
    Posts
    11

    Multi line macro help

    I cannot find any good info on how to setup multi line macros. The problem I am having is that I need to use only macros (no functions) to compute factorials. When I use functions the code works but when I try to use macros I keep getting parse errors(it points to the macro I am using as the problem).
    Code:
    #include<stdio.h>
    #include<math.h>
    #define fact(x) do {    \
    int factorial=1;        \
    int k=1;                \
    factorial=factorial*k;  \
    k++;                    \
    } while (k<=n)
    
    #define comb(answer)(result/(input*last))
    //int fact(int n);
    main()
    {
    int n,k,x,result,diff,input,answer,last;
    printf("Please enter a value for n \n");
    scanf("%i",&n);
    printf("Please enter a value for k \n");
    scanf("%i",&k);
    if (n<k)
      printf("N must be larger than or equal to K \n");
    else 
      {
      result=fact(n);
      input=fact(k);
      diff=n-k;
      last=fact(diff);  
      printf("The combination of %i things taken %i at a time is %i \n",n,k,comb(answer)); 
      } 
    return 0;
    }
    
    
    //int fact(int n)
    //{
    //	int k;
    //	int factorial=1;
    //	for(k=1; k<=n; k++)
    //	{
    //		factorial=factorial * k;
    //	}
    //return factorial;		
    //}
    I left the function in there so people can understand what I am trying to achieve. If anyone has any advice or can point me to some resources that discuss how to set up multi line macros I would really appreciate it. Thank you in advance.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So you have, after replacement, result = do stuff. do does not yield a numeric answer that can be assigned to result.

  3. #3
    Registered User
    Join Date
    Oct 2009
    Posts
    11
    Thank you very much for replying. Should I use a for loop instead? I guess I am kind of stuck on how this type of macro works.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    It's just text substitution, like all macros. The text you supply is literally pasted in the place of your "function call". So it must be a bit of code that you would expect to see on the right-hand side of an equals sign.

    (EDIT: Or alternatively, you can just do fact(k,n) where the first variable gets assigned the value of n!.)

  5. #5
    Registered User
    Join Date
    Oct 2009
    Posts
    11
    I am really struggling to grasp this problem. There has to be a loop somewhere. Either in the macro or main and I think that is where I am getting lost because I don't know how to set up a loop in the macro and in main I think I would need a separate loop for each input if I define it like this
    Code:
    #define fact(k,n)(factorial=factorial*k)
    I know that factorial = x(x-1)(x-2)...x number of times or x(x+1)(x+2)...x number of times but I do not know how set that up without using a function. Any more pointers would be greatly appreciated.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So you can set it up as a loop if you want, that's fine. You will just have to take the answer as a parameter, and at the end of your loop, do k = answer or whatever.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by bmancl
    Should I use a for loop instead?
    You wrote your function with a for loop, so why change it?

    I suspect that you decided to change it because you saw some function-style macros being written using a do while loop. But what you probably saw is something like this:
    Code:
    #define /* ... */\
    do\
    {\
        /* ... */\
    }\
    while (0)
    The reason is to use this do while loop to introduce a block of scope, much like what happens in a function.

    Speaking of scope, your do while loop's condition uses variables declared in the loop, but these variables do not exist at that point.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Oct 2009
    Posts
    11
    You are right. I could only find examples of do while loops and I have been searching for a long time. I have been trying to not use a loop in the macro like this
    Code:
     #include<stdio.h>
    #include<math.h>
    #define fact(x)(factorial=factorial*k)
    #define comb(answer)(result/(input*last))
    main()
    {
    int n,k=1,x,result,diff,input,answer,last,factorial=1;
    printf("Please enter a value for n \n");
    scanf("%i",&n);
    printf("Please enter a value for k \n");
    scanf("%i",&k);
    if (n<k)
      printf("N must be larger than or equal to K \n");
    else 
      {
      diff=n-k;
      for(k=1; k<=n; k++)
    	{	
      result=fact(n);
      	}
      for(k=1; k<=n; k++)
    	{	
      input=fact(k);
      	}
      for(k=1; k<=n; k++)
    	{	
      last=fact(diff);
      	}      
      printf("%i  \n",result);
      printf("%i \n",input);
      printf("%i \n",last);
      printf("The combination of %i things taken %i at a time is %i \n",n,k,comb(answer));  
      } 
    return 0;
    }
    but it is not working correctly. The first loop is gets the right answer but the next loops don't so I am not sure if this is even a correct setup. I feel like I am on the right track though so hopefully something will click soon.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Because you will need a loop, your macro cannot evaluate to a value. You will need an output parameter to the macro.

    Code:
    #define fact(n, f) do { int t = n; f = 1; while( t-- > 1 ) f *= t; } while( 0 )
    This sucks. It really, really, really sucks. fact(n, f) looks like a function call but is nothing like it.

    Please, why are you doing this? It's like killing kittens.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Registered User
    Join Date
    Oct 2009
    Posts
    11
    I have to do it this way. I would rather use functions but this is what the instructor wants. Here is what i have so far
    Code:
    #include<stdio.h>
    #include<math.h>
    #define fact(x) for(j=(x-1); j>=0; j--) 		\
    	{					\
    		x=x * j;			\
    	}					\
    	return x;		
    	
    #define comb(answer)(result/(input*last))
    main()
    {
    int n,k,j,x,result,diff=n-k,input,answer,last,ret_val;
    printf("Please enter a value for n \n");
    scanf("%i",&n);
    printf("Please enter a value for k \n");
    scanf("%i",&k);
    if (n<k)
      printf("N must be larger than or equal to K \n");
    else 
      {
      fact(n);
      fact(k);    
      fact(diff);    
      printf("The combination of %i things taken %i at a time is %i \n",n,k,comb(answer));   
      } 
    return 0;
    }
    It compiles. But when I enter the second number the program hangs. So I am getting even closer. Thank you for your suggestion. I am going to give it a try.

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by bmancl View Post
    I have to do it this way. I would rather use functions but this is what the instructor wants.
    Your instructor is a sadistic .............. who is trying to sabotage you. This kind of coding is nonsense and would get you fired from anywhere reasonable. I'm glad you realize that, at least.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #12
    Registered User
    Join Date
    Oct 2009
    Posts
    11
    What makes this problem is just that; most people are against using macros so it is very difficult to find any resources or help on the subject. So far I have a pretty good grasp on C programming but this problem is killing me. In my instructors defense he has put out that macros should not be used. He justs wants us to know what they are and why they shouldn't be used.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by bmancl
    In my instructors defense he has put out that macros should not be used. He justs wants us to know what they are and why they shouldn't be used.
    Most sadistic of all: after everyone has handed in their homework he will announce that this particular assignment will not be graded, and publicly hope that everyone has learnt to avoid macros from the experience

    Anyway, what exactly does the assignment stipulate? Are you forbidden from using an out parameter for your macro?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Oct 2009
    Posts
    11
    If you look at my first post I left the original working code with a function in but I // it.The assignment is to remove the function from the code and use two macros. One to compute the factorial and one that computes n!/k!(n-k)!. What I don't understand is that once I remove the function with the loop where does the loop go? I have tried a lot of different approaches but so far no luck. I know I need three loops; one for n!,k! and (n-k)! so I think having a loop in the macro makes the most sense. I have tried using 3 for loops in main but that didn't turn out. If you have any more suggestions I would greatly appreciate it.

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Ok, then, a few points.

    1. A macro cannot "return" something. It is just a substitution of characters. If you put a return in a macro, it will cause the function which "calls" the macro to return. If the macro is an expression, it can evaluate to a value, but this isn't the same thing as returning a value.

    2. A loop cannot evaluate to anything. It is a control statement.

    3. You need a loop.

    Putting these three together, it's clear that you cannot ever make something that looks like this:

    Code:
    int x = fact( n );
    Since that would require that fact( n ) be an expression, but it can't be an expression because you need a loop.

    Instead, you need to pass the variable x in as a macro parameter and let the macro assign the result itself. I already gave an example of it.

    Are we vomiting yet?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quantum Random Bit Generator
    By shawnt in forum C++ Programming
    Replies: 62
    Last Post: 06-18-2008, 10:17 AM
  2. Reading a buffer line by line, while using system read
    By Hammad Saleem in forum C Programming
    Replies: 9
    Last Post: 05-27-2008, 05:41 AM
  3. Finding carriage returns (\c) in a line
    By JizJizJiz in forum C++ Programming
    Replies: 37
    Last Post: 07-19-2006, 05:44 PM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM