Google
 

Thursday, April 05, 2007

Language C Learning Notes 2

  1. #define
    1. A #define line defines a symbolic name or symbolic constant to be a particular string of characters:
      #define name replacement list
      Thereafter, any occurrence of name (not in quotes and not part of another name) will be replaced by the corresponding replacement text. The name has the same form as a variable name: a sequence of letters and digits that begins with a letter. The replacement text can be any sequence of characters; it is not limited to numbers.
    2. Symbolic constant names are conventionally written in upper case so they can ber readily distinguished from lower case variable names. Notice that there is no semicolon at the end of a #define line.
  2. Macro Substitution
    1. A definition has the form
      #define name replacement text
      It calls for a macro substitution of the simplest kind - subsequent occurrences of the token name will be replaced by the replacement text.
    2. The name in a #define has the same form as a variable name; the replacement text is arbitrary.
    3. Normally the replacement text is the rest of the line, but a long definition may be continued onto several lines by placing a \ at the end of each line to be continued.
    4. The scope of a name defined with #define is from its point of definition to the end of the source file being compiled. A definition may use previous definitions.
    5. Substitutions are made only for tokens, and do not take place within quoted strings.
    6. It is also possible to define macros with arguments, so the replacement text can be different for different calls of the macro.
    7. If you examine the expansion of max, you will notice some pitfalls. The expressions are evaluated twice; this is bad if they involve side effects like increment operators or input and output. For instance
      max(i++, j++) /* WRONG */
      #define max(A, B) ((A) > (B) ? (A) : (B))
      x = max(p+q, r+s);
      will increment the larger twice. Some care also has to be taken with parentheses to make sure the order of evaluation is preserved; consider what happens when the macro
      #define square(x) x * x /* WRONG */
      is invoked as square(z+1).
    8. Names may be undefined with #undef, usually to ensure that a routine is really a function, not a macro:
      #undef getchar
      int getchar(void) { ... }
    9. Formal parameters are not replaced within quoted strings. If, however, a parameter name is preceded by a # in the replacement text, the combination will be expanded into a quoted string with the parameter replaced by the actual argument. This can be combined with string concatenation to make, for example, a debugging print macro:
      #define dprint(expr) printf(#expr " = %g\n", expr)
    10. The preprocessor operator ## provides a way to concatenate actual arguments during macro expansion. If a parameter in the replacement text is adjacent to a ##, the parameter is replaced by the actual argument, the ## and surrounding white space are removed, and the result is re-scanned. For example, the macro paste concatenates its two arguments:
      #define paste(front, back) front ## back
      so paste(name, 1) creates the token name1.
    11. Test Macro usage  

      #include 
      <assert.h>
      #include 
      < setjmp.h>
      #include 
      <stdlib.h >
      #include 
      <stdio.h>
      #include 
      <string.h>
          
      // Test Macro usage    
          
      //
           #undef max
          
      //  Be care to define a macro
          
      // At the end without semicolom, otherwise the semicolom will be at the end of the token
          #define max(A,B)  ((A) > (B) ? (A) : (B))
          
      #define maxName(A,B) ((A) > (B) ? (#A) : (#B))
          
      #undef square
          
      #undef square1
          
      #define square(a) ((a) * (a))
          
      #define  square1(a) (a * a)
          
          
      // #
          #undef dprintf
          
      #define dprintf(expr)  printf(#expr " =%g\n",expr)
          
      //  ##
          #undef paste
          
      #define paste(front,back) front ## back
          
      #undef map
          
      #define map(str) #str
          
      void main()
          {
            
      int a,b,c;
            
      //  Testing max(a,b)  
            printf( "max(a,b):\n");         
            printf(
      "Please input two numbers to compare:\n");
            printf(
      "a=");
            scanf(
      " %i"&a);
            printf(
      "b=");
            scanf(
      " %i",&b);
            printf(
      "Which is bigger, a=%i or b=%i? %s=%i is bigger.\n",a,b, maxName(a,b),max(a,b));    
            
            
      // Testing max(i++,j++)
            printf( "max(i++,j++):\n");
            printf(
      "Please input two numbers to compare:\n");
            printf(
      "a=");
            scanf(
      "%i"& a);
            printf(
      "b=");
            scanf(
      "%i",& b);
            printf(
      "Which is bigger, a=%i or b=%i? %s=%i is bigger.\n ",a,b, maxName(a,b),max(a++,b++ ));            
            printf(
      "Now the a=%i,b=%i.\n" ,a,b);
            
            
            b 
      = 2;
            printf(
      "\nTesting #define square(a) ((a) * (a))\n" );
            printf(
      "Square(%d) = %d\n",b,square(b));
            printf(
      "Square(%d + 1) = %d\n",b,square(b  + 1));
            
            
            printf(
      "\nTesting #define square1(a) (a * a)\n");
            printf(
      "Square1(%d) = %d\n",b,square1(b));
            printf(
      "Square1(%d) = %d\n",b +  1,square1(b +  1));

            
      // Testing  #
            double d =  1.003;
            dprintf(d);
            
      // Testing  ##         
            
      //        char* strd = "Testing";
            
      //        char* str = "Testing";
            double str  = 2.0;
            
      double  strd = 34.0;   
            
      // expected 
            dprintf(str);
            
      //  expected
            dprintf(strd);
            
            printf(
      "%e\n",paste(str,d));
            
            
      // Terminate program
            printf(" Please input any character to end the program:\n");
            
      char* t;
            scanf(
      "%s ",&t); 

          }
  3. Input and Output
    1. The % Format Specifiers:

      The % specifiers that you can use in ANSI C are:

            Usual variable type           Display

      %c        char                     single character
      %d (%i)   int                      signed integer
      %e (%E)   float or double          exponential format
      %f        float or double          signed decimal
      %g (%G)   float or double          use %f or %e as required
      %o        int                      unsigned octal value

      %p        pointer                  address stored in pointer
      %s        array of char            sequence of characters
      %u        int                      unsigned decimal
      %x (%X)   int                      unsigned hex value




s

--
Happy day, happy life!

No comments: