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!

Wednesday, April 04, 2007

Language C Learning Notes 1

File Inclusion
A control line of the form
# include <filename>
causes the replacement of that line by the entire contents of the file filename. The characters in the name filename must not include > or newline, and the effect is undefined if it contains any of ", ', \, or /*. The named file is searched for in a sequence of implementation-defined places.
Similarly, a control line of the form
# include "filename"
searches first in association with the original source file (a deliberately implementation-dependent phrase), and if that search fails, then as in the first form. The effect of using ', \, or /* in the filename remains undefined, but > is permitted.
Finally, a directive of the form
# include token-sequence
not matching one of the previous forms is interpreted by expanding the token sequence as for normal text; one of the two forms with <...> or "..." must result, and is then treated as previously described.
#include files may be nested.

--
Happy day, happy life!

CuTest Example Compiled with error!

I copy the example from the readme file of CuTest.
However, it compiles with error.

The following the updated version:
DETAILED EXAMPLE

Here is a more detailed example. We will work through a simple
test first exercise. The goal is to create a library of string
utilities. First, lets write a function that converts a
null-terminated string to all upper case.

Ensure that CuTest.c and CuTest.h are accessible from your C
project. Next, create a file called StrUtil.c with these
contents:

#include  <assert.h>
#include 
< setjmp.h>
#include 
<stdlib.h >
#include 
<stdio.h>
#include 
<string.h>
// The origianl version has missed the above includes
#include "CuTest.h"
    
    
char* StrToUpper(char*  str) {
        
return str;
    }
    
    
void  TestStrToUpper(CuTest *tc) {
        
char*  input = strdup(" hello world");
        
char*  actual = StrToUpper(input);
        
char*  expected = " HELLO WORLD";
        CuAssertStrEquals(tc, expected, actual);
    }
   
    CuSuite
* StrUtilGetSuite() {
        CuSuite
* suite =  CuSuiteNew();
        SUITE_ADD_TEST(suite, TestStrToUpper);
        
return suite;
    }

Create another file called AllTests.c with these contents:

    #include  "CuTest.h"
    
    CuSuite
*  StrUtilGetSuite();
    
    
void RunAllTests(void ) {
        CuString 
*output = CuStringNew();
        CuSuite
* suite = CuSuiteNew();
        
        CuSuiteAddSuite(suite, StrUtilGetSuite());
    
        CuSuiteRun(suite);
        CuSuiteSummary(suite, output);
        CuSuiteDetails(suite, output);
        printf(
" %s\n", output->buffer);
    }
    
    
int main(void) {
        RunAllTests();
    }

More detail please see its readme file.
--
Happy day, happy life!

Sunday, April 01, 2007

不管你是狮子还是瞪羚,当太阳升起时,你最好开始奔跑。

在非洲,瞪羚每天早上醒来时,
它知道自己必须跑得比最快的狮子还快,

否则就会被吃掉。

狮子每天早上醒来时,
它知道自己必须超过跑得最慢的瞪羚,

否则就会被饿死。


不管你是狮子还是瞪羚,
当太阳升起时,你最好开始奔跑。

摘于<<The World Is Flat>>

--
Happy day, happy life!