分类: 编程

  • 2019-12-15-学习c最少必要知识

    学习c最少必要知识

    C – Program Structure

    A C program basically consists of the following parts −

    • Preprocessor Commands
    • Functions
    • Variables
    • Statements & Expressions
    • Comments

    C – Basic Syntax

    A C program consists of various tokens and a token is either a keyword, an identifier, a constant, a string literal, or a symbol.

    In a C program, the semicolon is a statement terminator. That is, each individual statement must be ended with a semicolon. It indicates the end of one logical entity.

    Comments are like helping text in your C program and they are ignored by the compiler. They start with /* and terminate with the characters */ or start with //.

    A C identifier is a name used to identify a variable, function, or any other user-defined item. An identifier starts with a letter A to Z, a to z, or an underscore ‘_’ followed by zero or more letters, underscores, and digits (0 to 9). C is a case-sensitive programming language.

    The following list shows the reserved words in C. These reserved words may not be used as constants or variables or any other identifier names.

    auto else long switch break enum register typedef case extern return union char float short unsigned const for signed void continue goto sizeof volatile default if static while do int struct _Packed double

    A line containing only whitespace, possibly with a comment, is known as a blank line, and a C compiler totally ignores it.

    Whitespace is the term used in C to describe blanks, tabs, newline characters and comments. Whitespace separates one part of a statement from another and enables the compiler to identify where one element in a statement, such as int, ends and the next element begins.

    C – Data Types

    Data types in c refer to an extensive system used for declaring variables or functions of different types. The type of a variable determines how much space it occupies in storage and how the bit pattern stored is interpreted.

    The types in C can be classified as follows:

    • Basic Types: They are arithmetic types and are further classified into: (a) integer types and (b) floating-point types.
    • Enumerated types: They are again arithmetic types and they are used to define variables that can only assign certain discrete integer values throughout the program.
    • The type void: The type specifier void indicates that no value is available.
    • Derived types: They include (a) Pointer types, (b) Array types, (c) Structure types, (d) Union types and (e) Function types.

    Integer Types

    TypeStorage sizeValue range
    char1 byte-128 to 127 or 0 to 255
    unsigned char1 byte0 to 255
    signed char1 byte-128 to 127
    int2 or 4 bytes-32,768 to 32,767 or -2,147,483,648 to 2,147,483,647
    unsigned int2 or 4 bytes0 to 65,535 or 0 to 4,294,967,295
    short2 bytes-32,768 to 32,767
    unsigned short2 bytes0 to 65,535
    long8 bytes-9223372036854775808 to 9223372036854775807
    unsigned long8 bytes0 to 18446744073709551615

    Floating-Point Types

    TypeStorage sizeValue rangePrecision
    float4 byte1.2E-38 to 3.4E+386 decimal places
    double8 byte2.3E-308 to 1.7E+30815 decimal places
    long double10 byte3.4E-4932 to 1.1E+493219 decimal places

    The void Type

    • Function returns as void : There are various functions in C which do not return any value or you can say they return void. A function with no return value has the return type as void. For example, void exit (int status);
    • Function arguments as void: There are various functions in C which do not accept any parameter. A function with no parameter can accept a void. For example, int rand(void);
    • Pointers to void: A pointer of type void * represents the address of an object, but not its type. For example, a memory allocation function void *malloc( size_t size ); returns a pointer to void which can be casted to any data type.

    C – Variables

    A variable is nothing but a name given to a storage area that our programs can manipulate. Each variable in C has a specific type, which determines the size and layout of the variable’s memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.

    There are the following basic variable types:

    • char: Typically a single octet(one byte). This is an integer type.
    • int: The most natural size of integer for the machine.
    • float: A single-precision floating point value.
    • double: A double-precision floating point value.
    • void: Represents the absence of type.

    A variable definition tells the compiler where and how much storage to create for the variable. A variable definition specifies a data type and contains a list of one or more variables of that type as follows − type variable_list;

    Here, type must be a valid C data type including char, w_char, int, float, double, bool, or any user-defined object; and variable_list may consist of one or more identifier names separated by commas. Some valid declarations are shown here −

    int    i, j, k;
    char   c, ch;
    float  f, salary;
    double d;

    Variables can be initialized (assigned an initial value) in their declaration. The initializer consists of an equal sign followed by a constant expression as follows − type variable_name = value; Some examples are −

    extern int d = 3, f = 5;    // declaration of d and f.
    int d = 3, f = 5;           // definition and initializing d and f.
    byte z = 22;                // definition and initializes z.
    char x = 'x';               // the variable x has the value 'x'.

    For definition without an initializer: variables with static storage duration are implicitly initialized with NULL (all bytes have the value 0); the initial value of all other variables are undefined.

    A variable declaration provides assurance to the compiler that there exists a variable with the given type and name so that the compiler can proceed for further compilation without requiring the complete detail about the variable. A variable definition has its meaning at the time of compilation only, the compiler needs actual variable definition at the time of linking the program.

    A variable declaration is useful when you are using multiple files and you define your variable in one of the files which will be available at the time of linking of the program. You will use the keyword extern to declare a variable at any place. Though you can declare a variable multiple times in your C program, it can be defined only once in a file, a function, or a block of code.

    There are two kinds of expressions in C −

    lvalue − Expressions that refer to a memory location are called “lvalue” expressions. An lvalue may appear as either the left-hand or right-hand side of an assignment.

    rvalue − The term rvalue refers to a data value that is stored at some address in memory. An rvalue is an expression that cannot have a value assigned to it which means an rvalue may appear on the right-hand side but not on the left-hand side of an assignment.

    Variables are lvalues and so they may appear on the left-hand side of an assignment. Numeric literals are rvalues and so they may not be assigned and cannot appear on the left-hand side. Take a look at the following valid and invalid statements −

    int g = 20; // valid statement
    10 = 20; // invalid statement; would generate compile-time error

    C – Constants and Literals

    Constants refer to fixed values that the program may not alter during its execution. These fixed values are also called literals.

    Constants can be of any of the basic data types like an integer constant, a floating constant, a character constant, or a string literal. There are enumeration constants as well.

    Constants are treated just like regular variables except that their values cannot be modified after their definition.

    An integer literal can be a decimal, octal, or hexadecimal constant. A prefix specifies the base or radix: 0x or 0X for hexadecimal, 0 for octal, and nothing for decimal.

    An integer literal can also have a suffix that is a combination of U and L, for unsigned and long, respectively. The suffix can be uppercase or lowercase and can be in any order.

    Here are some examples of integer literals −

    212         /* Legal */
    215u        /* Legal */
    0xFeeL      /* Legal */
    078         /* Illegal: 8 is not an octal digit */
    032UU       /* Illegal: cannot repeat a suffix */
    85         /* decimal */
    0213       /* octal */
    0x4b       /* hexadecimal */
    30         /* int */
    30u        /* unsigned int */
    30l        /* long */
    30ul       /* unsigned long */

    A floating-point literal has an integer part, a decimal point, a fractional part, and an exponent part. You can represent floating point literals either in decimal form or exponential form.

    While representing decimal form, you must include the decimal point, the exponent, or both; and while representing exponential form, you must include the integer part, the fractional part, or both. The signed exponent is introduced by e or E.

    Here are some examples of floating-point literals −

    3.14159       /* Legal */
    314159E-5L    /* Legal */
    510E          /* Illegal: incomplete exponent */
    210f          /* Illegal: no decimal or exponent */
    .e55          /* Illegal: missing integer or fraction */

    Character literals are enclosed in single quotes, e.g., ‘x’ can be stored in a simple variable of char type.

    A character literal can be a plain character (e.g., ‘x’), an escape sequence (e.g., ‘\t’), or a universal character (e.g., ‘\u02C0’).

    There are certain characters in C that represent special meaning when preceded by a backslash for example, newline (\n) or tab (\t).

    Escape sequenceMeaning
    \|\ character
    \’‘ character
    \”” character
    \?? character
    \aAlert or bell
    \bBackspace
    \fForm feed
    \nNewline
    \rCarriage return
    \tHorizontal tab
    \vVertical tab
    \oooOctal number of one to three digits
    \xhh . . .Hexadecimal number of one or more digits

    String literals or constants are enclosed in double quotes “”. A string contains characters that are similar to character literals: plain characters, escape sequences, and universal characters.

    You can break a long line into multiple lines using string literals and separating them using white spaces.

    There are two simple ways in C to define constants −

    • Using #define preprocessor.
    • Using const keyword.

    Given below is the form to use #define preprocessor to define a constant − #define identifier value

    You can use const prefix to declare constants with a specific type as follows −const type variable = value;

    Note that it is a good programming practice to define constants in CAPITALS.

    C – Storage Classes

    A storage class defines the scope (visibility) and life-time of variables and/or functions within a C Program. They precede the type that they modify. We have four different storage classes in a C program −

    • auto
    • register
    • static
    • extern

    The auto storage class is the default storage class for all local variables.

    The register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and can’t have the unary ‘&’ operator applied to it (as it does not have a memory location).

    The register should only be used for variables that require quick access such as counters. It should also be noted that defining ‘register’ does not mean that the variable will be stored in a register. It means that it MIGHT be stored in a register depending on hardware and implementation restrictions.

    The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.

    The static modifier may also be applied to global variables. When this is done, it causes that variable’s scope to be restricted to the file in which it is declared.

    In C programming, when static is used on a global variable, it causes only one copy of that member to be shared by all the objects of its class.

    The extern storage class is used to give a reference of a global variable that is visible to ALL the program files. When you use ‘extern’, the variable cannot be initialized however, it points the variable name at a storage location that has been previously defined.

    When you have multiple files and you define a global variable or function, which will also be used in other files, then extern will be used in another file to provide the reference of defined variable or function. Just for understanding, extern is used to declare a global variable or function in another file.

    The extern modifier is most commonly used when there are two or more files sharing the same global variables or functions as explained below.

    First File: main.c

    #include <stdio.h>
    int count ;
    extern void write_extern();
    main() {
       count = 5;
       write_extern();
    }

    Second File: support.c

    #include <stdio.h>
    extern int count;
    void write_extern(void) {
       printf("count is %d\n", count);
    }

    Here, extern is being used to declare count in the second file, where as it has its definition in the first file, main.c. Now, compile these two files as follows − $gcc main.c support.c

    It will produce the executable program a.out. When this program is executed, it produces the following result − count is 5

    C – Operators

    An operator is a symbol that tells the compiler to perform specific mathematical or logical functions. C language is rich in built-in operators and provides the following types of operators −

    • Arithmetic Operators
    • Relational Operators
    • Logical Operators
    • Bitwise Operators
    • Assignment Operators
    • Misc Operators

    Arithmetic Operators

    Assume variable A holds 10 and variable B holds 20 then −

    OperatorDescriptionExample
    +Adds two operands.A + B = 30
    Subtracts second operand from the first.A − B = -10
    *Multiplies both operands.A * B = 200
    /Divides numerator by de-numerator.B / A = 2
    %Modulus Operator and remainder of after an integer division.B % A = 0
    ++Increment operator increases the integer value by one.A++ = 11
    Decrement operator decreases the integer value by one.A– = 9

    Relational Operators

    Assume variable A holds 10 and variable B holds 20 then −

    OperatorDescriptionExample
    ==Checks if the values of two operands are equal or not. If yes, then the condition becomes true.(A == B) is not true.
    !=Checks if the values of two operands are equal or not. If the values are not equal, then the condition becomes true.(A != B) is true.
    >Checks if the value of left operand is greater than the value of right operand. If yes, then the condition becomes true.(A > B) is not true.
    <Checks if the value of left operand is less than the value of right operand. If yes, then the condition becomes true.(A < B) is true.
    >=Checks if the value of left operand is greater than or equal to the value of right operand. If yes, then the condition becomes true.(A >= B) is not true.
    <=Checks if the value of left operand is less than or equal to the value of right operand. If yes, then the condition becomes true.(A <= B) is true.

    Logical Operators

    Assume variable A holds 1 and variable B holds 0, then −

    OperatorDescriptionExample
    &&Called Logical AND operator. If both the operands are non-zero, then the condition becomes true.(A && B) is false.
    ||Called Logical OR Operator. If any of the two operands is non-zero, then the condition becomes true.(A || B) is true.
    !Called Logical NOT Operator. It is used to reverse the logical state of its operand. If a condition is true, then Logical NOT operator will make it false.!(A && B) is true.

    Bitwise Operators

    pqp & qp | qp ^ q
    00000
    01011
    11110
    10011

    Assume A = 60 and B = 13 in binary format, they will be as follows −

    A = 0011 1100
    B = 0000 1101
    A&B = 0000 1100
    A|B = 0011 1101
    A^B = 0011 0001
    ~A = 1100 0011

    The following table lists the bitwise operators supported by C. Assume variable ‘A’ holds 60 and variable ‘B’ holds 13, then −

    OperatorDescriptionExample
    &Binary AND Operator copies a bit to the result if it exists in both operands.(A & B) = 12, i.e., 0000 1100
    |Binary OR Operator copies a bit if it exists in either operand.(A | B) = 61, i.e., 0011 1101
    ^Binary XOR Operator copies the bit if it is set in one operand but not both.(A ^ B) = 49, i.e., 0011 0001
    ~Binary One’s Complement Operator is unary and has the effect of ‘flipping’ bits.(~A ) = ~(60), i.e,. -0111101
    <<Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand.A << 2 = 240 i.e., 1111 0000
    >>Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand.A >> 2 = 15 i.e., 0000 1111

    Assignment Operators

    OperatorDescriptionExample
    =Simple assignment operator. Assigns values from right side operands to left side operandC = A + B will assign the value of A + B to C
    +=Add AND assignment operator. It adds the right operand to the left operand and assign the result to the left operand.C += A is equivalent to C = C + A
    -=Subtract AND assignment operator. It subtracts the right operand from the left operand and assigns the result to the left operand.C -= A is equivalent to C = C – A
    *=Multiply AND assignment operator. It multiplies the right operand with the left operand and assigns the result to the left operand.C *= A is equivalent to C = C * A
    /=Divide AND assignment operator. It divides the left operand with the right operand and assigns the result to the left operand.C /= A is equivalent to C = C / A
    %=Modulus AND assignment operator. It takes modulus using two operands and assigns the result to the left operand.C %= A is equivalent to C = C % A
    <<=Left shift AND assignment operator.C <<= 2 is same as C = C << 2
    >>=Right shift AND assignment operator.C >>= 2 is same as C = C >> 2
    &=Bitwise AND assignment operator.C &= 2 is same as C = C & 2
    ^=Bitwise exclusive OR and assignment operator.C ^= 2 is same as C = C ^ 2
    |=Bitwise inclusive OR and assignment operator.C |= 2 is same as C = C | 2

    Operators Precedence in C

    Operator precedence determines the grouping of terms in an expression and decides how an expression is evaluated. Certain operators have higher precedence than others; for example, the multiplication operator has a higher precedence than the addition operator.

    Here, operators with the highest precedence appear at the top of the table, those with the lowest appear at the bottom. Within an expression, higher precedence operators will be evaluated first.

    CategoryOperatorAssociativity
    Postfix() [] -> . ++ —Left to right
    Unary+ – ! ~ ++ — (type)* & sizeofRight to left
    Multiplicative* / %Left to right
    Additive+ –Left to right
    Shift<< >>Left to right
    Relational< <= > >=Left to right
    Equality== !=Left to right
    Bitwise AND&Left to right
    Bitwise XOR^Left to right
    Bitwise OR|Left to right
    Logical AND&&Left to right
    Logical OR||Left to right
    Conditional?:Right to left
    Assignment= += -= *= /= %=>>= <<= &= ^= |=Right to left
    Comma,Left to right

    C – Decision Making

    Decision making structures require that the programmer specifies one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.

    C programming language assumes any non-zero and non-null values as true, and if it is either zero or null, then it is assumed as false value.

    C programming language provides the following types of decision making statements.

    Sr.No.Statement & Description
    1if statement
    An if statement consists of a boolean expression followed by one or more statements.
    2if…else statement
    An if statement can be followed by an optional else statement, which executes when the Boolean expression is false.
    3nested if statements
    You can use one if or else if statement inside another if or else if statement(s).
    4switch statement
    A switch statement allows a variable to be tested for equality against a list of values.
    5nested switch statements
    You can use one switch statement inside another switch statement(s).

    We have covered conditional operator ? : in the previous chapter which can be used to replace if…else statements. It has the following general form −

    Exp1 ? Exp2 : Exp3;

    Where Exp1, Exp2, and Exp3 are expressions. Notice the use and placement of the colon.

    The value of a ? expression is determined like this −

    • Exp1 is evaluated. If it is true, then Exp2 is evaluated and becomes the value of the entire ? expression.
    • If Exp1 is false, then Exp3 is evaluated and its value becomes the value of the expression.

    C – Loops

    A loop statement allows us to execute a statement or group of statements multiple times.

    C programming language provides the following types of loops to handle looping requirements.

    Sr.No.Loop Type & Description
    1while loop
    Repeats a statement or group of statements while a given condition is true. It tests the condition before executing the loop body.
    2for loop
    Executes a sequence of statements multiple times and abbreviates the code that manages the loop variable.
    3do…while loop
    It is more like a while statement, except that it tests the condition at the end of the loop body.
    4nested loops
    You can use one or more loops inside any other while, for, or do..while loop.

    Loop control statements change execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed.

    C supports the following control statements.

    Sr.No.Control Statement & Description
    1break statement
    Terminates the loop or switch statement and transfers execution to the statement immediately following the loop or switch.
    2continue statement
    Causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating.
    3goto statement
    Transfers control to the labeled statement.

    A loop becomes an infinite loop if a condition never becomes false. The for loop is traditionally used for this purpose. Since none of the three expressions that form the ‘for’ loop are required, you can make an endless loop by leaving the conditional expression empty.

    C – Functions

    A function is a group of statements that together perform a task. Every C program has at least one function, which is main(), and all the most trivial programs can define additional functions.

    A function declaration tells the compiler about a function’s name, return type, and parameters. A function definition provides the actual body of the function.

    The C standard library provides numerous built-in functions that your program can call. For example, strcat() to concatenate two strings, memcpy() to copy one memory location to another location, and many more functions.

    A function can also be referred as a method or a sub-routine or a procedure, etc.

    The general form of a function definition in C programming language is as follows −

    return_type function_name( parameter list ) {
       body of the function
    }

    A function definition in C programming consists of a function header and a function body. Here are all the parts of a function −

    • Return Type − A function may return a value. The return_type is the data type of the value the function returns. Some functions perform the desired operations without returning a value. In this case, the return_type is the keyword void.
    • Function Name − This is the actual name of the function. The function name and the parameter list together constitute the function signature.
    • Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value to the parameter. This value is referred to as actual parameter or argument. The parameter list refers to the type, order, and number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters.
    • Function Body − The function body contains a collection of statements that define what the function does.

    A function declaration tells the compiler about a function name and how to call the function. The actual body of the function can be defined separately.

    A function declaration has the following parts − return_type function_name( parameter list );

    Parameter names are not important in function declaration only their type is required.

    While creating a C function, you give a definition of what the function has to do. To use a function, you will have to call that function to perform the defined task.

    When a program calls a function, the program control is transferred to the called function. A called function performs a defined task and when its return statement is executed or when its function-ending closing brace is reached, it returns the program control back to the main program.

    To call a function, you simply need to pass the required parameters along with the function name, and if the function returns a value, then you can store the returned value.

    Like:

    #include <stdio.h>
    int max(int a, int b) { return (a > b) ? a : b; }
    int main() {
        int a = 100, b = 200;
        printf("Max value is : %d\n", max(a, b));
        return 0;
    }

    If a function is to use arguments, it must declare variables that accept the values of the arguments. These variables are called the formal parameters of the function.

    Formal parameters behave like other local variables inside the function and are created upon entry into the function and destroyed upon exit.

    While calling a function, there are two ways in which arguments can be passed to a function −

    • Call by value: This method copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument.
    • Call by reference: This method copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. This means that changes made to the parameter affect the argument.

    By default, C uses call by value to pass arguments. In general, it means the code within a function cannot alter the arguments used to call the function.

    C – Scope Rules

    A scope in any programming is a region of the program where a defined variable can have its existence and beyond that variable it cannot be accessed. There are three places where variables can be declared in C programming language −

    • Inside a function or a block which is called local variables.
    • Outside of all functions which is called global variables.
    • In the definition of function parameters which are called formal parameters.

    Variables that are declared inside a function or block are called local variables. They can be used only by statements that are inside that function or block of code. Local variables are not known to functions outside their own.

    Global variables are defined outside a function, usually on top of the program. Global variables hold their values throughout the lifetime of your program and they can be accessed inside any of the functions defined for the program. A global variable can be accessed by any function. That is, a global variable is available for use throughout your entire program after its declaration.

    A program can have same name for local and global variables but the value of local variable inside a function will take preference.

    Formal parameters, are treated as local variables with-in a function and they take precedence over global variables.

    When a local variable is defined, it is not initialized by the system, you must initialize it yourself. Global variables are initialized automatically by the system when you define them as follows −

    Data TypeInitial Default Value
    int0
    char‘\0’
    float0
    double0
    pointerNULL

    C – Arrays

    Arrays a kind of data structure that can store a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type.

    Instead of declaring individual variables, such as number0, number1, …, and number99, you declare one array variable such as numbers and use numbers[0], numbers[1], and …, numbers[99] to represent individual variables. A specific element in an array is accessed by an index.

    All arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element.

    To declare an array in C, a programmer specifies the type of the elements and the number of elements required by an array as follows −
    type arrayName [ arraySize ];

    This is called a single-dimensional array. The arraySize must be an integer constant greater than zero and type can be any valid C data type, such as – double balance[10];

    You can initialize an array in C either one by one or using a single statement as follows −
    double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

    The number of values between braces { } cannot be larger than the number of elements that we declare for the array between square brackets [ ].

    If you omit the size of the array, an array just big enough to hold the initialization is created. Therefore, if you write −
    double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

    You will create exactly the same array as you did in the previous example.

    The above statement assigns the 5th element in the array with a value of 50.0. All arrays have 0 as the index of their first element which is also called the base index and the last index of an array will be total size of the array minus 1.

    An element is accessed by indexing the array name. This is done by placing the index of the element within square brackets after the name of the array. For example −
    double salary = balance[9];

    The above statement will take the 10th element from the array and assign the value to salary variable.

    The following important concepts related to array should be clear to a C programmer −

    1. Multi-dimensional arrays: C supports multidimensional arrays. The simplest form of the multidimensional array is the two-dimensional array.
    2. Passing arrays to functions: You can pass to the function a pointer to an array by specifying the array’s name without an index.
    3. Return array from a function: C allows a function to return an array.
    4. Pointer to an array: You can generate a pointer to the first element of an array by simply specifying the array name, without any index.

    C – Pointers

    A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before using it to store any variable address. The general form of a pointer variable declaration is −
    type *var-name;

    Here, type is the pointer’s base type; it must be a valid C data type and var-name is the name of the pointer variable. The asterisk * used to declare a pointer is the same asterisk used for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Take a look at some of the valid pointer declarations −

    int    *ip;    /* pointer to an integer */
    double *dp;    /* pointer to a double */
    float  *fp;    /* pointer to a float */
    char   *ch     /* pointer to a character */

    The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

    There are a few important operations, which we will do with the help of pointers very frequently. (a) We define a pointer variable, (b) assign the address of a variable to a pointer and (c) finally access the value at the address available in the pointer variable. This is done by using unary operator * that returns the value of the variable located at the address specified by its operand.

    #include <stdio.h>
    int main() {
        int var = 20; /* actual variable declaration */
        int *ip;      /* pointer variable declaration */
        ip = &var; /* store address of var in pointer variable*/
        printf("Address of var variable: %p\n", &var);
        /* address stored in pointer variable */
        printf("Address stored in ip variable: %p\n", ip);
        /* access the value using the pointer */
        printf("Value of *ip variable: %d\n", *ip);
        return 0;
    }

    It is always a good practice to assign a NULL value to a pointer variable in case you do not have an exact address to be assigned. This is done at the time of variable declaration. A pointer that is assigned NULL is called a null pointer.

    The NULL pointer is a constant with a value of zero defined in several standard libraries.

    Pointers have many but easy concepts and they are very important to C programming. The following important pointer concepts should be clear to any C programmer −

    1. Pointer arithmetic: There are four arithmetic operators that can be used in pointers: ++, –, +, –
    2. Array of pointers: You can define arrays to hold a number of pointers.
    3. Pointer to pointer: C allows you to have pointer on a pointer and so on.
    4. Passing pointers to functions in C: Passing an argument by reference or by address enable the passed argument to be changed in the calling function by the called function.
    5. Return pointer from functions in C: C allows a function to return a pointer to the local variable, static variable, and dynamically allocated memory as well.

    C – Strings

    Strings are actually one-dimensional array of characters terminated by a null character ‘\0’. Thus a null-terminated string contains the characters that comprise the string followed by a null.

    The following declaration and initialization create a string consisting of the word “Hello”. To hold the null character at the end of the array, the size of the character array containing the string is one more than the number of characters in the word “Hello.”

    char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

    Notice that char s[100]="hello"; printf("%d", strlen(s); will output 5 instead of 100;

    If you follow the rule of array initialization then you can write the above statement as follows −
    char greeting[] = "Hello";

    The C compiler automatically places the ‘\0’ at the end of the string when it initializes the array.

    C supports a wide range of functions that manipulate null-terminated strings −

    1. strcpy(s1, s2); Copies string s2 into string s1.
    2. strcat(s1, s2); Concatenates string s2 onto the end of string s1.
    3. strlen(s1); Returns the length of string s1.
    4. strcmp(s1, s2); Returns 0 if s1 and s2 are the same; less than 0 if s1s2.
    5. strchr(s1, ch); Returns a pointer to the first occurrence of character ch in string s1.
    6. strstr(s1, s2); Returns a pointer to the first occurrence of string s2 in string s1.

    C – Structures

    Arrays allow to define type of variables that can hold several data items of the same kind. Similarly structure is another user defined data type available in C that allows to combine data items of different kinds. Structures are used to represent a record.

    To define a structure, you must use the struct statement. The struct statement defines a new data type, with more than one member. The format of the struct statement is as follows −

    struct [structure tag] {
       member definition;
       member definition;
       ...
       member definition;
    } [one or more structure variables];

    struct without a tag has an “anonymous structure type” and you won’t be able to declare another variable of the same type.

    To access any member of a structure, we use the member access operator (.). The member access operator is coded as a period between the structure variable name and the structure member that we wish to access. You would use the keyword struct to define variables of structure type.

    #include <stdio.h>
    #include <string.h>
    struct Books {
        char title[50];
        char author[50];
        char subject[100];
        int book_id;
    };
    int main() {
        struct Books book; /* Declare book of type Book */
        /* book 1 specification */
        // book.title = "C Programming"; // will cause error: array type 'char [50]' is not assignable
        strcpy(book.title, "C Programming");
        strcpy(book.author, "Nuha Ali");
        strcpy(book.subject, "C Programming Tutorial");
        book.book_id = 6495407;
        /* print book info */
        printf("Book title : %s\n", book.title);
        printf("Book author : %s\n", book.author);
        printf("Book subject : %s\n", book.subject);
        printf("Book book_id : %d\n", book.book_id);
        return 0;
    }

    You can pass a structure as a function argument in the same way as you pass any other variable or pointer.

    You can define pointers to structures in the same way as you define pointer to any other variable −
    struct Books *pb = &book;

    To find the address of a structure variable, place the ‘&’; operator before the structure’s name.

    To access the members of a structure using a pointer to that structure, you must use the → operator as follows − pb->id

    #include <stdio.h>
    #include <string.h>
    struct Books {
        char title[50];
        char author[50];
        char subject[100];
        int book_id;
    };
    void printBook(struct Books);
    void updateBookId(struct Books *, int);
    int main() {
        struct Books book, *pb = &book;
        strcpy(book.title, "C Programming");
        strcpy(book.author, "Nuha Ali");
        strcpy(book.subject, "C Programming Tutorial");
        book.book_id = 6495407;
        printBook(book);
        updateBookId(pb, 100);
        strcpy(pb->author, "Alan");
        printBook(book);
        return 0;
    }
    void printBook(struct Books book) {
        printf("Book title : %s\n", book.title);
        printf("Book author : %s\n", book.author);
        printf("Book subject : %s\n", book.subject);
        printf("Book book_id : %d\n", book.book_id);
    }
    void updateBookId(struct Books *book, int id) { book->book_id = id; }

    Bit Fields

    Bit Fields allow the packing of data in a structure. This is especially useful when memory or data storage is at a premium. Typical examples include −

    Packing several objects into a machine word. e.g. 1 bit flags can be compacted.

    Reading external file formats — non-standard file formats could be read in, e.g., 9-bit integers.

    C allows us to do this in a structure definition by putting :bit length after the variable. For example −

    struct packed_struct {
       unsigned int f1:1;
       unsigned int f2:1;
       unsigned int f3:1;
       unsigned int f4:1;
       unsigned int type:4;
       unsigned int my_int:9;
    } pack;

    Here, the packed_struct contains 6 members: Four 1 bit flags f1..f3, a 4-bit type and a 9-bit my_int.

    C automatically packs the above bit fields as compactly as possible, provided that the maximum length of the field is less than or equal to the integer word length of the computer. If this is not the case, then some compilers may allow memory overlap for the fields while others would store the next field in the next word.

    C – Unions

    A union is a special data type available in C that allows to store different data types in the same memory location. You can define a union with many members, but only one member can contain a value at any given time. Unions provide an efficient way of using the same memory location for multiple-purpose.

    To define a union, you must use the union statement in the same way as you did while defining a structure. The union statement defines a new data type with more than one member for your program. The format of the union statement is as follows −

    union [union tag] {
       member definition;
       member definition;
       ...
       member definition;
    } [one or more union variables];

    The union tag is optional and each member definition is a normal variable definition, such as int i; or float f; or any other valid variable definition. At the end of the union’s definition, before the final semicolon, you can specify one or more union variables but it is optional. Here is the way you would define a union type named Data having three members i, f, and str −

    union Data {
       int i;
       float f;
       char str[20];
    } data;

    Now, a variable of Data type can store an integer, a floating-point number, or a string of characters. It means a single variable, i.e., same memory location, can be used to store multiple types of data. You can use any built-in or user defined data types inside a union based on your requirement.

    The memory occupied by a union will be large enough to hold the largest member of the union. For example, in the above example, Data type will occupy 20 bytes of memory space because this is the maximum space which can be occupied by a character string. The following example displays the total memory size occupied by the above union −

    #include <stdio.h>
    #include <string.h>
    union Data {
        int i;
        float f;
        char str[20];
    };
    int main() {
        union Data data;
        printf("Memory size occupied by data : %lu\n", sizeof(data)); //20
        return 0;
    }

    To access any member of a union, we use the member access operator (.). The member access operator is coded as a period between the union variable name and the union member that we wish to access. You would use the keyword union to define variables of union type. The following example shows how to use unions in a program −

    #include <stdio.h>
    #include <string.h>
    union Data {
        int i;
        float f;
        char str[20];
    };
    int main() {
        union Data data;
        data.i = 10;
        data.f = 220.5;
        strcpy(data.str, "C Programming");
        printf("data.i : %d\n", data.i);
        printf("data.f : %f\n", data.f);
        printf("data.str : %s\n", data.str);
        return 0;
    }

    output:

    data.i : 1917853763
    data.f : 4122360580327794860452759994368.000000
    data.str : C Programming

    Here, we can see that the values of i and f members of union got corrupted because the final value assigned to the variable has occupied the memory location and this is the reason that the value of str member is getting printed very well.

    Now let’s look into the same example once again where we will use one variable at a time which is the main purpose of having unions −

    #include <stdio.h>
    #include <string.h>
    union Data {
        int i;
        float f;
        char str[20];
    };
    int main() {
        union Data data;
        data.i = 10;
        printf("data.i : %d\n", data.i);
        data.f = 220.5;
        printf("data.f : %f\n", data.f);
        strcpy(data.str, "C Programming");
        printf("data.str : %s\n", data.str);
        return 0;
    }

    output:

    data.i : 10
    data.f : 220.500000
    data.str : C Programming

    C – Bit Fields

    struct {
       unsigned int widthValidated;
       unsigned int heightValidated;
    } status;

    can be rewritten as:

    struct {
       unsigned int widthValidated : 1;
       unsigned int heightValidated : 1;
    } status;

    The above structure requires 4 bytes of memory space for status variable, but only 2 bits will be used to store the values.

    If you will use up to 32 variables each one with a width of 1 bit, then also the status structure will use 4 bytes. However as soon as you have 33 variables, it will allocate the next slot of the memory and it will start using 8 bytes. Let us check the following example to understand the concept −

    The declaration of a bit-field has the following form inside a structure −

    struct {
       type [member_name] : width ;
    };

    type: An integer type that determines how a bit-field’s value is interpreted. The type may be int, signed int, or unsigned int.

    member_name: The name of the bit-field.

    width: The number of bits in the bit-field. The width must be less than or equal to the bit width of the specified type.

    The variables defined with a predefined width are called bit fields. A bit field can hold more than a single bit; for example, if you need a variable to store a value from 0 to 7, then you can define a bit field with a width of 3 bits as follows −

    struct {
       unsigned int age : 3;
    } Age;

    The above structure definition instructs the C compiler that the age variable is going to use only 3 bits to store the value. If you try to use more than 3 bits, then it will not allow you to do so. Let us try the following example −

    #include <stdio.h>
    #include <string.h>
    struct {
        unsigned int age : 3;
    } Age;
    int main() {
        Age.age = 4;
        printf("Sizeof( Age ) : %lu\n", sizeof(Age));
        printf("Age.age : %d\n", Age.age);
        Age.age = 7;
        printf("Age.age : %d\n", Age.age);
        Age.age = 8;
        printf("Age.age : %d\n", Age.age); // output 0 with warning
        return 0;
    }

    C – typedef

    The C programming language provides a keyword called typedef, which you can use to give a type a new name. Following is an example to define a term BYTE for one-byte numbers −

    typedef unsigned char BYTE;

    After this type definition, the identifier BYTE can be used as an abbreviation for the type unsigned char, for example..

    BYTE b1, b2;

    By convention, uppercase letters are used for these definitions to remind the user that the type name is really a symbolic abbreviation, but you can use lowercase, as follows −

    typedef unsigned char byte;

    You can use typedef to give a name to your user defined data types as well. For example,

    typedef struct Books {
       char title[50];
       char author[50];
       char subject[100];
       int book_id;
    } Book;

    define is a C-directive which is also used to define the aliases for various data types similar to typedef but with the following differences −

    typedef is limited to giving symbolic names to types only where as #define can be used to define alias for values as well, you can define 1 as ONE etc.

    typedef interpretation is performed by the compiler whereas #define statements are processed by the pre-processor.

    C – Input and Output

    When we say Input, it means to feed some data into a program. An input can be given in the form of a file or from the command line. C programming provides a set of built-in functions to read the given input and feed it to the program as per requirement.

    When we say Output, it means to display some data on screen, printer, or in any file. C programming provides a set of built-in functions to output the data on the computer screen as well as to save it in text or binary files.

    C programming treats all the devices as files. So devices such as the display are addressed in the same way as files and the following three files are automatically opened when a program executes to provide access to the keyboard and screen.

    Standard FileFile PointerDevice
    Standard inputstdinKeyboard
    Standard outputstdoutScreen
    Standard errorstderrYour screen

    The file pointers are the means to access the file for reading and writing purpose. This section explains how to read values from the screen and how to print the result on the screen.

    The int getchar(void) function reads the next available character from the screen and returns it as an integer. This function reads only single character at a time. You can use this method in the loop in case you want to read more than one character from the screen.

    The int putchar(int c) function puts the passed character on the screen and returns the same character. This function puts only single character at a time. You can use this method in the loop in case you want to display more than one character on the screen. Check the following example −

    #include <stdio.h>
    int main( ) {
       int c;
       printf( "Enter a value :");
       c = getchar( );
       printf( "\nYou entered: ");
       putchar( c );
       return 0;
    }

    The char *gets(char *s) function reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF (End of File).

    The int puts(const char *s) function writes the string ‘s’ and ‘a’ trailing newline to stdout.

    NOTE: Though it has been deprecated to use gets() function, Instead of using gets, you want to use fgets().

    #include <stdio.h>
    int main() {
        char str[100];
        printf("Enter a value :");
        // gets(str); warning: this program uses gets(), which is unsafe.
        fgets(str, 100, stdin);
        printf("You entered: ");
        puts(str);
        return 0;
    }

    The int scanf(const char *format, …) function reads the input from the standard input stream stdin and scans that input according to the format provided.

    The int printf(const char *format, …) function writes the output to the standard output stream stdout and produces the output according to the format provided.

    The format can be a simple constant string, but you can specify %s, %d, %c, %f, etc., to print or read strings, integer, character or float respectively. There are many other formatting options available which can be used based on requirements. Let us now proceed with a simple example to understand the concepts better −

    Here, it should be noted that scanf() expects input in the same format as you provided %s and %d, which means you have to provide valid inputs like “string integer”. If you provide “string string” or “integer integer”, then it will be assumed as wrong input. Secondly, while reading a string, scanf() stops reading as soon as it encounters a space, so “this is test” are three strings for scanf().

    C – File I/O

    A file represents a sequence of bytes, regardless of it being a text file or a binary file. C programming language provides access on high level functions as well as low level (OS level) calls to handle file on your storage devices.

    You can use the fopen( ) function to create a new file or to open an existing file. This call will initialize an object of the type FILE, which contains all the information necessary to control the stream. The prototype of this function call is as follows −

    FILE *fopen( const char * filename, const char * mode );

    Here, filename is a string literal, which you will use to name your file, and access mode can have one of the following values −

    1. r: Opens an existing text file for reading purpose.
    2. w: Opens a text file for writing. If it does not exist, then a new file is created. Here your program will start writing content from the beginning of the file.
    3. a: Opens a text file for writing in appending mode. If it does not exist, then a new file is created. Here your program will start appending content in the existing file content.
    4. r+: Opens a text file for both reading and writing.
    5. w+: Opens a text file for both reading and writing. It first truncates the file to zero length if it exists, otherwise creates a file if it does not exist.
    6. a+: Opens a text file for both reading and writing. It creates the file if it does not exist. The reading will start from the beginning but writing can only be appended.

    If you are going to handle binary files, then you will use following access modes instead of the above mentioned ones −

    "rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"

    To close a file, use the fclose( ) function. The prototype of this function is −

    int fclose( FILE *fp );

    The fclose(-) function returns zero on success, or EOF if there is an error in closing the file. This function actually flushes any data still pending in the buffer to the file, closes the file, and releases any memory used for the file. The EOF is a constant defined in the header file stdio.h.

    Following is the simplest function to write individual characters to a stream −

    int fputc( int c, FILE *fp );

    The function fputc() writes the character value of the argument c to the output stream referenced by fp. It returns the written character written on success otherwise EOF if there is an error. You can use the following functions to write a null-terminated string to a stream −

    int fputs( const char *s, FILE *fp );

    The function fputs() writes the string s to the output stream referenced by fp. It returns a non-negative value on success, otherwise EOF is returned in case of any error. You can use int fprintf(FILE *fp,const char *format, …) function as well to write a string into a file.

    #include <stdio.h>
    int main() {
       FILE *fp;
       fp = fopen("test.log", "w+");
       fprintf(fp, "This is testing for fprintf...\n");
       fputs("This is testing for fputs...\n", fp);
       fclose(fp);
    }

    Given below is the simplest function to read a single character from a file −

    int fgetc( FILE * fp );

    The fgetc() function reads a character from the input file referenced by fp. The return value is the character read, or in case of any error, it returns EOF. The following function allows to read a string from a stream −

    char *fgets( char *buf, int n, FILE *fp );

    The functions fgets() reads up to n-1 characters from the input stream referenced by fp. It copies the read string into the buffer buf, appending a null character to terminate the string.

    If this function encounters a newline character ‘\n’ or the end of the file EOF before they have read the maximum number of characters, then it returns only the characters read up to that point including the new line character. You can also use int fscanf(FILE *fp, const char *format, ...) function to read strings from a file, but it stops reading after encountering the first space character.

    There are two functions, that can be used for binary input and output −

    size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);

    size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);

    Both of these functions should be used to read or write blocks of memories – usually arrays or structures.

    C – Preprocessors

    The C Preprocessor is not a part of the compiler, but is a separate step in the compilation process. In simple terms, a C Preprocessor is just a text substitution tool and it instructs the compiler to do required pre-processing before the actual compilation. We’ll refer to the C Preprocessor as CPP.

    All preprocessor commands begin with a hash symbol (#). It must be the first nonblank character, and for readability, a preprocessor directive should begin in the first column. The following section lists down all the important preprocessor directives −

    1. #define: Substitutes a preprocessor macro.
    2. #include: Inserts a particular header from another file.
    3. #undef: Undefines a preprocessor macro.
    4. #ifdef: Returns true if this macro is defined.
    5. #ifndef: Returns true if this macro is not defined.
    6. #if: Tests if a compile time condition is true.
    7. #else: The alternative for #if.
    8. #elif: #else and #if in one statement.
    9. #endif: Ends preprocessor conditional.
    10. #error: Prints error message on stderr.
    11. #pragma: Issues special commands to the compiler, using a standardized method.

    Examples:

    #define MAX_ARRAY_LENGTH 20

    This directive tells the CPP to replace instances of MAX_ARRAY_LENGTH with 20. Use #define for constants to increase readability.

    #include <stdio.h>
    #include "myheader.h"

    These directives tell the CPP to get stdio.h from System Libraries and add the text to the current source file. The next line tells CPP to get myheader.h from the local directory and add the content to the current source file.

    #undef  FILE_SIZE
    #define FILE_SIZE 42

    It tells the CPP to undefine existing FILE_SIZE and define it as 42.

    #ifndef MESSAGE
       #define MESSAGE "You wish!"
    #endif

    It tells the CPP to define MESSAGE only if MESSAGE isn’t already defined.

    #ifdef DEBUG
       /* Your debugging statements here */
    #endif

    It tells the CPP to process the statements enclosed if DEBUG is defined. This is useful if you pass the -DDEBUG flag to the gcc compiler at the time of compilation. This will define DEBUG, so you can turn debugging on and off on the fly during compilation.

    ANSI C defines a number of macros. Although each one is available for use in programming, the predefined macros should not be directly modified.

    1. DATE The current date as a character literal in “MMM DD YYYY” format.
    2. TIME The current time as a character literal in “HH:MM:SS” format.
    3. FILE This contains the current filename as a string literal.
    4. LINE This contains the current line number as a decimal constant.
    5. STDC Defined as 1 when the compiler complies with the ANSI standard.

    The C preprocessor offers the following operators to help create macros −

    The Macro Continuation () Operator

    A macro is normally confined to a single line. The macro continuation operator () is used to continue a macro that is too long for a single line. For example −

    #define  message_for(a, b)  \
       printf(#a " and " #b ": We love you!\n")

    The Stringize (#) Operator

    The stringize or number-sign operator ( ‘#’ ), when used within a macro definition, converts a macro parameter into a string constant. This operator may be used only in a macro having a specified argument or parameter list. For example −

    #include <stdio.h>
    #define  message_for(a, b)  \
           printf(#a " and " #b ": We love you!\n")
    int main(void) {
       message_for(Carole, Debra);
       return 0;
    }

    The Token Pasting (##) Operator

    The token-pasting operator (##) within a macro definition combines two arguments. It permits two separate tokens in the macro definition to be joined into a single token. For example −

    #include <stdio.h>
    #define tokenpaster(n) printf("token" #n " = %d\n", token##n)
    int main(void) {
        int token34 = 40;
        int token35 = 50;
        tokenpaster(34); // = printf ("token34 = %d", token34);
        tokenpaster(35);
        return 0;
    }

    The Defined() Operator

    The preprocessor defined operator is used in constant expressions to determine if an identifier is defined using #define. If the specified identifier is defined, the value is true (non-zero). If the symbol is not defined, the value is false (zero). The defined operator is specified as follows −

    #include <stdio.h>
    #if !defined(MESSAGE)
        #define MESSAGE "You wish!"
    #endif
    int main(void) {
        printf("Here is the message: %s\n", MESSAGE);
        return 0;
    }

    Parameterized Macros

    One of the powerful functions of the CPP is the ability to simulate functions using parameterized macros. For example, we might have some code to square a number as follows −

    int square(int x) {return x * x;}

    We can rewrite above the code using a macro as follows −

    #define square(x) ((x) * (x))

    Macros with arguments must be defined using the #define directive before they can be used. The argument list is enclosed in parentheses and must immediately follow the macro name. Spaces are not allowed between the macro name and open parenthesis. For example −

    #include <stdio.h>
    #define MAX(x, y) ((x) > (y) ? (x) : (y))
    int main(void) {
        printf("Max between 20 and 10 is %d\n", MAX(10, 20));
        return 0;
    }

    C – Header Files

    A header file is a file with extension .h which contains C function declarations and macro definitions to be shared between several source files. There are two types of header files: the files that the programmer writes and the files that comes with your compiler.

    You request to use a header file in your program by including it with the C preprocessing directive #include, like you have seen inclusion of stdio.h header file, which comes along with your compiler.

    Including a header file is equal to copying the content of the header file but we do not do it because it will be error-prone and it is not a good idea to copy the content of a header file in the source files, especially if we have multiple source files in a program.

    A simple practice in C or C++ programs is that we keep all the constants, macros, system wide global variables, and function prototypes in the header files and include that header file wherever it is required.

    Both the user and the system header files are included using the preprocessing directive #include. It has the following two forms −

    #include <file>

    This form is used for system header files. It searches for a file named ‘file’ in a standard list of system directories. You can prepend directories to this list with the -I option while compiling your source code.

    #include "file"

    This form is used for header files of your own program. It searches for a file named ‘file’ in the directory containing the current file. You can prepend directories to this list with the -I option while compiling your source code.

    The #include directive works by directing the C preprocessor to scan the specified file as input before continuing with the rest of the current source file. The output from the preprocessor contains the output already generated, followed by the output resulting from the included file, followed by the output that comes from the text after the #include directive. For example, if you have a header file header.h as follows −

    char *test (void);

    and a main program called program.c that uses the header file, like this −

    int x;
    #include "header.h"
    int main (void) {
       puts (test ());
    }

    the compiler will see the same token stream as it would if program.c read.

    int x;
    char *test (void);
    int main (void) {
       puts (test ());
    }

    If a header file happens to be included twice, the compiler will process its contents twice and it will result in an error. The standard way to prevent this is to enclose the entire real contents of the file in a conditional, like this −

    #ifndef HEADER_FILE
    #define HEADER_FILE
    the entire header file file
    #endif

    This construct is commonly known as a wrapper #ifndef. When the header is included again, the conditional will be false, because HEADER_FILE is defined. The preprocessor will skip over the entire contents of the file, and the compiler will not see it twice.

    Sometimes it is necessary to select one of the several different header files to be included into your program. For instance, they might specify configuration parameters to be used on different sorts of operating systems. You could do this with a series of conditionals as follows −

    #if SYSTEM_1
       # include "system_1.h"
    #elif SYSTEM_2
       # include "system_2.h"
    #elif SYSTEM_3
       ...
    #endif

    But as it grows, it becomes tedious, instead the preprocessor offers the ability to use a macro for the header name. This is called a computed include. Instead of writing a header name as the direct argument of #include, you simply put a macro name there −

    #define SYSTEM_H "system_1.h"
    ...
    #include SYSTEM_H

    SYSTEM_H will be expanded, and the preprocessor will look for system_1.h as if the #include had been written that way originally. SYSTEM_H could be defined by your Makefile with a -D option.

    C – Type Casting

    Type casting is a way to convert a variable from one data type to another data type. For example, if you want to store a ‘long’ value into a simple integer then you can type cast ‘long’ to ‘int’. You can convert the values from one type to another explicitly using the cast operator as follows −

    (type_name) expression

    Consider the following example where the cast operator causes the division of one integer variable by another to be performed as a floating-point operation −

    #include <stdio.h>
    main() {
       int sum = 17, count = 5;
       double mean;
       mean = (double) sum / count;
       printf("Value of mean : %f\n", mean ); // Value of mean : 3.400000
    }

    It should be noted here that the cast operator has precedence over division, so the value of sum is first converted to type double and finally it gets divided by count yielding a double value.

    Type conversions can be implicit which is performed by the compiler automatically, or it can be specified explicitly through the use of the cast operator. It is considered good programming practice to use the cast operator whenever type conversions are necessary.

    Integer promotion is the process by which values of integer type “smaller” than int or unsigned int are converted either to int or unsigned int. Consider an example of adding a character with an integer −

    #include <stdio.h>
    int main() {
        int i = 17;
        char c = 'c'; /* ascii value is 99 */
        int sum = i + c;
        printf("Value of sum : %d\n", sum); //Value of sum : 116
    }

    The usual arithmetic conversions are implicitly performed to cast their values to a common type. The compiler first performs integer promotion; if the operands still have different types, then they are converted to the type that appears highest in the following hierarchy −

    int->unsigned int->long->unsigned long->long long->unsigned long long->float->double->long double

    The usual arithmetic conversions are not performed for the assignment operators, nor for the logical operators && and ||. Let us take the following example to understand the concept −

    #include <stdio.h>
    int main() {
        int i = 17;
        char c = 'c'; /* ascii value is 99 */
        float sum = i + c;
        printf("Value of sum : %f\n", sum); // Value of sum : 116.000000
    }

    Here, it is simple to understand that first c gets converted to integer, but as the final value is double, usual arithmetic conversion applies and the compiler converts i and c into ‘float’ and adds them yielding a ‘float’ result.

    C – Error Handling

    As such, C programming does not provide direct support for error handling but being a system programming language, it provides you access at lower level in the form of return values. Most of the C or even Unix function calls return -1 or NULL in case of any error and set an error code errno. It is set as a global variable and indicates an error occurred during any function call. You can find various error codes defined in header file.

    So a C programmer can check the returned values and can take appropriate action depending on the return value. It is a good practice, to set errno to 0 at the time of initializing a program. A value of 0 indicates that there is no error in the program.

    The C programming language provides perror() and strerror() functions which can be used to display the text message associated with errno.

    The perror() function displays the string you pass to it, followed by a colon, a space, and then the textual representation of the current errno value.

    The strerror() function, which returns a pointer to the textual representation of the current errno value.

    Let’s try to simulate an error condition and try to open a file which does not exist. Here I’m using both the functions to show the usage, but you can use one or more ways of printing your errors. Second important point to note is that you should use stderr file stream to output all the errors.

    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    extern int errno;
    int main() {
        FILE *pf;
        int errnum;
        pf = fopen("unexist.txt", "rb");
        if (pf == NULL) {
            errnum = errno;
            fprintf(stderr, "Value of errno: %d\n", errno);
            perror("Error printed by perror");
            fprintf(stderr, "Error opening file: %s\n", strerror(errnum));
        } else {
            fclose(pf);
        }
        return 0;
    }

    output:

    Value of errno: 2
    Error printed by perror: No such file or directory
    Error opening file: No such file or directory

    It is a common problem that at the time of dividing any number, programmers do not check if a divisor is zero and finally it creates a runtime error.

    The code below fixes this by checking if the divisor is zero before dividing −

    #include <stdio.h>
    #include <stdlib.h>
    int main() {
        int dividend = 20;
        int divisor = 0;
        int quotient;
        if (divisor == 0) {
            fprintf(stderr, "Division by zero! Exiting...\n");
            exit(-1);
        }
        quotient = dividend / divisor;
        fprintf(stderr, "Value of quotient : %d\n", quotient);
        exit(0);
    }

    It is a common practice to exit with a value of EXIT_SUCCESS in case of program coming out after a successful operation. Here, EXIT_SUCCESS is a macro and it is defined as 0.

    If you have an error condition in your program and you are coming out then you should exit with a status EXIT_FAILURE which is defined as -1. So let’s write above program as follows −

    #include <stdio.h>
    #include <stdlib.h>
    int main() {
        int dividend = 20;
        int divisor = 5;
        int quotient;
        if (divisor == 0) {
            fprintf(stderr, "Division by zero! Exiting...\n");
            exit(EXIT_FAILURE);
        }
        quotient = dividend / divisor;
        fprintf(stderr, "Value of quotient : %d\n", quotient);
        exit(EXIT_SUCCESS);
    }

    C – Recursion

    Recursion is the process of repeating items in a self-similar way. In programming languages, if a program allows you to call a function inside the same function, then it is called a recursive call of the function.

    void recursion() {
       recursion(); /* function calls itself */
    }

    The C programming language supports recursion, i.e., a function to call itself. But while using recursion, programmers need to be careful to define an exit condition from the function, otherwise it will go into an infinite loop.

    Recursive functions are very useful to solve many mathematical problems, such as calculating the factorial of a number, generating Fibonacci series, etc.

    The following example calculates the factorial of a given number using a recursive function −

    #include <stdio.h>
    #define N 200
    long double fibonacci(unsigned int i) {
        static long double f[N];
        if (i <= 1) {
            f[i] = i;
        } else {
            if (f[i] == 0) {
                f[i]= fibonacci(i - 1) + fibonacci(i - 2);
            }
        }
        return f[i];
    }
    int main() {
        int i;
        for (i = 0; i < N; i++) {
            printf("%Lf\t\n", fibonacci(i));
        }
        return 0;
    }

    C – Variable Arguments

    Sometimes, you may come across a situation, when you want to have a function, which can take variable number of arguments, i.e., parameters, instead of predefined number of parameters. The C programming language provides a solution for this situation and you are allowed to define a function which can accept variable number of parameters based on your requirement. The following example shows the definition of such a function.

    int func(int, ... ) {
       .
    }
    int main() {
       func(1, 2, 3);
       func(1, 2, 3, 4);
    }

    It should be noted that the function func() has its last argument as ellipses, i.e. three dotes (…) and the one just before the ellipses is always an int which will represent the total number variable arguments passed. To use such functionality, you need to make use of stdarg.h header file which provides the functions and macros to implement the functionality of variable arguments and follow the given steps −

    • Define a function with its last parameter as ellipses and the one just before the ellipses is always an int which will represent the number of arguments.
    • Create a va_list type variable in the function definition. This type is defined in stdarg.h header file.
    • Use int parameter and va_start macro to initialize the va_list variable to an argument list. The macro va_start is defined in stdarg.h header file.
    • Use va_arg macro and va_list variable to access each item in argument list.
    • Use a macro va_end to clean up the memory assigned to va_list variable.

    Now let us follow the above steps and write down a simple function which can take the variable number of parameters and return their average −

    #include <stdarg.h>
    #include <stdio.h>
    double average(int num, ...) {
        va_list valist;
        double sum = 0.0;
        int i;
        /* initialize valist for num number of arguments */
        va_start(valist, num);
        /* access all the arguments assigned to valist */
        for (i = 0; i < num; i++) {
            sum += va_arg(valist, int);
        }
        /* clean memory reserved for valist */
        va_end(valist);
        return sum / num;
    }
    int main() {
        printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2, 3, 4, 5));
        printf("Average of 5, 10, 15 = %f\n", average(3, 5, 10, 15));
    }

    C – Memory Management

    The C programming language provides several functions for memory allocation and management. These functions can be found in the header file.

    1. void *calloc(int num, int size); This function allocates an array of num elements each of which size in bytes will be size.
    2. void free(void *address); This function releases a block of memory block specified by address.
    3. void *malloc(int num); This function allocates an array of num bytes and leave them uninitialized.
    4. void *realloc(void *address, int newsize); This function re-allocates memory extending it upto newsize.

    While programming, if you are aware of the size of an array, then it is easy and you can define it as an array. For example, to store a name of any person, it can go up to a maximum of 100 characters, so you can define something as follows −

    char name[100];

    But now let us consider a situation where you have no idea about the length of the text you need to store, for example, you want to store a detailed description about a topic. Here we need to define a pointer to character without defining how much memory is required and later, based on requirement, we can allocate memory as shown in the below example −

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main() {
        char name[100];
        char *description;
        strcpy(name, "Zara Ali");
        /* allocate memory dynamically */
        // description = malloc(200 * sizeof(char));
        description = calloc(200, sizeof(char));
        if (description == NULL) {
            fprintf(stderr, "Error - unable to allocate required memory\n");
        } else {
            strcpy(description, "Zara ali a DPS student in class 10th");
        }
        printf("Name = %s\n", name);
        printf("Description: %s\n", description);
    }

    When your program comes out, operating system automatically release all the memory allocated by your program but as a good practice when you are not in need of memory anymore then you should release that memory by calling the function free().

    Alternatively, you can increase or decrease the size of an allocated memory block by calling the function realloc(). Let us check the above program once again and make use of realloc() and free() functions −

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main() {
        char name[100];
        char *description;
        strcpy(name, "Zara Ali");
        /* allocate memory dynamically */
        description = malloc(30 * sizeof(char));
        if (description == NULL) {
            fprintf(stderr, "Error - unable to allocate required memory\n");
        } else {
            strcpy(description, "Zara ali a DPS student.");
        }
        /* suppose you want to store bigger description */
        description = realloc(description, 100 * sizeof(char));
        if (description == NULL) {
            fprintf(stderr, "Error - unable to allocate required memory\n");
        } else {
            strcat(description, "She is in class 10th");
        }
        printf("Name = %s\n", name);
        printf("Description: %s\n", description);
        /* release memory using free() function */
        free(description);
        return 0;
    }

    C – Command Line Arguments

    It is possible to pass some values from the command line to your C programs when they are executed. These values are called command line arguments and many times they are important for your program especially when you want to control your program from outside instead of hard coding those values inside the code.

    The command line arguments are handled using main() function arguments where argc refers to the number of arguments passed, and argv[] is a pointer array which points to each argument passed to the program. Following is a simple example which checks if there is any argument supplied from the command line and take action accordingly −

    #include <stdio.h>
    int main(int argc, char *argv[]) {
        printf("Program name %s\n", argv[0]);
        if (argc == 2) {
            printf("The argument supplied is %s\n", argv[1]);
        } else if (argc > 2) {
            printf("Too many arguments supplied.\n");
        } else {
            printf("One argument expected.\n");
        }
    }

    It should be noted that argv[0] holds the name of the program itself and argv[1] is a pointer to the first command line argument supplied, and *argv[n] is the last argument. If no arguments are supplied, argc will be one, and if you pass one argument then argc is set at 2.

    You pass all the command line arguments separated by a space, but if argument itself has a space then you can pass such arguments by putting them inside double quotes “” or single quotes ”.

  • 2019-12-13-the-c-programming-language-notes

    The C Programming Language Notes

    ch1 A Tutorial Introduction p22-p46

    1. Getting Started
      printf(“hello, world\n”);
    2. Variables and Arithmetic Expressions
      celsius = 5 * (fahr-32) / 9;
    3. The for statement
      for (fahr = 0; fahr <= 300; fahr = fahr + 20) printf(“%3d %6.1f\n”, fahr, (5.0/9.0)*(fahr-32));
    4. Symbolic Constants
      #define UPPER 300
    5. Character Input and Output c = getchar(); putchar(c);
      1. File Copying
      2. Character Counting
      3. Line Counting
      4. Word Counting
    6. Arrays
      int ndigit[10];
    7. Functions
      A function provides a convenient way to encapsulate some computation, which can then be used without worrying about its implementation.
    8. Arguments – Call by Value
      In C, all function arguments are passed “by value.” This means that the called function is given the values of its arguments in temporary variables rather than the originals.
    9. Character Arrays
      Character array is stored as an array of characters containing the characters in the string and terminated with a ‘\0’ to mark the end.
    10. External Variables and Scope
      An external variable must be defined, exactly once, outside of any function; this sets aside storage for it.

    ch2 Types, Operators and Expressions p47-p63

    1. Variable Names
      Names are made up of letters and digits; the first character must be a letter. The underscore “_” counts as a letter; it is sometimes useful for improving the readability of long variable names. Don’t begin variable names with underscore, however, since library routines often use such names. Upper and lower case letters are distinct, so x and X are two different names.
    2. Data Types and Sizes
      There are only a few basic data types in C: char, int, float, double
    3. Constants
      A long constant is written with a terminal l (ell) or L, as in 123456789L; an integer constant too big to fit into an int will also be taken as a long. Unsigned constants are written with a terminal u or U, and the suffix ul or UL indicates unsigned long.
      The first name in an enum has value 0, the next 1, and so on, unless explicit values are specified.
    4. Declarations
      All variables must be declared before use, although certain declarations can be made implicitly by content.
    5. Arithmetic Operators
      The binary arithmetic operators are +, -, *, /, and the modulus operator %.
    6. Relational and Logical Operators
      The relational operators are > >= < <=. Expressions connected by && or || are evaluated left to right, and evaluation stops as soon as the truth or falsehood of the result is known.
    7. Type Conversions
      When an operator has operands of different types, they are converted to a common type according to a small number of rules.
    8. Increment and Decrement Operators
      The increment operator ++ adds 1 to its operand, while the decrement operator — subtracts 1.
    9. Bitwise Operators
      The bitwise exclusive OR operator ^ sets a one in each bit position where its operands have different bits, and zero where they are the same.
    10. Assignment Operators and Expressions
      i += 2 is equivalent to i = i + 2
    11. Conditional Expressions
      z = (a > b) ? a : b;
    12. Precedence and Order of Evaluation
      x = f() + g();
      f may be evaluated before g or vice versa; thus if either f or g alters a variable on which the other depends, x can depend on the order of evaluation.

    ch3 Control Flow p64-p74

    1. Statements and Blocks
      x = 0; Braces { and } are used to group declarations and statements together into a compound statement, or block, so that they are syntactically equivalent to a single statement.
    2. If-Else
      if (a > b) z = a; else z = b;
    3. Else-If
      if (expression)
      statement
      else if (expression)
      statement
      else
      statement
    4. Switch
      switch (expression) {
      case const-expr: statements
      case const-expr: statements
      default: statements
      }
    5. Loops – While and For
      while (expression)
      statement
      for (expr1; expr2; expr3)
      statement
    6. Loops – Do-While
      do
      statement
      while (expression);
    7. Break and Continue
      The break statement provides an early exit from for, while, and do, just as from switch. The continue statement causes the next iteration of the enclosing for, while, or do loop to begin.
    8. Goto and labels
      C provides the infinitely-abusable goto statement, and labels to branch to.

    ch4 Functions and Program Structure p75-p95

    1. Basics of Functions
      cc main.c getline.c strindex.c -o grep.exe
    2. Functions Returning Non-integers
      double atof(char s[])
    3. External Variables
      A C program consists of a set of external objects, which are either variables or functions.
    4. Scope Rules
      If an external variable is to be referred to before it is defined, or if it is defined in a different source file from the one where it is being used, then an extern declaration is mandatory.
      in file1: extern int sp;
      in file2: int sp = 0;
    5. Header Files
      #include “calc.h”
    6. Static Variables
      The static declaration, applied to an external variable or function, limits the scope of that object to the rest of the source file being compiled.
    7. Register Variables
      A register declaration advises the compiler that the variable in question will be heavily used.
    8. Block Structure
      Declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that begins a function.
    9. Initialization
      In the absence of explicit initialization, external and static variables are guaranteed to be initialized to zero; automatic and register variables have undefined (i.e., garbage) initial values.
      char pattern[] = { ‘o’, ‘u’, ‘l’, ‘d’, ‘\0’ };// char pattern = “ould”; wouldn’t work.
    10. Recursion
      C functions may be used recursively; that is, a function may call itself either directly or indirectly.
    11. The C Preprocessor
      1. File Inclusion
        If the filename is quoted, searching for the file typically begins where the source program was found; if it is not found there, or if the name is enclosed in < and >, searching follows an implementation-defined rule to find the file.
      2. Macro Substitution
        The scope of a name defined with #define is from its point of definition to the end of the source file being compiled.
        #define max(A, B) ((A) > (B) ? (A) : (B))
        The expressions are evaluated twice; this is bad if they involve side effects like increment operators or input and output.
        #define dprint(expr) printf(#expr ” = %g\n”, expr)
        If 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.
      3. Conditional Inclusion
        It is possible to control preprocessing itself with conditional statements that are evaluated during preprocessing.

    ch5 pointer p96-125

    1. Pointers and Addresses
      int x=1, y;
      int *p; p=&x; y = *p;
    2. Pointers and Function Arguments
      void swap(int *px, int *py)
      swap(&a, &b);
    3. Pointers and Arrays
      int a[10], *pa, x;
      pa = &a[i]; // pa = a+i;
      x = *pa; // x= a[0];
      x = *(pa+1); // x = a[1]; x= *(a+1)
      f(&a[2]); // f(a+2)
    4. Address Arithmetic
      int *ptr; ptr = (int *)malloc(1024 * sizeof(ptr));
    5. Character Pointers and Functions
      char amessage[] = “now is the time”; /* an array */
      char *pmessage = “now is the time”; /* a pointer */
      void strcpy(char *s, char t){ while (s++ = *t++);
      }
    6. Pointer Arrays; Pointers to Pointers
      char lineptr[MAXLINES]; / pointers to text lines */
      lineptr[i] is a character pointer, *lineptr[i] is the character it points to.
    7. Multi-dimensional Arrays
      static char daytab[2][13] = {
      {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
      {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
      };
      int *daytab[13] is an array of 13 pointers to integers.
      daytab[i] is a integer pointer, *daytab[i] is the interger it points to.
    8. Initialization of Pointer Arrays
      char *month_name(int n)
      {
      static char *name[] = {
      “Illegal month”,
      “January”, “February”, “March”,
      “April”, “May”, “June”,
      “July”, “August”, “September”,
      “October”, “November”, “December”
      };
      return (n < 1 || n > 12) ? name[0] : name[n];
      }
    9. Pointers vs. Multi-dimensional Arrays
      int a[10][20]; //fixed size
      int *b[10]; // initialization must be done explicitly, either statically or with code.
    10. Command-line Arguments
      int main(int argc, char *argv[])
      For “echo hello, world” command, argc is 3, and argv[0], argv[1], and argv[2] are “echo”, “hello,”, and “world” respectively.
    11. Pointers to Functions
      void qsort(void lineptr[], int left, int right, int (comp)(void *, void *));
      int (*comp)(void *, void *) says that comp is a pointer to a function that has two void * arguments and returns an int.
      call pointer to function with
      (*comp)(v[i], v[left]) // comp(v[i],v[left]) also works, because a function’s name can also be used to get functions’ address.
    12. Complicated Declarations
      void comp() // comp: function returning pointer to void void (comp)() // comp: pointer to function returning void

    ch6 struct p126-p146

    1. Basics of Structures
      struct point {int x; int y;} x, y, z; // similar to int x, y, z;
    2. Structures and Functions
      legal operations to a struct: copy, assign it as a unit, take address by &, accessing its member.
      struct point makepoint(int x, int y)
      {
      struct point temp;
      temp.x = x;
      temp.y = y;
      return temp;
      }
      struct point pp; access x by(pp).x or pp->x;
    3. Arrays of Structures
      struct key {
      char *word;
      int count;
      } keytab[NKEYS];
      //equals
      struct key {
      char *word;
      int count;
      };
      struct key keytab[NKEYS];
    4. Pointers to Structures
      struct key *binsearch(char *word, struct key *tab, int n)
      pointer arithmetic that involves the first element beyond the end of an array (that is, &tab[n]) will work correctly.
    5. Self-referential Structures
      struct tnode{
      char *word;
      int count;
      struct tnode *left;
      struct tnode *right;
      }
    6. Table Lookup
      struct nlist *lookup(char *s)
      for (ptr = head; ptr != NULL; ptr = ptr->next)
    7. Typedef
      typedef int Length;
      typedef char *String;
      String p, lineptr[MAXLINES], alloc(int);
      int strcmp(String, String);
      p = (String) malloc(100);
    8. Unions
      union u_tag {
      int ival;
      float fval;
      char *sval;
      } u;
      struct {
      char *name;
      int flags;
      int utype;
      union {
      int ival;
      float fval;
      char *sval;
      } u;
      } symtab[NSYM];
    9. Bit-fields
      struct {
      unsigned int is_keyword : 1;
      unsigned int is_extern : 1;
      unsigned int is_static : 1;
      } flags;
      flags that contains three 1-bit fields

    ch7 Input and Output p147-p161

    1. Standard Input and Output
      while ((c = getchar()) != EOF) putchar(tolower(c));
    2. Formatted Output – printf
      int printf(char *format, arg1, arg2, …);
    3. Variable-length Argument Lists
      void minprintf(char *fmt, …)
    4. Formatted Input – Scanf
      int scanf(char *format, …)
    5. File Access
      FILE *fp;p
    6. Error Handling – Stderr and Exit
      fprintf(stderr, “%s: can’t open %s\n”, prog, *argv);
    7. Line Input and Output
      char *fgets(char *line, int maxline, FILE *fp)
      int fputs(char *line, FILE *fp)
    8. Miscellaneous Functions
      system(“date”);
      #define frand() ((double) rand() / (RAND_MAX+1.0))

    ch8 The UNIX System Interface p162-178

    1. File Descriptors
      prog outfile
    2. Low Level I/O – Read and Write
      int n_read = read(int fd, char *buf, int n);
      int n_written = write(int fd, char *buf, int n);
    3. Open, Creat, Close, Unlink
      int open(char *name, int flags, int perms);
      int creat(char *name, int perms);
    4. Random Access – Lseek
      long lseek(int fd, long offset, int origin);
    5. Example – An implementation of Fopen and Getc
      FILE *fopen(char *name, char *mode)
    6. Example – Listing Directories
      void fsize(char *name)
      void dirwalk(char *dir, void (*fcn)(char *))
    7. Example – A Storage Allocator
      void *malloc(unsigned nbytes)

    Appendix A: Reference Manual p179-p233

    1. Introduction
    2. Lexical Conventions
      There are six classes of tokens: identifiers, keywords, constants, string literals, operators, and other separators.
      Upper and lower case letters are different.
      Keywords auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while
    3. Syntax Notation
      { expression\sub(opt) } means an optional expression, enclosed in braces.
    4. Meaning of Identifiers
      Identifiers, or names, refer to a variety of things: functions; tags of structures, unions, and enumerations; members of structures or unions; enumeration constants; typedef names; and objects.
      There are two storage classes: automatic and static.
    5. Objects and Lvalues
      An Object is a named region of storage; an lvalue is an expression referring to an object.
    6. Conversions
      Integral Promotion, Integral Conversions, Integer and Floating, Floating Types, Arithmetic Conversions, Pointers and Integers
    7. Expressions
      A pair of expressions separated by a comma is evaluated left-to-right, and the value of the left expression is discarded.
    8. Declarations
      In a declaration T D:
      When D is an unadored identifier, the type of the identifier is T.
      When D has the form ( D1 ) then the type of the identifier in D1 is the same as that of D. The parentheses do not alter the type, but may change the binding of complex declarators.
      int i, *pi, *const cpi = &i;
      const int ci = 3, *pci;
      declare an integer i and a pointer to an integer pi. The value of the constant pointer cpi may not be changed; it will always point to the same location, although the value to which it refers may be altered. The integer ci is constant, and may not be changed (though it may be initialized, as here.) The type of pci is “pointer to const int,” and pci itself may be changed to point to another place, but the value to which it points may not be altered by assigning through pci.
    9. Statements
      Except as described, statements are executed in sequence.
    10. External Declarations
      The unit of input provided to the C compiler is called a translation unit; it consists of a sequence of external declarations, which are either declarations or function definitions.
    11. Scope and Linkage
      A program need not all be compiled at one time: the source text may be kept in several files containing translation units, and precompiled routines may be loaded from libraries.
    12. Preprocessor
      A preprocessor performs macro substitution, conditional compilation, and inclusion of named files.
    13. Grammar
      A recapitulation of the grammar that was given throughout the earlier part of this appendix.

    Appendix B – Standard Library p234-p296

    1. Input and Output: The input and output functions, types, and macros defined in represent nearly one third of the library.
      1. File Operations
      2. Formatted Output
      3. Formatted Input
      4. Character Input and Output Functions
      5. Direct Input and Output Functions
      6. File Positioning Functions
      7. Error Functions
    2. Character Class Tests:
      The header declares functions for testing characters.
    3. String Functions:
      There are two groups of string functions defined in the header . The first have names beginning with str; the second have names beginning with mem.
    4. Mathematical Functions:
      The header declares mathematical functions and macros.
    5. Utility Functions:
      The header declares functions for number conversion, storage allocation, and similar tasks.
    6. Diagnostics:
      The assert macro is used to add diagnostics to programs.
    7. Variable Argument Lists:
      The header provides facilities for stepping through a list of function arguments of unknown number and type.
    8. Non-local Jumps:
      The declarations in provide a way to avoid the normal function call and return sequence, typically to permit an immediate return from a deeply nested function call.
    9. Signals:
      The header provides facilities for handling exceptional conditions that arise during execution, such as an interrupt signal from an external source or an error in execution.
    10. Date and Time Functions:
      The header declares types and functions for manipulating date and time.
    11. Implementation-defined Limits: and
      The header defines constants for the sizes of integral types. The values below are acceptable minimum magnitudes; larger values may be used.
  • 2019-12-01-twitter视频下载

    今天在twitter上面看到一个好玩的视频,我就想下载下来,结果折腾了几个小时。

    首先看网页代码,视频那里是一个blob:

    <video preload="none" playsinline="" aria-label="Embedded video" poster="https://pbs.twimg.com/ext_tw_video_thumb/1200926756321951745/pu/img/l-V1sNMeAZL5tcGN.jpg" src="blob:https://twitter.com/dd866381-2ada-4c2b-80af-9cec2a580039" style="width: 100%; height: 100%; position: absolute; background-color: black; top: 0%; left: 0%; transform: rotate(0deg) scale(1.005);"></video>

    我google了一下,这是流媒体的格式,要下载的话需要找到对应的m3u8文件,就是在chrom浏览器的Network里面过滤m3u8. 看到一个https://video.twimg.com/ext_tw_video/1200926756321951745/pu/pl/460×258/Kuir9CTQnfaw-EWA.m3u8

    Google说可以用youtube-dl下载,然后我先去下载这个玩意,因为还有同学说可以直接用ffmpeg转换格式。

    等youtube-dl下载完了之后,我运行下面的命令:

    ./youtube-dl -f mp4 -o baby.mp4 https://video.twimg.com/ext_tw_video/1200926756321951745/pu/pl/460x258/Kuir9CTQnfaw-EWA.m3u8

    结果提示需要ffmpeg或者avconv,尼玛还是得安装ffmpeg。

    然后我就老实的brew install ffmpeg。完事之后。

    运行:

    ./youtube-dl -f mp4 -o baby.mp4 https://video.twimg.com/ext_tw_video/1200926756321951745/pu/pl/460x258/Kuir9CTQnfaw-EWA.m3u8

    结果卡在那儿不动弹。

    我就试一下直接用ffmpeg转换:

    ffmpeg -i 'https://video.twimg.com/ext_tw_video/1200926756321951745/pu/pl/460x258/Kuir9CTQnfaw-EWA.m3u8' -vcodec copy -acodec copy -absf aac_adtstoasc o.mp4

    也是一样的,下到一半卡在那儿不动弹。

    我就换了个思路,想先看看m3u8里面的内容,

    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/pl/460x258/Kuir9CTQnfaw-EWA.m3u8
    cat Kuir9CTQnfaw-EWA.m3u8

    结果是这样:

    #EXTM3U
    #EXT-X-VERSION:6
    #EXT-X-MEDIA-SEQUENCE:0
    #EXT-X-TARGETDURATION:4
    #EXT-X-PLAYLIST-TYPE:VOD
    #EXT-X-ALLOW-CACHE:YES
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/0/3000/460x258/G5KaOzbFFR97qdzl.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/3000/6000/460x258/4lEqbRtnJ2YtXHRw.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/6000/9000/460x258/uSvCKT4MckCDGKSf.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/9000/12000/460x258/QSnzs6dHUar2OXfY.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/12000/15000/460x258/zdytmI8intABhyFW.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/15000/18000/460x258/Gh8owrBVf_s8SwDs.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/18000/21000/460x258/GWnvSye6J8mkjr35.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/21000/24000/460x258/Bmd-gN7sTAtj_bme.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/24000/27000/460x258/lkTRSPSKrGpFB_h6.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/27000/30000/460x258/DcZQHhRTJOJ-HNyJ.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/30000/33000/460x258/-3GD9_NdfoDUVF9q.ts
    #EXTINF:3.000,
    /ext_tw_video/1200926756321951745/pu/vid/33000/36000/460x258/WuuI_REDOMnYjzSU.ts
    #EXTINF:3.958,
    /ext_tw_video/1200926756321951745/pu/vid/36000/39958/460x258/AZrLcuvgp5XsaOcU.ts
    #EXT-X-ENDLIST

    我就写了个脚本wget.sh先把这个视频下载下来再转换:

    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/0/3000/460x258/G5KaOzbFFR97qdzl.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/3000/6000/460x258/4lEqbRtnJ2YtXHRw.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/6000/9000/460x258/uSvCKT4MckCDGKSf.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/9000/12000/460x258/QSnzs6dHUar2OXfY.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/12000/15000/460x258/zdytmI8intABhyFW.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/15000/18000/460x258/Gh8owrBVf_s8SwDs.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/18000/21000/460x258/GWnvSye6J8mkjr35.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/21000/24000/460x258/Bmd-gN7sTAtj_bme.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/24000/27000/460x258/lkTRSPSKrGpFB_h6.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/27000/30000/460x258/DcZQHhRTJOJ-HNyJ.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/30000/33000/460x258/-3GD9_NdfoDUVF9q.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/33000/36000/460x258/WuuI_REDOMnYjzSU.ts
    wget https://video.twimg.com/ext_tw_video/1200926756321951745/pu/vid/36000/39958/460x258/AZrLcuvgp5XsaOcU.ts

    下载下来之后,因为m3u8里面的路径也要改一下:
    把前面的“/ext_tw_video/1200926756321951745/pu/vid/33000/36000/460×258/”这一串也去掉。变成k.m3u8。

    #EXTM3U
    #EXT-X-VERSION:6
    #EXT-X-MEDIA-SEQUENCE:0
    #EXT-X-TARGETDURATION:4
    #EXT-X-PLAYLIST-TYPE:VOD
    #EXT-X-ALLOW-CACHE:YES
    #EXTINF:3.000,
    G5KaOzbFFR97qdzl.ts
    #EXTINF:3.000,
    4lEqbRtnJ2YtXHRw.ts
    #EXTINF:3.000,
    uSvCKT4MckCDGKSf.ts
    #EXTINF:3.000,
    QSnzs6dHUar2OXfY.ts
    #EXTINF:3.000,
    zdytmI8intABhyFW.ts
    #EXTINF:3.000,
    Gh8owrBVf_s8SwDs.ts
    #EXTINF:3.000,
    GWnvSye6J8mkjr35.ts
    #EXTINF:3.000,
    Bmd-gN7sTAtj_bme.ts
    #EXTINF:3.000,
    lkTRSPSKrGpFB_h6.ts
    #EXTINF:3.000,
    DcZQHhRTJOJ-HNyJ.ts
    #EXTINF:3.000,
    -3GD9_NdfoDUVF9q.ts
    #EXTINF:3.000,
    WuuI_REDOMnYjzSU.ts
    #EXTINF:3.958,
    AZrLcuvgp5XsaOcU.ts
    #EXT-X-ENDLIST

    然后再来用ffmpeg -i k.m3u8 k.mp4,就搞定了。

    总结一下, ffmpeg这个肯定是需要安装的,youtube-dl是调用这个的。如果网络给力的话,youtube-dl应该可以直接完成转换,但是我试了两次就没成功,所以用wget先把ts文件下载下来再转换。

  • 2019-11-08-关于定投的思考

    昨天我写了一篇比特币定投收益分析的文章,发到群里面之后,小伙伴们纷纷发表意见。其中两种意见比较有价值。

    一种意见是历史不代表未来,我是同意这一点的。

    因为未来是无法预测的,定投是否成功的关键还在于选择的标的,说的更直接一点在于你自己的判断和对这个判断的信心。

    如果判断失误,定投是没有意义的,而且可能投的越多亏的越多。

    至于怎么做出判断,每个人都有自己的标准,当然有些是理性的,有些只是碰运气,没有人能百分之百判断正确。

    比较靠谱的方法是看长期的趋势,就是巴菲特所说的价值投资,标的短期价格没有任何人能够预测,但是长期来看是跟它本身的价值一致的。

    可惜长期趋势也不是那么容易判断的,在某一个时间点,我们其实是没有足够的信息判断所谓的长期趋势向上还是向下,掌握的信息越多当然越有利,但是没有人敢说自己有百分之百的把握。

    即使是一些明显会向上的行业,具体到你投资的那个标的是否能够增长还是不一定的。比如按照现在的中国人口变化趋势,中国老龄人口比例是不断升高的,所以20年内养老行业肯定是上升趋势的,可是没有哪个标的叫做养老行业。

    你只能具体到某一个公司,这个公司可能是做疗养院,养老院,保健品或者其他跟养老行业有关的事情。

    一旦涉及到具体的公司,你要考虑的就不仅仅是整个长期的趋势了,你要考虑运作这个公司的人是否靠谱,公司的运营方法是否得当,公司的成本管理是否合理,公司有没有受到政策的影响等等一系列的因素。

    这其实是一件很专业的事情。巴菲特就是因为擅长这件事变成世界最有钱的几个人之一。

    另外一种意见说定投是没有意义的,就像昨天那篇文章里面每个月1000块钱投79个月,有个小伙伴说你还不如开始定投的那个月一次拿79000块钱买成比特币,删掉软件,放到今天再看。

    我稍微算了一下,如果这么操作的话,收益有69.38倍,比我用定投的收益20.1倍强多了。

    我差点同意了他的意见,感觉只要选择标的是对的,而且你有信心,直接一把梭哈收益比定投还要好。

    不过我又回头仔细想了一下,这么思考是不对的,因为你一把梭哈,结果是不太确定的,如果你在2017年最高点梭哈你就悲剧了,因为直到今天价格(2019-11-08, 9,242.60USD)也不到最高点(2017-12-17, 19308.3USD)的一半,你的收益是-52%,就是亏了一半多,俗称腰斩。

    而如果用定投的话,即使你是在最高点那一天买入,然后每个月再投1000块钱,到今天为止收益也有60%。

    $btc = 0;
    $money = 0;
    $init_price = ($result[0][$keys[1]]+$result[0][$keys[4]])/2;
    echo 'initial price on '.$result[0][$keys[0]].': '.$init_price.PHP_EOL;
    foreach ($result as $row) {
        if (strtotime($row[$keys[0]])>strtotime('2017-11-30')){
            if (explode("-", $row[$keys[0]])[2]=='17') {
                $price = ($row[$keys[1]]+$row[$keys[4]])/2;
                $spend = 140*($init_price/$price);
                $btc += $spend/$price;
                $money += $spend;
                echo $row[$keys[0]].' '.$row[$keys[1]].' '.$row[$keys[4]].' ';
                echo 'buy '.$spend/$price.' BTC for '.$spend.' USD'.PHP_EOL;
                $init_price = $price > $init_price ? $price: $init_price;
            }
        }
    }
    echo 'total:'.PHP_EOL;
    echo 'buy '.$btc.' BTC for '.$money.' USD'.PHP_EOL;

    结果如下:

    2017-12-17 19475.80 19140.80 buy 5.0604000119016E-5 BTC for 0.977077215498 USD
    2018-01-17 11431.10 11188.60 buy 0.021132865240077 BTC for 239.00953593549 USD
    2018-02-17 10207.50 11112.70 buy 0.023787539157875 BTC for 253.57754617687 USD
    2018-03-17 8321.91 7916.88 buy 0.041003859231437 BTC for 332.92652962444 USD
    2018-04-17 8071.66 7902.09 buy 0.042375837907192 BTC for 338.45052038501 USD
    2018-05-17 8370.05 8094.32 buy 0.039887960431049 BTC for 328.36506954108 USD
    2018-06-17 6545.53 6499.27 buy 0.063541463744209 BTC for 414.44284312523 USD
    2018-07-17 6739.65 7321.04 buy 0.054691369482636 BTC for 384.4991959854 USD
    2018-08-17 6340.91 6580.63 buy 0.064759503785061 BTC for 418.39625926941 USD
    2018-09-17 6514.06 6281.20 buy 0.066044070848885 BTC for 422.52552898495 USD
    2018-10-17 6590.52 6544.43 buy 0.062672239975984 BTC for 411.59836923627 USD
    2018-11-17 5578.58 5554.33 buy 0.087239801476468 BTC for 485.61642912769 USD
    2018-12-17 3253.12 3545.86 buy 0.23390771030276 BTC for 795.16692209714 USD
    2019-01-17 3651.87 3678.56 buy 0.20122093521853 BTC for 737.51799007698 USD
    2019-02-17 3633.36 3673.84 buy 0.20250235419038 BTC for 739.86260126998 USD
    2019-03-17 4047.72 4025.23 buy 0.16590808085281 BTC for 669.68382066035 USD
    2019-04-17 5236.14 5251.94 buy 0.098296958985144 BTC for 515.47318479645 USD
    2019-05-17 7886.93 7343.90 buy 0.046610624688886 BTC for 354.95925041511 USD
    2019-06-17 8988.92 9320.35 buy 0.032254477185794 BTC for 295.27796575177 USD
    2019-07-17 9471.21 9693.80 buy 0.029438383903566 BTC for 282.09346094784 USD
    2019-08-17 10358.72 10231.74 buy 0.025503510657795 BTC for 262.56450802945 USD
    2019-09-17 10281.51 10241.27 buy 0.025671998916176 BTC for 263.43039295846 USD
    2019-10-17 8047.81 8103.91 buy 0.041447134508633 BTC for 334.72125569289 USD
    total:
    buy 1.6699492846915 BTC for 9281.1362573038 USD

    最后结果是花了9281.14USD(66293.85人民币)买到了1.6699492846915个比特币,这些比特币今天(2019-11-08)的价格是107,479.85元人民币。1.62倍的收益。

    所以定投策略还是有意义的,它的作用就在于你不用去判断现在是什么点位,能不能进去投,只要你判断这个标的长期是增长的,你随时可以开始定投,几乎可以保证你是盈利的。

  • 2019-11-07-定投比特币收益分析

    有一个朋友,我们认识很多年了。2013年的时候,记得某一天我跟他说比特币你可以了解一下,现在好像涨到一千块一个了,你可以花一万块钱买上十个,然后放起来,过几年再看,肯定不是现在的价格。他一脸蒙逼,然后事情就过去了。

    到了今年的某一天,那个朋友跟我说,现在比特币好几万一个了,当初应该买一点的,我说你现在买也不迟呀。然后他就决定以后每个月给我一千块钱让我帮他买比特币。

    今天我心血来潮就想算一下,如果从2013年起每个月买一千块钱比特币,现在有多少收益。(你看,为了朋友感觉扎心,我也很拼的。)

    首先要拿到比特币价格的历史数据,google一下之后,我在coinmarketcap找到从2013年04月28日到今天的数据。
    直接chrome里面右键copy element,把数据复制到一个history.html文件里面。

    数据大概长这样:

    <table class="table">
    <thead>
    <tr>
    <th class="text-left">Date</th>
    <th class="text-right">Open*</th>
    <th class="text-right">High</th>
    <th class="text-right">Low</th>
    <th class="text-right">Close**</th>
    <th class="text-right">Volume</th>
    <th class="text-right">Market Cap</th>
    </tr>
    </thead>
    <tbody>
    <tr class="text-right">
    <td class="text-left">Nov 06, 2019</td>
    <td data-format-fiat="" data-format-value="9340.86427973">9,340.86</td>
    <td data-format-fiat="" data-format-value="9423.23703723">9,423.24</td>
    <td data-format-fiat="" data-format-value="9305.90931362">9,305.91</td>
    <td data-format-fiat="" data-format-value="9360.87991187">9,360.88</td>
    <td data-format-market-cap="" data-format-value="23133895764.6">23,133,895,765</td>
    .
    ..
    ...
    <tr class="text-right">
    <td class="text-left">Apr 28, 2013</td>
    <td data-format-fiat="" data-format-value="135.300003052">135.30</td>
    <td data-format-fiat="" data-format-value="135.979995728">135.98</td>
    <td data-format-fiat="" data-format-value="132.100006104">132.10</td>
    <td data-format-fiat="" data-format-value="134.210006714">134.21</td>
    <td data-format-market-cap="" data-format-value="-">-</td>
    <td data-format-market-cap="" data-format-value="1488566728.25">1,488,566,728</td>
    </tr>
    </tbody>
    </table>

    一看这个数据很归整,每一行7个数据,分别是日期,开盘价格,最高价格,最低价格,收盘价格,交易量和总市值。我就写了个php脚本来分析:

    <?php
    $html = file_get_contents("history.html");
    $doc = new DOMDocument();
    $doc->loadHTML('<?xml encoding="utf-8" ?>'.$html);
    $trs = $doc->getElementsByTagName('tr');
    $ths = $trs[0]->getElementsByTagName('th');
    $keys = [];
    foreach ($ths as $th) {
        $keys[] = trim($th->nodeValue, "*").PHP_EOL;
    }
    $result = [];
    foreach ($trs as $tr) {
        $tds = $tr->getElementsByTagName('td');
        $row = [];
        if ($tds->length > 0) {
            for ($i = 0; $i<sizeof($keys); $i++) {
                if ($i == 0) {
                    $tds[$i]->nodeValue = date('Y-m-d', strtotime($tds[$i]->nodeValue));
                }
                $row[$keys[$i]] = str_replace(',', '', $tds[$i]->nodeValue);
            }
        }
        if ($row) {
            $result[]=$row;
        }
    }
    // reverse order
    $result = array_reverse($result);

    然后我就计算如果每个月一号买1000块钱的比特币,最后能买到多少币:

    (因为拿到的价格是用美元计算的,为了方便计算,我就把1000块写成140usd)

    $btc = 0;
    $money = 0;
    echo 'simple policy: buy 100 usd on the first day of everymonth:'.PHP_EOL;
    foreach ($result as $row) {
        if (explode("-", $row[$keys[0]])[2]=='01') {
            $price = ($row[$keys[1]]+$row[$keys[4]])/2;
            $btc += 140/$price;
            $money += 140;
            echo $row[$keys[0]].' '.$row[$keys[1]].' '.$row[$keys[4]].' ';
            echo 'buy '.(100/$price).' BTC for 100 USD'.PHP_EOL;
        }
    }
    echo 'total:'.PHP_EOL;
    echo 'buy '.$btc.' BTC for '.$money.' USD'.PHP_EOL;

    输出结果是这样的:

    buy 140 usd on the first day of everymonth:
    2013-05-01 139.00 116.99 buy 1.0937927262784 BTC for 140 USD
    2013-06-01 128.82 129.30 buy 1.0847667751433 BTC for 140 USD
    2013-07-01 97.51 88.05 buy 1.5089458935115 BTC for 140 USD
    2013-08-01 106.21 104.00 buy 1.3320013320013 BTC for 140 USD
    2013-09-01 135.14 138.34 buy 1.0238408658768 BTC for 140 USD
    2013-10-01 132.68 132.18 buy 1.0571622744091 BTC for 140 USD
    2013-11-01 203.90 206.18 buy 0.68279360124854 BTC for 140 USD
    2013-12-01 1128.92 955.85 buy 0.13430738162963 BTC for 140 USD
    2014-01-01 754.97 771.40 buy 0.18344176051678 BTC for 140 USD
    2014-02-01 828.61 832.58 buy 0.16855386801028 BTC for 140 USD
    2014-03-01 549.92 565.61 buy 0.25100176597671 BTC for 140 USD
    2014-04-01 457.00 478.38 buy 0.29934358228741 BTC for 140 USD
    2014-05-01 447.63 457.76 buy 0.30925899336198 BTC for 140 USD
    2014-06-01 623.69 630.23 buy 0.22329973204032 BTC for 140 USD
    2014-07-01 641.39 640.81 buy 0.21837466853845 BTC for 140 USD
    2014-08-01 586.20 594.92 buy 0.23706312652398 BTC for 140 USD
    2014-09-01 477.79 474.88 buy 0.29391079807278 BTC for 140 USD
    2014-10-01 387.43 383.61 buy 0.36314588088815 BTC for 140 USD
    2014-11-01 338.65 325.75 buy 0.421432871764 BTC for 140 USD
    2014-12-01 378.25 379.24 buy 0.36964184345668 BTC for 140 USD
    2015-01-01 320.43 314.25 buy 0.4411672023697 BTC for 140 USD
    2015-02-01 216.87 226.97 buy 0.6308579668349 BTC for 140 USD
    2015-03-01 254.28 260.20 buy 0.54423884310372 BTC for 140 USD
    2015-04-01 244.22 247.27 buy 0.56969622983174 BTC for 140 USD
    2015-05-01 235.94 232.08 buy 0.59826503140891 BTC for 140 USD
    2015-06-01 230.23 222.93 buy 0.61788330832377 BTC for 140 USD
    2015-07-01 263.35 258.62 buy 0.53642929670288 BTC for 140 USD
    2015-08-01 284.69 281.60 buy 0.49444630842854 BTC for 140 USD
    2015-09-01 230.26 228.12 buy 0.61084689558881 BTC for 140 USD
    2015-10-01 236.00 237.55 buy 0.59127864005913 BTC for 140 USD
    2015-11-01 315.01 325.43 buy 0.43719942539504 BTC for 140 USD
    2015-12-01 377.41 362.49 buy 0.37842951750237 BTC for 140 USD
    2016-01-01 430.72 434.33 buy 0.32368071209757 BTC for 140 USD
    2016-02-01 369.35 373.06 buy 0.37715009226708 BTC for 140 USD
    2016-03-01 437.92 435.12 buy 0.32071840923669 BTC for 140 USD
    2016-04-01 416.76 417.96 buy 0.33544182480353 BTC for 140 USD
    2016-05-01 448.48 451.88 buy 0.31098671642454 BTC for 140 USD
    2016-06-01 531.11 536.92 buy 0.26216492046104 BTC for 140 USD
    2016-07-01 672.52 676.30 buy 0.20758885544402 BTC for 140 USD
    2016-08-01 624.60 606.27 buy 0.22748137496242 BTC for 140 USD
    2016-09-01 575.55 572.30 buy 0.24393431197456 BTC for 140 USD
    2016-10-01 609.93 613.98 buy 0.2287749916252 BTC for 140 USD
    2016-11-01 701.34 729.79 buy 0.19564959158148 BTC for 140 USD
    2016-12-01 746.05 756.77 buy 0.18631639184999 BTC for 140 USD
    2017-01-01 963.66 998.33 buy 0.14271224623979 BTC for 140 USD
    2017-02-01 970.94 989.02 buy 0.14286005836854 BTC for 140 USD
    2017-03-01 1180.04 1222.50 buy 0.11654332498106 BTC for 140 USD
    2017-04-01 1071.71 1080.50 buy 0.1300988286459 BTC for 140 USD
    2017-05-01 1348.30 1421.60 buy 0.10108668182967 BTC for 140 USD
    2017-06-01 2288.33 2407.88 buy 0.059622546691907 BTC for 140 USD
    2017-07-01 2492.60 2434.55 buy 0.056827983722842 BTC for 140 USD
    2017-08-01 2871.30 2718.26 buy 0.050093388388353 BTC for 140 USD
    2017-09-01 4701.76 4892.01 buy 0.029185606909484 BTC for 140 USD
    2017-10-01 4341.05 4403.74 buy 0.032019065066171 BTC for 140 USD
    2017-11-01 6440.97 6767.31 buy 0.021198823768121 BTC for 140 USD
    2017-12-01 10198.60 10975.60 buy 0.013223640090299 BTC for 140 USD
    2018-01-01 14112.20 13657.20 buy 0.010083041045179 BTC for 140 USD
    2018-02-01 10237.30 9170.54 buy 0.014427159333548 BTC for 140 USD
    2018-03-01 10385.00 10951.00 buy 0.013123359580052 BTC for 140 USD
    2018-04-01 7003.06 6844.23 buy 0.020220563012691 BTC for 140 USD
    2018-05-01 9251.47 9119.01 buy 0.015241844524476 BTC for 140 USD
    2018-06-01 7500.70 7541.45 buy 0.018614360314184 BTC for 140 USD
    2018-07-01 6411.68 6385.82 buy 0.021879273295566 BTC for 140 USD
    2018-08-01 7769.04 7624.91 buy 0.018188963846186 BTC for 140 USD
    2018-09-01 7044.81 7193.25 buy 0.019665600510182 BTC for 140 USD
    2018-10-01 6619.85 6589.62 buy 0.02119691403213 BTC for 140 USD
    2018-11-01 6318.14 6377.78 buy 0.022054329264835 BTC for 140 USD
    2018-12-01 4024.46 4214.67 buy 0.033984170658795 BTC for 140 USD
    2019-01-01 3746.71 3843.52 buy 0.036889527721821 BTC for 140 USD
    2019-02-01 3460.55 3487.95 buy 0.040296466863352 BTC for 140 USD
    2019-03-01 3853.76 3859.58 buy 0.036300746498923 BTC for 140 USD
    2019-04-01 4105.36 4158.18 buy 0.033883783463262 BTC for 140 USD
    2019-05-01 5350.91 5402.70 buy 0.026037767782168 BTC for 140 USD
    2019-06-01 8573.84 8564.02 buy 0.016338095888285 BTC for 140 USD
    2019-07-01 10796.93 10583.13 buy 0.013096314977601 BTC for 140 USD
    2019-08-01 10077.44 10399.67 buy 0.013673804555428 BTC for 140 USD
    2019-09-01 9630.59 9757.97 buy 0.014441505712647 BTC for 140 USD
    2019-10-01 8299.72 8343.28 buy 0.016823889923692 BTC for 140 USD
    2019-11-01 9193.99 9261.10 buy 0.015171966107995 BTC for 140 USD
    total:
    buy 22.313812243429 BTC for 11060 USD

    就是从2013年5月1号起每个月的1号买1000块钱比特币,到2019年11月1号,总共79个月,共花了79000块钱,买到了22.313812243429个比特币,这些比特币今天(2019-11-07)的价格是1,429,726.68人民币。18.1倍的收益。

    我想起之前读过的一本书叫做价值平均策略,大概的意思是动态的调整每个月投资的额度,具体算法我不太记得了,我就自己想了一个简单粗暴的动态策略,用已知的最高价格作为参考值,把最高价格除以当前价格做为系数,这样价格越低买入的越多。代码如下:

    $btc = 0;
    $money = 0;
    $init_price = ($result[0][$keys[1]]+$result[0][$keys[4]])/2;
    echo 'initial price on '.$result[0][$keys[0]].': '.$init_price.PHP_EOL;
    foreach ($result as $row) {
        if (explode("-", $row[$keys[0]])[2]=='01') {
            $price = ($row[$keys[1]]+$row[$keys[4]])/2;
            $spend = 140*($init_price/$price);
            $btc += $spend/$price;
            $money += $spend;
            echo $row[$keys[0]].' '.$row[$keys[1]].' '.$row[$keys[4]].' ';
            echo 'buy '.$spend/$price.' BTC for '.$spend.' USD'.PHP_EOL;
            $init_price = $price > $init_price ? $price: $init_price;
        }
    }
    echo 'total:'.PHP_EOL;
    echo 'buy '.$btc.' BTC for '.$money.' USD'.PHP_EOL;

    输出结果是这样的:

    buy 140*(local high price/current price):
    initial price on 2013-04-28: 134.755
    2013-05-01 139.00 116.99 buy 1.1515609112047 BTC for 147.39403882964 USD
    2013-06-01 128.82 129.30 buy 1.1326340212648 BTC for 146.17774678444 USD
    2013-07-01 97.51 88.05 buy 2.191614613927 BTC for 203.33800388015 USD
    2013-08-01 106.21 104.00 buy 1.7077573806559 BTC for 179.49383949384 USD
    2013-09-01 135.14 138.34 buy 1.0089781766947 BTC for 137.96767588123 USD
    2013-10-01 132.68 132.18 buy 1.0915681447006 BTC for 144.5563694027 USD
    2013-11-01 203.90 206.18 buy 0.45535113653299 BTC for 93.365197034725 USD
    2013-12-01 1128.92 955.85 buy 0.026418631819663 BTC for 27.538385529339 USD
    2014-01-01 754.97 771.40 buy 0.25055122877977 BTC for 191.21693953629 USD
    2014-02-01 828.61 832.58 buy 0.21153272498137 BTC for 175.6980237059 USD
    2014-03-01 549.92 565.61 buy 0.46908729631231 BTC for 261.64047582763 USD
    2014-04-01 457.00 478.38 buy 0.667175394006 BTC for 312.03126002266 USD
    2014-05-01 447.63 457.76 buy 0.71210624326671 BTC for 322.36693579562 USD
    2014-06-01 623.69 630.23 buy 0.37125859892633 BTC for 232.76429118285 USD
    2014-07-01 641.39 640.81 buy 0.35506235979481 BTC for 227.63047886445 USD
    2014-08-01 586.20 594.92 buy 0.41843512452875 BTC for 247.1110471417 USD
    2014-09-01 477.79 474.88 buy 0.6431780306908 BTC for 306.3682072491 USD
    2014-10-01 387.43 383.61 buy 0.98188892677318 BTC for 378.5378190496 USD
    2014-11-01 338.65 325.75 buy 1.3223820109383 BTC for 439.29530403371 USD
    2014-12-01 378.25 379.24 buy 1.0173312201919 BTC for 385.30911299159 USD
    2015-01-01 320.43 314.25 buy 1.4491273531296 BTC for 459.86607424214 USD
    2015-02-01 216.87 226.97 buy 2.9632159415969 BTC for 657.59688175919 USD
    2015-03-01 254.28 260.20 buy 2.2053584452988 BTC for 567.30640646867 USD
    2015-04-01 244.22 247.27 buy 2.416500048966 BTC for 593.84280453315 USD
    2015-05-01 235.94 232.08 buy 2.6649395101285 BTC for 623.62249476518 USD
    2015-06-01 230.23 222.93 buy 2.8425822771077 BTC for 644.07229234707 USD
    2015-07-01 263.35 258.62 buy 2.1425210354757 BTC for 559.16585244363 USD
    2015-08-01 284.69 281.60 buy 1.8202808285906 BTC for 515.40341521129 USD
    2015-09-01 230.26 228.12 buy 2.7782086533372 BTC for 636.73764125834 USD
    2015-10-01 236.00 237.55 buy 2.6030619162413 BTC for 616.33998521803 USD
    2015-11-01 315.01 325.43 buy 1.4231781994891 BTC for 455.73012304041 USD
    2015-12-01 377.41 362.49 buy 1.0662772066542 BTC for 394.4692526017 USD
    2016-01-01 430.72 434.33 buy 0.78007032906727 BTC for 337.39991907982 USD
    2016-02-01 369.35 373.06 buy 1.0590794814936 BTC for 393.13559892782 USD
    2016-03-01 437.92 435.12 buy 0.76585736967879 BTC for 334.31205901219 USD
    2016-04-01 416.76 417.96 buy 0.83778878317957 BTC for 349.65952654782 USD
    2016-05-01 448.48 451.88 buy 0.72008505131324 BTC for 324.1678884002 USD
    2016-06-01 531.11 536.92 buy 0.51173989609801 BTC for 273.27678061478 USD
    2016-07-01 672.52 676.30 buy 0.32085453816226 BTC for 216.38750908201 USD
    2016-08-01 624.60 606.27 buy 0.385293610276 BTC for 237.12317304021 USD
    2016-09-01 575.55 572.30 buy 0.44304302441539 BTC for 254.2734677876 USD
    2016-10-01 609.93 613.98 buy 0.38968816276562 BTC for 238.47161964524 USD
    2016-11-01 701.34 729.79 buy 0.28500862887461 BTC for 203.94219952066 USD
    2016-12-01 746.05 756.77 buy 0.25846530139145 BTC for 194.21341211855 USD
    2017-01-01 963.66 998.33 buy 0.15164308156174 BTC for 148.76110479666 USD
    2017-02-01 970.94 989.02 buy 0.15195736845904 BTC for 148.91518194249 USD
    2017-03-01 1180.04 1222.50 buy 0.10112881684416 BTC for 121.48301381038 USD
    2017-04-01 1071.71 1080.50 buy 0.14523101359762 BTC for 156.28381988746 USD
    2017-05-01 1348.30 1421.60 buy 0.087679987206416 BTC for 121.43239828153 USD
    2017-06-01 2288.33 2407.88 buy 0.035166334572328 BTC for 82.574246040956 USD
    2017-07-01 2492.60 2434.55 buy 0.054164404460803 BTC for 133.43807271952 USD
    2017-08-01 2871.30 2718.26 buy 0.044156899397747 BTC for 123.40881929884 USD
    2017-09-01 4701.76 4892.01 buy 0.017004233055095 BTC for 81.567350478488 USD
    2017-10-01 4341.05 4403.74 buy 0.03512760693623 BTC for 153.59177292994 USD
    2017-11-01 6440.97 6767.31 buy 0.015397662640547 BTC for 101.68831975094 USD
    2017-12-01 10198.60 10975.60 buy 0.0082487905532152 BTC for 87.330770465944 USD
    2018-01-01 14112.20 13657.20 buy 0.0076883305976663 BTC for 106.75016384942 USD
    2018-02-01 10237.30 9170.54 buy 0.020642872076286 BTC for 200.31677919851 USD
    2018-03-01 10385.00 10951.00 buy 0.017080419081473 BTC for 182.21391076115 USD
    2018-04-01 7003.06 6844.23 buy 0.040550382242634 BTC for 280.7564512623 USD
    2018-05-01 9251.47 9119.01 buy 0.023040055422503 BTC for 211.628438669 USD
    2018-06-01 7500.70 7541.45 buy 0.034364078094468 BTC for 258.45480865435 USD
    2018-07-01 6411.68 6385.82 buy 0.04747601421011 BTC for 303.78714592694 USD
    2018-08-01 7769.04 7624.91 buy 0.032811371521298 BTC for 252.54830631514 USD
    2018-09-01 7044.81 7193.25 buy 0.038355079751556 BTC for 273.05096340372 USD
    2018-10-01 6619.85 6589.62 buy 0.044560878258085 BTC for 294.31279226192 USD
    2018-11-01 6318.14 6377.78 buy 0.048238764192504 BTC for 306.21774554345 USD
    2018-12-01 4024.46 4214.67 buy 0.11454122324716 BTC for 471.86001434617 USD
    2019-01-01 3746.71 3843.52 buy 0.13496297887131 BTC for 512.20002555917 USD
    2019-02-01 3460.55 3487.95 buy 0.16104320456432 BTC for 559.50435345758 USD
    2019-03-01 3853.76 3859.58 buy 0.1306891631676 BTC for 504.02497491359 USD
    2019-04-01 4105.36 4158.18 buy 0.11386552694181 BTC for 470.46616825235 USD
    2019-05-01 5350.91 5402.70 buy 0.067238182215101 BTC for 361.52659432507 USD
    2019-06-01 8573.84 8564.02 buy 0.02647349902264 BTC for 226.84955998007 USD
    2019-07-01 10796.93 10583.13 buy 0.017010093009046 BTC for 181.83840456949 USD
    2019-08-01 10077.44 10399.67 buy 0.0185433075381 BTC for 189.85667411075 USD
    2019-09-01 9630.59 9757.97 buy 0.020683947066558 BTC for 200.51597436839 USD
    2019-10-01 8299.72 8343.28 buy 0.028071220864445 BTC for 233.59466442348 USD
    2019-11-01 9193.99 9261.10 buy 0.022829278840654 BTC for 210.65819781968 USD
    total:
    buy 51.375763838804 BTC for 22893.725512278 USD

    最后结果是花了22893.72USD(就是163526.57人民币)买到了51.375763838804个比特币,这些比特币今天(2019-11-07)的价格是3,290,352.13元人民币。20.1倍的收益。

    两者‌‍‍‌‍​‌‌‍​‌‌‌‌‌​‌‌‌‍‍​‍‍‍‍‌​‌‌‍‌​‌‍‍‌‍​‌‌‍​‍‌‌‌‌​‌‌‌‌‌​‍‍‍‌‌​‍‍‌‌‌​‌‍‍‌‍​‌‌‍​‍‍‍‍‌​‌‌‌‌‍​‌‌‍‌​‌​‌‍‍‌‍​‌‌‍​‍‌‌‌‌​‌‌‌‍‍​‌‍​‌‌‌‌‌​​‌‌‌‌​‍​‍​‌‍‍‌​‌‌‌​​​​‍​‌​‍‌‍‌​‌‌‌‌​​‌‍‌‌​‌‍​‍‍‍​‍‍‌​‍‍‍​‍‌​‍‍‌​‌‌‌​‌‌‌‌​‌‌‍​‍‍‍​​‍‌‍‌​‍‍‍​‍‍​对比,后一个方案虽然收益多了两倍,但是投入的资金也翻倍了,而且每个月还要计算投多少钱进去,感觉不太值得,当然如果看最后结果的话,

    79000变成1,429,726.68 (八万变成一百四十万)

    163526.57变成3,290,352.13 (十六万变成三百二十万)

    可能很多人还是愿意选择第二个方案,因为16万虽然不是小数目,但是努力一下还是可以拿出来的,最后的收益也更有吸引力的。

    友情提示,本文章只是历史数据分析,并不构成任何投资建议,比特币风险很大,你需要强大的心脏来承受价格的巨大波动。

  • 2019-10-23-Elasticsearch

    Elasticsearch Rest High Level Client

    昨天折腾了一下Elasticsearch, 今天把过程记录下来免得忘记。

    首先当然是安装,我用的mac, 所以安装很简单:

    brew tap elastic/tap
    brew install elastic/tap/elasticsearch-full
    elasticsearch

    搞定。

    然后就是按照官方的教程,
    用curl把这几个页面上(index,
    search, aggregations)的命令跑了一遍。
    为了免得以后重新打命令,我把这个命令都放到一个reference.sh里面去了,想要跑哪一行,就把那个命令前面的#去掉,然后bash reference.sh就可以了。

    最后还折腾了一下官方的Java REST Client 7.4, 其中有一个坑就是Maven Repository页面上写的是7.4.1,但是我在pom.xml里面用7.4.1死活编译不了,我还以为是因为我用了阿里云的maven源,里面没有更新,换成官方的源还是不行,我去官方的源上一看,到今天(2019-10-23)为止, 官方源上最新的版本是7.4.0,所以上面应该写7.4.0.

    其它的就没什么了,先搞个project:

    mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.laogongshuo.es -DartifactId=elasticsearch
    cd elasticsearch

    然后把依赖关系加到pom.xml里面去:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.0</version>
        </dependency>
    </dependencies>

    在src/main/java/com/laogongshuo/es/App.java里面撸一些代码:

    package com.laogongshuo.es;
    
    import java.io.IOException;
    import org.apache.http.HttpHost;
    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    
    public class App {
    
      private static final String[] FETCH_FIELDS = {
        "account_number",
        "balance",
        "firstname",
        "lastname",
        "age",
        "gender",
        "address",
        "employer",
        "email",
        "city",
        "state"
      };
    
      public static void matchAll() throws IOException {
        RestHighLevelClient client =
            new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest("bank");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchRequest.source(searchSourceBuilder);
    
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        if (searchResponse.getHits().getTotalHits().value > 0) {
          System.out.println(searchResponse.getHits().getTotalHits());
          for (SearchHit hit : searchResponse.getHits()) {
            System.out.println("Match: ");
            for (String fetchField : FETCH_FIELDS) {
              System.out.println(" - " + fetchField + " " + hit.getSourceAsMap().get(fetchField));
            }
          }
        } else {
          System.out.println("No results matching the criteria.");
        }
        client.close();
      }
    
      public static void search() throws IOException {
        RestHighLevelClient client =
            new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest("bank");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery("account_number", "49"));
        searchRequest.source(sourceBuilder);
    
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        if (searchResponse.getHits().getTotalHits().value > 0) {
          System.out.println(searchResponse.getHits().getTotalHits());
          for (SearchHit hit : searchResponse.getHits()) {
            System.out.println("Match: ");
            for (String fetchField : FETCH_FIELDS) {
              System.out.println(" - " + fetchField + " " + hit.getSourceAsMap().get(fetchField));
            }
          }
        } else {
          System.out.println("No results matching the criteria.");
        }
        client.close();
      }
    
      public static void main(String[] args) throws IOException {
        matchAll();
        search();
      }
    }

    最后编译运行:

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.laogongshuo.es.App"

    因为没有在pom.xml里面写执行的mainClass,所以只能这么跑,不过能看到结果就行了。

    文中全部代码都在这里,github, 欢迎star.

  • 2016-05-05-lightsword安装中遇到的坑

    2016-05-05-lightsword安装中遇到的坑

    lightsword是一个基于 Node.js 的 SOCKS5 代理 / Apple NE 服务器。LightSword 参考了 Shadowsocks 的协议,并用 Typescript 实现。想必大家已经知道这货是干嘛的了。项目的主页在这里:https://github.com/UnsignedInt8/LightSword 。

    之前看到一篇介绍lightsword的文章,刚好上午没啥事,我就折腾了一下,遇到两个坑,这里说一下。

    1.服务器
    我服务器用的是ubuntu, 作者提供了一个一键安装脚本.
    curl -sL https://raw.githubusercontent.com/UnsignedInt8/LightSword/master/misc/onekey_ubuntu.sh | bash –
    但是这个脚本执行会报错,我直接打开那个脚本,里面内容是
    #!/bin/bash
    apt-get update -y
    apt-get install curl -y
    curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash –
    apt-get install -y nodejs
    npm install lightsword -g
    我直接在前面加一个sudo,就ok了。所以正确命令应该是
    curl -sL https://raw.githubusercontent.com/UnsignedInt8/LightSword/master/misc/onekey_ubuntu.sh | sudo -E bash –
    安装完成之后执行
    lsserver -f -m aes-256-cfb -p 4433 -k your_password
    就ok了。

    2.本地
    我本地是mac, 直接brew install node && npm install lightsword -g就安装好了。
    我看到https://github.com/UnsignedInt8/LightSword/tree/master/client 这里有一个json文件,我就执行了lslocal -c config.json, 结果报错,我仔细一看作者提供的那个json文件里面倒数第二行是
    “dontbypasslocal”, false
    坑爹,这里面应该是
    ”dontbypasslocal”: false,
    改正之后重新执行
    lslocal -c config.json
    就没有问题了。
    后来我又仔细看了一下lsserver和lslocal的manual, 其时本地也不需要config.json文件, 直接执行
    lslocal -f -m aes-256-cfb -s your_host_ip -p 4433 -k your_password -l 1081
    就ok了。其中的your_host_ip填你自己的服务器的ip地址,your_password填你的密码。

    就这样,lightsword就可以了,万一shaowsocks挂了,你还可以用这个做备用方案。

  • 2014-11-07-XSLT_Tips

    XSLT usage and performance tips

    Eight tips for how to use XSLT efficiently:

    • Keep the source documents small. If necessary split the document first.
    • Keep the XSLT processor (and Java VM) loaded in memory between runs
    • If you use the same stylesheet repeatedly, compile it first.
    • If you use the same source document repeatedly, keep it in memory.
    • If you perform the same transformation repeatedly, don’t. Store the result instead.
    • Keep the output document small. For example, if you’re generating HTML, use CSS.
    • Never validate the same source document more than once.
    • Split complex transformations into several stages.

    Eight tips for how to write efficient XSLT:

    • Avoid repeated use of “//item”.
    • Don’t evaluate the same node-set more than once; save it in a variable.
    • Avoid xsl:number if you can. For example, by using position().
    • Use xsl:key, for example to solve grouping problems.
    • Avoid complex patterns in template rules. Instead, use xsl:choose within the rule.
    • Be careful when using the preceding[-sibling] or following[-sibling] axes. This often indicates an algorithm with n-squared performance.
    • Don’t sort the same node-set more than once. If necessary, save it as a result tree fragment and access it using the node-set() extension function.
    • To output the text value of a simple #PCDATA element, use xsl:value-of in preference to xsl:apply-templates.

    XSLT Best Practices

    XSLT (Extensible Stylesheet Language Transformations) is a functional language for transforming XML documents into another file structure such as plain text, HTML, XML, etc. XSLT is available in multiple versions, but version 1.0 is the most commonly used version. XSLT is extremely fast at transforming XML and does not require compilation to test out changes. It can be debugged with modern debuggers, and the output is very easy to test simply by using a compare tool on the output. XSLT also makes it easier to keep a clear separation between business and display logic.

    Uses

    XSLT has numerous uses. XML is easy to generate and can easily be transformed to the desired layout of other systems. Many older EDI systems need to receive data in a fixed, flat file format. One such example of a fixed file format is the ABA file format used in the banking industry of Australia. XSLT can be used to transform your data source to a flat file format for another system to consume, and that same data source can then be used to transform the data into HTML for display in a web browser. In fact, it’s even possible to use XSLT to build an XSLT view engine for use with MVC to render content.

    Another use for XSLT is creating dynamic documents in various formats such as Word, Excel, and PDF. Starting with Office 2003, Microsoft began supporting the WordML and ExcelML data formats. These data formats are XML documents that represent a Word document or an Excel spreadsheet. Data from a database can be easily transformed into either of these formats through the use of XSLT. In addition, the same data source can also be transformed into XSL-FO to create PDF documents.

    Besides the two uses above, you may want to consider using XSLT whenever you are working with templates, when you are working with XML data, or when you are working with static data that doesn’t need to live in a database. An example of a template would be an email newsletter that gets sent out and is “mail-merged” with data from the database.

    Of course there are times that you could use XSLT to accomplish a programming task, but it might not be the right choice. For instance, it might be easier to use LINQ to access data from an object hierarchy and then use a StringBuilder to build output rather than to use an XSLT to do the same thing. An XSLT might also not be appropriate for generating output if you need to do a large amount of string manipulation. Having to use certain string functions like replace or split are not as easy to accomplish in XSLT as they are in languages like C#.

    Basics

    Assuming that XSLT is the right solution for the task you are trying to accomplish, there are several basic things that a developer needs to be aware of. The first thing to remember is that XSLT is a functional language. Once a variable is set it cannot be changed. In order to change a value, you need to setup a template that you can call recursively. The following is an example of what that code might look like:

    <xsl:template name="pad-left">
        <xsl:param name="totalWidth"/>
        <xsl:param name="paddingChar"/>
        <xsl:param name="value"/>
        <xsl:choose>
            <xsl:when test="string-length($value) &lt; $totalWidth">
                <xsl:call-template name="pad-left">
                    <xsl:with-param name="totalWidth">
                        <xsl:value-of select="$totalWidth"/>
                    </xsl:with-param>
                    <xsl:with-param name="paddingChar">
                        <xsl:value-of select="$paddingChar"/>
                    </xsl:with-param>
                    <xsl:with-param name="value">
                        <xsl:value-of select="concat($paddingChar, $value)"/>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$value"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    The template above performs the equivalent function of the pad left function in .Net. The pad-left template takes in three parameters. It then checks to see if the length of the value passed in is less than the total length specified. If the length is less then the template calls itself again passing in the value passed to the function concatenated with the padding character and the desired length. This process is repeated until the value passed into the template is greater than or equal to the string length passed into the template.

    Another important thing to know when working with XSLT is that namespaces affect how you select data from XML. For instance, let’s say you’re working with XML that starts with the following fragment:

    <FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">

    In order to select data from this XML document, you need to include a reference to the namespace(s) used in the XML document that you are consuming in your XSLT. For the example above you would do something like this:

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
        xmlns:fm="http://www.filemaker.com/fmpxmlresult"
        exclude-result-prefixes="msxsl fm">

    <xsl:template match="fm:FMPXMLRESULT">
        <xsl:apply-templates select="fm:RESULTSET" />
    </xsl:template>

    The last area I would like to focus on is the use of templates. XSLT provides two techniques for accessing data. The push approach, as the name implies, pushes the source XML to the stylesheet, which has various templates to handle variable kinds of nodes. Such an approach makes use of several different templates and applies the appropriate template for a given node through the use of the xsl:apply-templates command. An example of this is as follows:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="Orders">
            <html>
                <body>
                    <xsl:apply-templates select="Invoice"/>
                </body>
            </html>
        </xsl:template>
        <xsl:template match="Invoice">
            <xsl:apply-templates select="CustomerName" />
            <p>
                <xsl:apply-templates select="Address" />
                <xsl:apply-templates select="City" />
                <xsl:apply-templates select="State" />
                <xsl:apply-templates select="Zip" />
            </p>
            <table>
                <tr>
                    <th>Description</th>
                    <th>Cost</th>
                </tr>
                <xsl:apply-templates select="Item" />
            </table>
            <p />
        </xsl:template>
        <xsl:template match="CustomerName">
            <h1><xsl:value-of select="." /></h1>
        </xsl:template>
        <xsl:template match="Address">
            <xsl:value-of select="." /><br />
        </xsl:template>
        <xsl:template match="City">
            <xsl:value-of select="." />
            <xsl:text>, </xsl:text>
        </xsl:template>
        <xsl:template match="State">
            <xsl:value-of select="." />
            <xsl:text> </xsl:text>
        </xsl:template>
        <xsl:template match="Zip">
            <xsl:value-of select="." />
        </xsl:template>
        <xsl:template match="Item">
            <tr>
                <xsl:apply-templates />
            </tr>
        </xsl:template>
        <xsl:template match="Description">
            <td><xsl:value-of select="." /></td>
        </xsl:template>
        <xsl:template match="TotalCost">
            <td><xsl:value-of select="." /></td>
        </xsl:template>
        <xsl:template match="*">
            <xsl:apply-templates />
        </xsl:template>
        <xsl:template match="text()" />
    </xsl:stylesheet>

    The pull approach on the other hand makes minimal use of xsl:apply-template instruction and instead pulls the xml through the transform with the use of the xsl:for-each and xsl:value-of instructions. Using the pull technique, the above template would look something like this:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="Orders">
            <html>
                <body>
                    <xsl:for-each select="Invoice">
                        <h1>
                            <xsl:value-of select="CustomerName" />
                        </h1>
                        <p>
                            <xsl:value-of select="Address" /><br />
                            <xsl:value-of select="City" />
                            <xsl:text>, </xsl:text>
                            <xsl:value-of select="State" />
                            <xsl:text> </xsl:text>
                            <xsl:value-of select="Zip" />
                        </p>
                        <table>
                            <tr>
                                <th>Description</th>
                                <th>Cost</th>
                            </tr>
                            <xsl:for-each select="Item">
                                <tr>
                                    <td><xsl:value-of select="Description" /></td>
                                    <td><xsl:value-of select="TotalCost" /></td>
                                </tr>
                            </xsl:for-each>
                        </table>
                        <p />
                    </xsl:for-each>
                </body>
            </html>
        </xsl:template>
    </xsl:stylesheet>

    You can read more about these two approaches at http://www.xml.com/pub/a/2005/07/06/tr.html and http://www.ibm.com/developerworks/library/x-xdpshpul.html.

    Best Practices

    While XSLT is extremely fast and powerful, there are several rules to keep in mind in order to write quality code. They are as follows:

    • Avoid the use of the // near the root of the document especially when transforming very large XML document. The // selector selects nodes in the document from the current node that match the selection no matter where they are in the document. It is best to avoid using the // operator all together if possible. More scanning of the XML document is required which makes transforms take longer and makes them less efficient.
    • Avoid the use of very long xpath queries (i.e. more than a screen width long). It makes the XSLT logic difficult to read.
    • Set the indent attribute in the output declaration to off when outputting XML or HTML. Not only will this reduce the size of the file you generate, but it will also decrease the processing time.
    • Try to use template matching (push method) instead of named templates (pull method). Named templates are fine to use for utility functions like the padding template listed above. However, template matching will create cleaner and more elegant code.
      Make use of built in XSLT functions whenever possible. A good example of this is when you are trying to concatenate strings. One approach to accomplish this would be to utilize several xsl:value-of instructions. However, it is much cleaner to use the xsl concat() function instead.
    • If you are transforming a large amount of data through .Net code you should utilize the XmlDataReader and XmlDataWriter classes. If you try and use the XmlDocument class to read in your XML and the StringBuilder class to write out your XML you are likely to get an Out of Memory exception since data must be loaded in one continuous memory block.

    Additional best practices can be found here:

    http://www.xml.org//sites/www.xml.org/files/xslt_efficient_programming_techniques.pdf

    XSLT Tips for Cleaner Code and Better Performance

    Conclusion

    There are many times to consider using XSLT. The language tends to be verbose and at times it can feel unnatural to program in if you are more accustomed to a procedural programming style. However, it is a flexible and powerful language that with a little time can be easy to pick up and learn. There are debugging and profiling tools available to make the development process easier. In addition, changes to an XSLT does not require compilation in order to test, which can easily be done by comparing output with a compare tool such as Araxis Merge.

    XSLT Tips for Cleaner Code and Better Performance

    On this page:

    • Avoid XSLT Named Templates; Use Template Match
    • Avoid xsl:for-each; Use Template Match
    • You don’t have to use xsl:element or xsl:attribute
    • Use the element name itself rather than xsl:element
    • Use the { } shorthand for writing values inside of attributes
    • Use template modes
    • Use in-built functions: concat()
    • Use in-built functions: boolean()
    • Use in-built functions: string()
    • Use in-built functions: number()
    • Use in-built functions: other
    • More tips

    XSLT is a transformation language to convert XML from one format to another (or to another text-based output).

    People seem to love or hate XSLT. Some find it hard to read or strange to get used to. Yet, it can be quite elegant when coded right. So this will be the first in a series of posts to show where it can be useful (and what its pitfalls/annoyances may be), how to make best use of XSLT, etc.

    This first post looks at coding style in XSLT 1.0 and XPath 1.0.

    I think some frustrations at this technology come from wanting to do procedural programming with it, whereas it is really more like a functional programming language; you define what rules to act against, rather than how to determine the rules (kind of).

    For example, consider the following example where a named template may be used to create a link to a product:

    <xsl:template name="CreateLink">
      <xsl:param name="product" />
      <xsl:element name="a">
        <xsl:attribute name="href">
          <xsl:value-of select="'/product/?id='" /><xsl:value-of select="normalize-space($product/@id)" />
        <xsl:value-of select="$product/name" />
      </xsl:element>
    </xsl:template>

    I have found the above to be a common way people initially code their XSLTs. Yet, the following is far neater:

    <xsl:template match="product">
      <a href="{concat('/product/?id=', normalize-space(./@id))}">
        <xsl:value-of select="./@name" />
      </a>
    </xsl:template>

    Not only does such neater coding become easier to read and maintain, but it can even improve performance.

    (Update: As Azat rightly notes in a comment below the use of ‘./’ is redundant. That is definitely true. I should have added originally that I tend to use that to help others in the team, especially those newer to XSLT to understand the context of which element your template is running under a bit more clearly.)

    Lets look at a few tips on how this may be possible (a future post will concentrate on additional performance-related tips; the tips below are primarily on coding style):

    Avoid XSLT Named Templates; Use Template Match

    The first coding practice that leads to code bloat and hard to read XSLT is using named templates everywhere. Named templates give a procedural feel to coding. (You define templates with names, pass parameters as needed and do some stuff). This may feel familiar to most coders, but it really misses the elegance and flexibility of XSLT.

    So, instead of this:

    <xsl:template name="CreateLink">
      <xsl:param name="product" />
      <-- create the link here based on the product parameter -->
    </xsl:template>
    
    <-- The above would be called from elsewhere using this: -->
    <xsl:call-template name="CreateLink"<>
      <xsl:with-param name="product" select="./product" />
    </xsl:call-template>

    Far neater would be this:

    <xsl:template match="product">
      <-- create the link here based on the product parameter -->
    </xsl:template>
    
    <-- The above would be called from elsewhere using this: -->
    <xsl:apply-templates select="./product" />

    The above example doesn’t look like much on its own. When you have a real stylesheet with lots of template matches, (and modes, which we look at later) this gets a lot easier to read, and cuts a LOT of code, especially when calling/applying these templates.

    (Of course, each tip has exceptions; named templates can be useful for utility functions. Sometimes XSLT extension objects can be useful for that too, depending on your parser and runtime requirements. A subsequent post on XSLT performance tips will cover that.)

    Avoid xsl:for-each; Use Template Match

    xsl:for-each is another programming construct that would appeal to many coders. But again, it is rarely needed. Let the XSLT processor do the looping for you (it has potential to be optimised further, too).

    There are some instances or XSLT parsers that may perform a bit quicker using xsl:for-each because for-each avoids the XSLT processor having to determine which of possibly many matched templates is the suitable one to execute. However, matched templates that use modes can overcome those issues to most extents, and lend to highly elegant, reusable XSLT.

    You don’t have to use xsl:element or xsl:attribute

    You can use xsl:element and xsl:attribute, but it leads to very bloated code.

    Here are a few examples of what you can do instead. In each example we will just assume we are working with some XML that represents some kind of product (it is not important what this structure is for this discussion).

    Use the element name itself rather than xsl:element

    Instead of

    <xsl:element name="p">
      <xsl:value-of select="$product/name" />
    </xsl:element>

    This is a lot cleaner to read:

    <p>
      <xsl:value-of select="$product/name" />
    </p>

    Sometimes I prefer this:

    <p><xsl:value-of select="$product/name" /></p>

    Use the { } shorthand for writing values inside of attributes

    Using xsl:value-of for many attributes can get verbose very quickly. There is more code to read. So the code just looks uglier and more bloated. For attributes only then, with most XSLT parsers, you can use the shorthand { as a replacement for .

    In between { and } you just put in your normal select expression.

    So, instead of

    <h3>
        <xsl:attribute name="class">
            <xsl:value-of select="$product/@type" />
        </xsl:attribute>
        <xsl:value-of select="$product/name" />
    </h3>

    This is a lot cleaner to read:

    <h3 class="{$product/name}">
      <xsl:value-of select="$product/name" />
    </h3>

    Or, instead of

    <xsl:element name="img">
        <xsl:attribute name="src" select="$product/image/@src" />
        <xsl:attribute name="width" select="$product/image/@width" />
        <xsl:attribute name="height" select="$product/image/@height" />
        <xsl:attribute name="alt" select="$product/image" />
        <xsl:attribute name="class" select="$product/@type" />
    </xsl:element>

    This is a lot cleaner to read:

    <img
        src="{$product/image/@src}"
        width="{$product/image/@width}"
        height="{$product/image/@height}"
        alt="{$product/image}"
        class="{$product/@type}"
        />

    The above is only put onto multiple lines for this web page. In a proper editor sometimes a one-liner is even easier to read:

    <img src="{$product/image/@src}" width="{$product/image/@width}" height="{$product/image/@height}" alt="{$product/image}" class="{$product/@type}" />

    The above is also looking a lot like some templating languages now, and you might see why I am wondering why there are so many proprietary ones people have to learn, when XSLT is an open, widely supported, standard with transferable skills!

    The above also doesn’t show how clean the code would really be, because someone using xsl:attribute is likely to use xsl:element as well, so really we should compare the legibility of this:

    <xsl:element name="h3">
        <xsl:attribute name="class">
            <xsl:value-of select="$product/@type" />
        </xsl:attribute>
        <xsl:value-of select="$product/name" />
    </xsl:element>

    … versus this:

    <h3 class="{$product/name}">
        <xsl:value-of select="$product/name" />
    </h3>

    Use template modes

    Often, you will want to use a template match for totally different purposes. Rather than pass unnecessary parameters or resort to different named templates, a mode attribute on the template can do the trick.

    For example, suppose you are showing an order history for some e-commerce site. Suppose you want a summary of orders at the top that anchor to the specific entries further down the page.

    You can have more than one template have the same match, and use mode to differentiate or indicate what they are used for.

    Consider this example. First, here is a starting point in the XSLT. The idea is to reuse the Orders element, one for summary purpose, the next for details.

    <!-- starting point -->
    <xsl:template match="/">
        <h1>Order summary</h1>
        <h2>Summary of orders</h2>
        <p><xsl:apply-templates select="./Orders" mode="summary-info" /></p>
        <h2>Table of orders</h2>
        <xsl:apply-templates select="./Orders" mode="order-summary-details" />
    </xsl:template>

    Next, we match Orders with the summary-info mode:

    <xsl:template match="Orders" mode="summary-info">
        <xsl:value-of select="concat(count(./Order), ' orders, from ', ./Order[1]/@date, ' to ', ./Order[last()]/@date)" />
    </xsl:template>

    We can also match Orders for the order-summary-details mode. Note how the variable has also re-used the other mode to get the summary for the table’s summary attribute.

    <xsl:template match="Orders" mode="order-summary-details">
        <xsl:variable name="summary">
            <xsl:apply-templates select="." mode="summary-info" />
        </xsl:variable>
        <table summary="{normalize-space($summary)}">
            <thead>
                <tr>
                    <th scope="col">Order number</th>
                    <th scope="col">Amount</th>
                    <th scope="col">Status</th>
                </tr>
            </thead>
            <tbody>
                <xsl:apply-templates select="./Order" mode="order-summary-details" />
            </tbody>
        </table>
    </xsl:template>

    Note how the same mode name can be used for additional matches. This is a neat way to keep related functionality together:

    <xsl:template match="Order" mode="order-summary-details">
        <tr>
            <td><a href="/order/details/?id={./@id}"><xsl:value-of select="./@id" /></a></td>
            <td><xsl:value-of select="./amount" /></td>
            <td><xsl:value-of select="./status" /></td>
        </tr>
    </xsl:template>

    In many real XSLTs I have written these modes can be re-used many times over. They help with performance, while maintaining this elegance/reduction of code because the XSLT processor can use that to narrow down which possible template matches to select from when looking for the one to execute.

    The use of modes (and other features such as importing other XSLTs and overriding moded templates) has allowed us to create multiple sub-sites in parallel (e.g. an ecommerce site that sells books, entertainment products (CDs, DVDs, computer games, etc) that all run off the same XSLTs with some minor customisation in each sub-site. Although the actual data is different, they fall into the same XML structure — they are products after all! — thus making the XSLTs highly reusable. A future post will describe arranging XSLTs in an almost object-oriented fashion).

    Use in-built functions: concat()

    The concat() function allows you to remove unnecessary and excessive uses of statements one after the other (and with the accompanying xsl:text /xsl:text type of trick to get a white space in there).

    Code looks easier to read, in most cases, and typically performs better too.

    Example:

    Instead of this:

    <xsl:value-of select="$string1" /><xsl:text> </xsl:text><xsl:value-of select="$string2" />

    This is much cleaner to read:

    <xsl:value-of select="concat($string1, ' ', $string2)" />

    Or,

    Instead of this:

    <a>
        <xsl:attribute name="href">
            <xsl:value-of select="$domain" />/product/?<xsl:value-of select="$someProductId" />
        </xsl:attribute>
        <xsl:value-of select="$productDescription" />
    </a>

    This is much cleaner to read:

    <a href="{concat($domain, '/product/?', $someProductId}">
        <xsl:value-of select="$productDescription" />
    </a>

    Storing a string resulting from a concat into a variable is also efficient from a performance point of view (storing node-sets does not cache the result, as in most DOM and XSLT implementations, node-sets are live collections. More on that in a future post).

    (Update: Azat notes in a comment below that the above href attribute can be even further simplified into this: href=”{$domain}/product/?{$someProductId}”.)

    Use in-built functions: boolean()

    How many times have we seen code like this:

    <xsl:if test="$new = 'true'"> ... </xsl:if>

    While it works, it is not ideal using string comparison, especially if this kind of test is going to be repeated in a template.

    It would be better to create a variable using this kind of syntax:

    <xsl:variable name="isNew" select="boolean($new = 'true')" />

    Then, in your code, when you need to use it, you can do things like:

    <xsl:if test="$isNew"> ... </xsl:if>

    or

    <xsl:if test="$isNew = true()"> ... </xsl:if>

    or

    <xsl:if test="$isNew = false()"> ... </xsl:if>

    or

    <xsl:if test="not($isNew)"> ... </xsl:if>

    These above variations are down to style/preference, but is better from a coding perspective than constant testing of strings. (Sometimes the calculation of what true or false means may require testing many values, such as true, True, 1, Y, etc. This can all be hidden away in that one variable declaration, and the rest of the code is unchanged.)

    (Update: Azat rightly notes in a comment below that the variable declaration can be made smaller by omitting the actual boolean function so it is just this: . I find the explicit use of boolean can aid with readability, especially for those new to XSLT so might be useful to retain under such situations.)

    Use in-built functions: string()

    Instead of this:

    <xsl:variable name="mystring">my text</variable>

    Consider this:

    <xsl:variable name="mystring" select="'my text'" />

    Or this:

    <xsl:variable name="mystring" select="string('my text')" />

    Or, more importantly, instead of this:

    <xsl:variable name="bookTitle"><xsl:value-of select="./title" /></xsl:variable>

    Consider this:

    <xsl:variable name="mystring" select="string(./title)" />

    Why?

    Code is cleaner to read.

    But it is also more optimal; casting to a string instead of storing the node will result in the variable value being cached in most XSLT processors, rather than being re-evaluated each time it is accessed. (XML nodes are live collections according to W3C which means they may change. Hence references to nodes require evaluation each time they are accessed.)

    Use in-built functions: number()

    For similar reasons as above to use string(), number() should be used too.

    Use in-built functions: other

    XPath functions such as starts-with(), string-length() are handy.

    For example, it is common to see code to test for the presence of strings by testing if a variable equals the empty string (”). But as most programmers should know, it is more efficient to test for the presence of a string by testing its length. In XPath expressions you can use string-length() function for this.

    For more information and full list of XPath functions, consider the following:

    • The XPath 1.0 Specification from the W3C
    • The MSDN XPath reference from Microsoft (Same as the W3C information, of course, but has useful examples)
    • Documentation from Stylus (also has some useful examples)

    More tips

    The above is about XPath 1.0 and XSLT 1.0. Even with the above tips, some XSLT can require more code than ideal, which XSLT 2.0 and XPath 2.0 help to address. The features in those are very useful for sure, but not as widely implemented as 1.0. My experiences are almost entirely in 1.0 which we use in live, production/run-time environments.

    Here are a some additional useful tips:

    • There are Monsters in My Closet or How Not to Use XSLT by R. Alexander Milowski from the School of Information Management and Systems, Berkeley
    • XSLT by Example is a blog of XSLT examples by Miguael deMelo

    Do you have any useful tips to augment/improve the above? Let me know and I will add them above

    Be Sociable, Share!

  • 2013-03-13-html5设计原理

    今天看了一篇文章,是Jeremy Keith在 Fronteers 2010 上的主题演讲
    (http://adactio.com/articles/1704/)的全文翻译
    (http://www.cn-cuckoo.com/2010/10/21/the-design-of-html5-2151.html)。

    这是一篇很好的文章,因为里面主要讲的是设计原理,
    (文章开头就提到“设计原理本质上是一种信念、一种想法、一个概念,是你行动的支柱。”)
    而且有很多很有意思的设计原理方面的格言:
    1.美国的设计原理:
    我们认为这些真理是不言而喻的,人人生而平等,
    造物主赋予了每个人不可剥夺的权利,包括生存、自由和追求幸福。
    We hold these Truths to be self-evident, that all Men are created equal,
    that they are endowed by their Creator with certain unalienable Rights,
    that among these are Life, Liberty and the pursuit of Happiness.
    2.卡尔·马克思的社会主义设计原理:各尽所能,各取所需。
    Karl Marx’s design principle for socialism:
    From each according to his ability, to each according to his need.
    3.圣经:人人为我,我为人人。
    Jesus Christ: Do unto others as you would have them do unto you.
    4.动物庄园设计原理:四条腿的都是好人,两条腿的都是坏蛋!
    Animal Farm’s design principle was: four legs good, two legs bad.
    5.阿西莫夫机器人三大法则:
    机器人不得伤害人类,或袖手旁观人类受伤害。
    机器人必须服从人类命令,除非命令违反第一法则。
    机器人必须自卫,只要不违背第一和第二法则。
    Isaac Asimov three laws of robotics:
    A robot may not injure a human being or,
    through inaction, allow a human being to come to harm.
    A robot must obey any orders given to it by human beings,
    except where such orders would conflict with the First Law.
    A robot must protect its own existence as long as such protection
    does not conflict with the First or Second Law.
    6.伯斯塔尔法则:发送时要保守;接收时要开放。
    Postel’s Law: Be conservative in what you send; be liberal in what you accept.
    7.html5: 避免不必要的复杂性。
    html5: Avoid needless complexity.
    8.html5: 支持已有的内容。
    html5: Support existing content.
    9.html5: 解决现实的问题。
    html5: Solve real problems.
    10.html5: 求真务实。
    html5: Pave the cowpaths.
    11.html5: 平稳退化。
    html5: Degrade gracefully.
    12.梅特卡夫定律:网络价值同网络用户数量的平方成正比。
    Metcalfe’s Law:
    The value of a network is proportional to the square of the number of connected users of the system.
    13.html5: 最终用户优先。
    一旦遇到冲突,最终用户优先,其次是作者,其次是实现者,
    其次标准制定者,最后才是理论上的完满。
    html5: Priority of constituencies.
    In case of conflict, consider users over authors
    over implementors over specifiers over theoretical purity.
    14.因此,我认为无论你做什么,不管是构建像HTML5这样的格式,
    还是构建一个网站,亦或一个内容管理系统,明确你的设计原理都至关重要。
    软件,就像所有技术一样,具有天然的政治性。代码必然会反映作者的选择、偏见和期望。
    So I think that whatever you’re doing, whether it’s building a format like HTML5 or
    whether it’s building a website, whether it’s building a content management system,
    having design principles is really really useful.
    Software, like all technologies, is inherently political.
    Code inevitably reflects the choices, biases and desires of its creators.
    15.马克·博尔顿和丽莎·雷贺特的设计原理:
    简化最常见的任务,让不常见的任务不至于太麻烦。
    只为80%设计。
    给内容创建者最大的权利。
    默认设置智能化。
    Mark Boulton and Leisa Reichelt’s four design principles:
    Make the most frequent tasks easy and less frequent tasks achievable.
    Design for the 80%.
    Privilege the Content Creator.
    Make the default settings smart.
    16.微格式的设计原理:首先为人类设计,其次为机器设计。
    Microformats’s design principles: Design for humans first, machines second.
    17.互联网哲学:大多数人的意见和运行的代码。
    Internet Philosophy:Rough consensus and running code.

    我的观点:
    我感觉设计原理是一种接近哲学的概念,虽然我以前没有仔细想过设计原理这个概念,
    但是直觉告诉我这是一个很重要的,长久以来被我忽略的概念,
    而且了解和思考这个概念必将对我的未来产生很大的影响。
    下面是我对上面那些设计原理的一些看法,
    当然我不可能一一铺开去讲,因为每一条原理都能铺开成一篇文章甚至一本书。
    a. 关于美国的设计原理。其实之前看经济学的时候我就研究过这句话。
    从某种角度讲,生存,自由和追求幸福的权利是相互重叠的。
    这三条其实对应了生命权,自由权和财产权。这三条可以归并成一条,就是自由权。
    因为我认为自由权就包括了你有权自由的支配自己的生命和合法财产。
    这就是为什么我一直很强调自由权的重要。
    这里合法财产也是一个很大的课题,我倾向于奥地利学派的观点。
    b. 关于马克思的社会主义想法。历史已经证明了他的观点只能是一个美好的愿望。
    因为人与人之间本质就不是相同的,这里的本质我是指的欲望,能力等等方面的不同。
    而且人有天生的惰性,天生就想不劳而获,各取所需注定是一句空话。
    有的人可能会相信马克思主义者的辩护,
    “现在不可以,但是生产力发展到物质极度丰富的时候就能实现各取所需了。”
    他们没有想到的是生产力发展会带来欲望的提高,
    也就是各取所需中的“需”会提着生产力发展而提高。
    比如十年前的人不可能有要iphone的需求,但是到现在这只是一个很普通的需求。
    c. 关于人人为我,我为人人。这一条原理也存在问题。
    问题就在于这个人人为我和我为人人有没有报酬,也就是用不用付钱。
    如果付钱,那就是市场交易,整个经济学都是建立在这个基础上,互通有无,交换提高双方的幸福度。
    如果不付钱,那就是宗教了。宗教鼓励我为人人,这样自然而然就会人人为我。
    但是其中的问题是每个人都人人为我多一点,我为人人少一点,能占便宜就占便宜。
    这是天性,由基因决定的,无法改变。
    因为那些整天想着我为人人的物种或者个体已经被进化所淘汰了。
    所以人人为我,我为人人这种宗教机制用来作为社会的缓解矛盾的缓冲器还可以,
    如果想用它来作为整个社会的基础,那它就跟马克思主义没有分别了,注定是行不通的。
    d. 关于机器人三大法则。我之前看过阿西莫夫的小说,
    小说很精彩,但是现实中我觉得至少现在是没有办法让机器人来遵守三大法则的。
    而现实中的机器人已经可以做很多事了,美国甚至已经研制出了用来杀人的机器人。
    不知道这是不是一件的可怕的事。
    e. 关于html5的几条设计原理。我觉得这些原理不仅仅对html5的设计有用,
    对任何程序的设计都是有用的。比如发送时要保守;接收时要开放。比如避免不必要的复杂性。
    比如支持已有的内容。还有解决现实的问题。
    f. 关于求真务实(Pave the cowpaths.)。
    我认为这个翻译其实不太准确。我觉得应该翻译成承认既定事实。
    我以前在关于美国的历史上立法过程的文章中就看到过这种原理。
    这里面的逻辑其实是最终的用户自己就会产生一种解释问题的方案,
    不论是争论法律争端还是解决html中的问题,用户是最先接触问题的人,
    所以最有可能想出解决问题的方法。立法者或者标准制定者只要择其善者而从之就可以了。
    g. 关于平稳退化。
    其实我觉得平稳退化,支持已有内容和接收时要开放可以归为一条,保持连续性。
    h. 关于最终用户优先。
    其实这一条与求真务实有相通之处,都是要把最终用户放在优先的位置。
    我觉得这一条用在公司管理里面也是对的,一个成功的公司一定是解决了用户的一种需求。
    所以一定要把用户放在优先的位置,公司内部越接近客户就越重要。
    老板作为规则制定者要把自己摆在最后,尊重支持比自己优先级高的人,
    如果发现优先级高的人产生了对用户有用的方案,那就推广它,把它制定成标准。
    i. 关于代码有政治性。
    我有体会,因为有些人的代码只是为了解决问题,不去考虑性能,扩展性,代码是否简洁这些问题,
    而另外一些人力图把代码模块化,简洁优雅。我以前觉得这只是代码风格和编码素质的问题。
    现在仔细想想其实这些区别反映了代码作者的设计思想甚至价值观,有的作者只是为完成任务,
    而另外一些作者是为了创造自己的作品甚至想到把代码共享出去造福社会。
    j. 关于马克·博尔顿的几个设计原理。
    以前没有意识到设计原理的重要性,所以我也没有总结归纳自己的设计原理。
    现在看来我要开始留心总结归纳自己的设计原理了。我直觉中想到的有这么几条:
    一.要模块化。二.要简洁。三.要有连续性。四.要有统一的风格和清楚的注释。

  • 2011-04-04-圆周率pi和自然对数底e小数点后一万位

    2011-04-04-圆周率pi和自然对数底e小数点后一万位(2011-04-04 13:52:14)

    Fortran77源程序计算圆周率pi和自然对数底e小数点后一万位

    前段时间看到google的一个招聘广告:

    Google在旧金山的101公路上曾放出一块广告牌,写着:“常数E里出现的连续的第一个10位质数.Com”。

    虽然在网上可以找到答案,但是我就很好奇,想要自己编程计算出来。然后就用fortran77写了程序来计算自然对数底e和圆周率pi.

    fortran77的编译器可以从这里下载
    http://www.math.hawaii.edu/lab/197/fortran_instr_hile.html
    我编的程序计算了pi和e小数点后面一万位,精确到小数点后9996位。
    计算结果给出了pi和e的值,还给出了一万位以内的所有十位数的质数。

    算法分别是
    pi=16actan(1/5)-4actan(1/239)
    actan(x)=x-x*3/3+x5/5-x*7/7+….

    e=1+1/2!+1/3!+1/4!+…..+1/n!

    程序的算法没有经过优化,因为反正是自娱自乐,对计算速度没什么要求。
    在本人的机器上计算出来结果只需要不到十秒钟。

    欢迎大家转载,但是请保留原文链接。
    http://blog.sina.com.cn/s/blog_4fb4b6ba0100qfln.html
    下面是计算的程序和结果。
    有兴趣的同学可以下个fortran77的编译器自己运行编译一下,很酷哦!

    计算圆周率:

    C    This program is free software: you can redistribute it and/or
          C    modify
          C    it under the terms of the GNU General Public License as
          C    published by
          C    the Free Software Foundation, either version 3 of the
          C    License, or
          C    (at your option) any later version.
          C
          C    This program is distributed in the hope that it will be
          C    useful,
          C    but WITHOUT ANY WARRANTY; without even the implied warranty
          C    of
          C    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          C    GNU General Public License for more details.
          C
          C   You should have received a copy of the GNU General Public
          C   License
          C    along with this program.  If not, see
          C    <http://www.gnu.org/licenses/>.
          C
          C Author: Cheng GONG, gongchengym@sina.com 
          C Date: 2011-040-04
          C pi=16actan(1/5)-4actan(1/239
          C actan(x)=x-x^3/3+x^5/5-x^7/7+x^9/9+....
          C pi=3.2-4/239-1/3*(3.2/25-4/239**3)+1/5*(3.2/25**2-4/239**5)
          implicit real*8(a-h,o-z)
          parameter(nk=10000)
          dimension ns(nk),na1(nk),na2(nk),nt1(nk),nt2(nk),np1(nk),np2(nk)
          do i=1,nk
          ns(i)=0
          na1(i)=0
          na2(i)=0
          nt1(i)=0
          nt2(i)=0
          np1(i)=0
          np2(i)=0
          end do
          nt1(2)=3
          nt1(3)=2
          nt2(2)=4
          do i=2,nk
          na2(i)=nt2(i)
          nd=mod(na2(i-1),239)*10+na2(i)
          nt2(i)=nd/239
          na2(i)=mod(nd,239)
          end do
          do i=1,nk
          ns(i)=ns(i)+nt1(i)
          end do
          do i=nk,2,-1
          ntmp=ns(i)
          if(ntmp.ge.nt2(i)) ns(i)=ns(i)-nt2(i)
          if(ntmp.lt.nt2(i)) then
              ns(i)=ns(i)+10-nt2(i)
              ns(i-1)=ns(i-1)-1
          end if
          end do
          n=1
          nflag=1
          do j=1,nk
          n=n+2
          nflag=-1*nflag
          do i=2,nk
          na1(i)=nt1(i)
          nd=mod(na1(i-1),25)*10+na1(i)
          nt1(i)=nd/25
          na1(i)=mod(nd,25)
          end do
          do i=2,nk
          na1(i)=nt1(i)
          nd=mod(na1(i-1),n)*10+na1(i)
          np1(i)=nd/n
          na1(i)=mod(nd,n)
          end do
          do i=2,nk
          na2(i)=nt2(i)
          nd=mod(na2(i-1),57121)*10+na2(i)
          nt2(i)=nd/57121
          na2(i)=mod(nd,57121)
          end do
          do i=2,nk
          na2(i)=nt2(i)
          nd=mod(na2(i-1),n)*10+na2(i)
          np2(i)=nd/n
          na2(i)=mod(nd,n)
          end do
          if(nflag.lt.0) then
              do i=2,nk
              ns(i)=ns(i)+np2(i)
              end do
              do i=nk,2,-1
              ntmp=ns(i)
              if(ntmp.ge.np1(i)) ns(i)=ns(i)-np1(i)
              if(ntmp.lt.np1(i)) then
                  ns(i)=ns(i)+10-np1(i)
                  ns(i-1)=ns(i-1)-1
              end if
              ns(i-1)=ns(i-1)+ns(i)/10
              ns(i)=mod(ns(i),10)
              end do
          end if
          if(nflag.gt.0) then
              do i=2,nk
              ns(i)=ns(i)+np1(i)
              end do
              do i=nk,2,-1
              ntmp=ns(i)
              if(ntmp.ge.np2(i)) ns(i)=ns(i)-np2(i)
              if(ntmp.lt.np2(i)) then
                  ns(i)=ns(i)+10-np2(i)
                  ns(i-1)=ns(i-1)-1
              end if
              ns(i-1)=ns(i-1)+ns(i)/10
              ns(i)=mod(ns(i),10)
              end do
          end if
          end do
          open(60,file="pi.txt")
          write(60,'(1a)'),"pi=3."
          write(60,'(50i1)')(ns(i),i=3,nk)
          write(*,'(a)'),'The ten digital primes in pi:'
          write(60,'(a)'),'The ten digital primes in pi:'
          do i=2,nk-10
          tmp=0
          if (ns(i).ne.0) then
              do j=i,i+9
              tmp=tmp*10+ns(j)
              end do
              nst=sqrt(tmp)
              do it=2,nst
              if (mod(tmp,it).eq.0) then 
                  goto 13
              end if 
              end do
              13 if (it.gt.nst) then
                  write(*,'(i5,f15.1)'),i,tmp
                  write(60,'(i5,f15.1)'),i,tmp
              end if
          end if
          end do
          close(60)
          stop
          end

    结果:
    pi=3.
    14159265358979323846264338327950288419716939937510
    58209749445923078164062862089986280348253421170679
    82148086513282306647093844609550582231725359408128
    48111745028410270193852110555964462294895493038196
    44288109756659334461284756482337867831652712019091
    45648566923460348610454326648213393607260249141273
    72458700660631558817488152092096282925409171536436
    78925903600113305305488204665213841469519415116094
    33057270365759591953092186117381932611793105118548
    07446237996274956735188575272489122793818301194912
    98336733624406566430860213949463952247371907021798
    60943702770539217176293176752384674818467669405132
    00056812714526356082778577134275778960917363717872
    14684409012249534301465495853710507922796892589235
    42019956112129021960864034418159813629774771309960
    51870721134999999837297804995105973173281609631859
    50244594553469083026425223082533446850352619311881
    71010003137838752886587533208381420617177669147303
    59825349042875546873115956286388235378759375195778
    18577805321712268066130019278766111959092164201989
    38095257201065485863278865936153381827968230301952
    03530185296899577362259941389124972177528347913151
    55748572424541506959508295331168617278558890750983
    81754637464939319255060400927701671139009848824012
    85836160356370766010471018194295559619894676783744
    94482553797747268471040475346462080466842590694912
    93313677028989152104752162056966024058038150193511
    25338243003558764024749647326391419927260426992279
    67823547816360093417216412199245863150302861829745
    55706749838505494588586926995690927210797509302955
    32116534498720275596023648066549911988183479775356
    63698074265425278625518184175746728909777727938000
    81647060016145249192173217214772350141441973568548
    16136115735255213347574184946843852332390739414333
    45477624168625189835694855620992192221842725502542
    56887671790494601653466804988627232791786085784383
    82796797668145410095388378636095068006422512520511
    73929848960841284886269456042419652850222106611863
    06744278622039194945047123713786960956364371917287
    46776465757396241389086583264599581339047802759009
    94657640789512694683983525957098258226205224894077
    26719478268482601476990902640136394437455305068203
    49625245174939965143142980919065925093722169646151
    57098583874105978859597729754989301617539284681382
    68683868942774155991855925245953959431049972524680
    84598727364469584865383673622262609912460805124388
    43904512441365497627807977156914359977001296160894
    41694868555848406353422072225828488648158456028506
    01684273945226746767889525213852254995466672782398
    64565961163548862305774564980355936345681743241125
    15076069479451096596094025228879710893145669136867
    22874894056010150330861792868092087476091782493858
    90097149096759852613655497818931297848216829989487
    22658804857564014270477555132379641451523746234364
    54285844479526586782105114135473573952311342716610
    21359695362314429524849371871101457654035902799344
    03742007310578539062198387447808478489683321445713
    86875194350643021845319104848100537061468067491927
    81911979399520614196634287544406437451237181921799
    98391015919561814675142691239748940907186494231961
    56794520809514655022523160388193014209376213785595
    66389377870830390697920773467221825625996615014215
    03068038447734549202605414665925201497442850732518
    66600213243408819071048633173464965145390579626856
    10055081066587969981635747363840525714591028970641
    40110971206280439039759515677157700420337869936007
    23055876317635942187312514712053292819182618612586
    73215791984148488291644706095752706957220917567116
    72291098169091528017350671274858322287183520935396
    57251210835791513698820914442100675103346711031412
    67111369908658516398315019701651511685171437657618
    35155650884909989859982387345528331635507647918535
    89322618548963213293308985706420467525907091548141
    65498594616371802709819943099244889575712828905923
    23326097299712084433573265489382391193259746366730
    58360414281388303203824903758985243744170291327656
    18093773444030707469211201913020330380197621101100
    44929321516084244485963766983895228684783123552658
    21314495768572624334418930396864262434107732269780
    28073189154411010446823252716201052652272111660396
    66557309254711055785376346682065310989652691862056
    47693125705863566201855810072936065987648611791045
    33488503461136576867532494416680396265797877185560
    84552965412665408530614344431858676975145661406800
    70023787765913440171274947042056223053899456131407
    11270004078547332699390814546646458807972708266830
    63432858785698305235808933065757406795457163775254
    20211495576158140025012622859413021647155097925923
    09907965473761255176567513575178296664547791745011
    29961489030463994713296210734043751895735961458901
    93897131117904297828564750320319869151402870808599
    04801094121472213179476477726224142548545403321571
    85306142288137585043063321751829798662237172159160
    77166925474873898665494945011465406284336639379003
    97692656721463853067360965712091807638327166416274
    88880078692560290228472104031721186082041900042296
    61711963779213375751149595015660496318629472654736
    42523081770367515906735023507283540567040386743513
    62222477158915049530984448933309634087807693259939
    78054193414473774418426312986080998886874132604721
    56951623965864573021631598193195167353812974167729
    47867242292465436680098067692823828068996400482435
    40370141631496589794092432378969070697794223625082
    21688957383798623001593776471651228935786015881617
    55782973523344604281512627203734314653197777416031
    99066554187639792933441952154134189948544473456738
    31624993419131814809277771038638773431772075456545
    32207770921201905166096280490926360197598828161332
    31666365286193266863360627356763035447762803504507
    77235547105859548702790814356240145171806246436267
    94561275318134078330336254232783944975382437205835
    31147711992606381334677687969597030983391307710987
    04085913374641442822772634659470474587847787201927
    71528073176790770715721344473060570073349243693113
    83504931631284042512192565179806941135280131470130
    47816437885185290928545201165839341965621349143415
    95625865865570552690496520985803385072242648293972
    85847831630577775606888764462482468579260395352773
    48030480290058760758251047470916439613626760449256
    27420420832085661190625454337213153595845068772460
    29016187667952406163425225771954291629919306455377
    99140373404328752628889639958794757291746426357455
    25407909145135711136941091193932519107602082520261
    87985318877058429725916778131496990090192116971737
    27847684726860849003377024242916513005005168323364
    35038951702989392233451722013812806965011784408745
    19601212285993716231301711444846409038906449544400
    61986907548516026327505298349187407866808818338510
    22833450850486082503930213321971551843063545500766
    82829493041377655279397517546139539846833936383047
    46119966538581538420568533862186725233402830871123
    28278921250771262946322956398989893582116745627010
    21835646220134967151881909730381198004973407239610
    36854066431939509790190699639552453005450580685501
    95673022921913933918568034490398205955100226353536
    19204199474553859381023439554495977837790237421617
    27111723643435439478221818528624085140066604433258
    88569867054315470696574745855033232334210730154594
    05165537906866273337995851156257843229882737231989
    87571415957811196358330059408730681216028764962867
    44604774649159950549737425626901049037781986835938
    14657412680492564879855614537234786733039046883834
    36346553794986419270563872931748723320837601123029
    91136793862708943879936201629515413371424892830722
    01269014754668476535761647737946752004907571555278
    19653621323926406160136358155907422020203187277605
    27721900556148425551879253034351398442532234157623
    36106425063904975008656271095359194658975141310348
    22769306247435363256916078154781811528436679570611
    08615331504452127473924544945423682886061340841486
    37767009612071512491404302725386076482363414334623
    51897576645216413767969031495019108575984423919862
    91642193994907236234646844117394032659184044378051
    33389452574239950829659122850855582157250310712570
    12668302402929525220118726767562204154205161841634
    84756516999811614101002996078386909291603028840026
    91041407928862150784245167090870006992821206604183
    71806535567252532567532861291042487761825829765157
    95984703562226293486003415872298053498965022629174
    87882027342092222453398562647669149055628425039127
    57710284027998066365825488926488025456610172967026
    64076559042909945681506526530537182941270336931378
    51786090407086671149655834343476933857817113864558
    73678123014587687126603489139095620099393610310291
    61615288138437909904231747336394804575931493140529
    76347574811935670911013775172100803155902485309066
    92037671922033229094334676851422144773793937517034
    43661991040337511173547191855046449026365512816228
    82446257591633303910722538374218214088350865739177
    15096828874782656995995744906617583441375223970968
    34080053559849175417381883999446974867626551658276
    58483588453142775687900290951702835297163445621296
    40435231176006651012412006597558512761785838292041
    97484423608007193045761893234922927965019875187212
    72675079812554709589045563579212210333466974992356
    30254947802490114195212382815309114079073860251522
    74299581807247162591668545133312394804947079119153
    26734302824418604142636395480004480026704962482017
    92896476697583183271314251702969234889627668440323
    26092752496035799646925650493681836090032380929345
    95889706953653494060340216654437558900456328822505
    45255640564482465151875471196218443965825337543885
    69094113031509526179378002974120766514793942590298
    96959469955657612186561967337862362561252163208628
    69222103274889218654364802296780705765615144632046
    92790682120738837781423356282360896320806822246801
    22482611771858963814091839036736722208883215137556
    00372798394004152970028783076670944474560134556417
    25437090697939612257142989467154357846878861444581
    23145935719849225284716050492212424701412147805734
    55105008019086996033027634787081081754501193071412
    23390866393833952942578690507643100638351983438934
    15961318543475464955697810382930971646514384070070
    73604112373599843452251610507027056235266012764848
    30840761183013052793205427462865403603674532865105
    70658748822569815793678976697422057505968344086973
    50201410206723585020072452256326513410559240190274
    21624843914035998953539459094407046912091409387001
    26456001623742880210927645793106579229552498872758
    461012648369998922569596881592056001016552563793
    The ten digital primes in pi:
    6 5926535897.0
    38 4197169399.0
    42 1693993751.0
    49 7510582097.0
    89 4825342117.0
    135 5822317253.0
    162 2841027019.0
    173 8521105559.0
    191 8954930381.0
    225 4756482337.0
    243 2712019091.0
    274 5432664821.0
    276 3266482133.0
    288 6072602491.0
    317 5588174881.0
    324 8815209209.0
    334 6282925409.0
    339 2540917153.0
    357 5903600113.0
    375 8204665213.0
    384 3841469519.0
    402 4330572703.0
    415 5959195309.0
    427 8611738193.0
    433 8193261179.0
    452 8074462379.0
    476 5752724891.0
    483 8912279381.0
    492 1830119491.0
    602 2000568127.0
    621 8277857713.0
    627 7713427577.0
    637 8960917363.0
    653 1468440901.0
    690 2796892589.0
    710 6112129021.0
    727 3441815981.0
    736 1362977477.0
    749 9960518707.0
    776 8049951059.0
    779 9951059731.0
    784 5973173281.0
    787 3173281609.0
    819 3026425223.0
    847 3118817101.0
    852 1710100031.0
    869 2886587533.0
    893 7669147303.0
    895 6914730359.0
    938 3787593751.0
    965 1226806613.0
    1128 5331168617.0
    1159 3746493931.0
    1170 2550604009.0
    1197 8240128583.0
    1221 1047101819.0
    1257 2553797747.0
    1263 7747268471.0
    1270 4710404753.0
    1291 8425906949.0
    1314 9891521047.0
    1323 7521620569.0
    1375 9647326391.0
    1388 9272604269.0
    1389 2726042699.0
    1432 2458631503.0
    1459 4983850549.0
    1487 7210797509.0
    1532 5499119881.0
    1579 1757467289.0
    1588 9097777279.0
    1595 2793800081.0
    1616 5249192173.0
    1623 1732172147.0
    1670 3475741849.0
    1679 9468438523.0
    1682 8438523323.0
    1691 3907394143.0
    1698 1433345477.0
    1735 1922218427.0
    1756 8767179049.0
    1814 1454100953.0
    1874 6945604241.0
    1906 4427862203.0
    1916 9194945047.0
    1917 1949450471.0
    1947 9172874677.0
    1952 7467764657.0
    1963 7396241389.0
    1993 7802759009.0
    2004 4657640789.0
    2006 5764078951.0
    2020 6839835259.0
    2062 6848260147.0
    2073 9909026401.0
    2093 5305068203.0
    2113 4939965143.0
    2130 1906592509.0
    2137 5093722169.0
    2143 2169646151.0
    2167 9788595977.0
    2180 5498930161.0
    2184 9301617539.0
    2190 7539284681.0
    2198 8138268683.0
    2230 4595395943.0
    2411 9452267467.0
    2416 6746767889.0
    2436 5499546667.0
    2451 9864565961.0
    2465 4886230577.0
    2491 6817432411.0
    2515 5109659609.0
    2524 9402522887.0
    2547 1368672287.0
    2574 6179286809.0
    2589 7609178249.0
    2590 6091782493.0
    2612 9675985261.0
    2623 6554978189.0
    2643 6829989487.0
    2654 2658804857.0
    2678 5132379641.0
    2727 1413547357.0
    2738 9523113427.0
    2742 1134271661.0
    2746 2716610213.0
    2771 2484937187.0
    2788 6540359027.0
    2841 6833214457.0
    2850 7138687519.0
    2857 5194350643.0
    2941 2371819217.0
    2973 1426912397.0
    2991 1864942319.0
    2997 2319615679.0
    3031 8193014209.0
    3050 5956638937.0
    3104 3068038447.0
    3138 4974428507.0
    3139 9744285073.0
    3150 5186660021.0
    3159 1324340881.0
    3207 5081066587.0
    3213 6587969981.0
    3219 9981635747.0
    3243 1028970641.0
    3273 7595156771.0
    3293 7869936007.0
    3313 7635942187.0
    3315 3594218731.0
    3331 2053292819.0
    3351 8673215791.0
    3450 3965725121.0
    3456 5121083579.0
    3462 3579151369.0
    3477 1444210067.0
    3537 1685171437.0
    3540 5171437657.0
    3570 8599823873.0
    3595 4791853589.0
    3600 5358932261.0
    3607 2618548963.0
    3613 8963213293.0
    3656 9859461637.0
    3672 9819943099.0
    3696 8905923233.0
    3722 3573265489.0
    3726 2654893823.0
    3728 5489382391.0
    3730 8938239119.0
    3760 4281388303.0
    3786 4374417029.0
    3787 3744170291.0
    3788 7441702913.0
    3821 6921120191.0
    3841 1976211011.0
    3948 6978028073.0
    3951 8028073189.0
    3956 7318915441.0
    4001 9666557309.0
    4026 3466820653.0
    4029 6820653109.0
    4036 1098965269.0
    4090 7648611791.0
    4101 4533488503.0
    4149 5560845529.0
    4211 7659134401.0
    4240 3899456131.0
    4268 3269939081.0
    4283 4645880797.0
    4297 2668306343.0
    4306 3285878569.0
    4308 8587856983.0
    4319 5235808933.0
    4323 8089330657.0
    4451 1129961489.0
    4563 1472213179.0
    4569 3179476477.0
    4592 4540332157.0
    4599 1571853061.0
    4617 5850430633.0
    4641 2371721591.0
    4689 8433663937.0
    4690 4336639379.0
    4802 6617119637.0
    4813 9213375751.0
    4814 2133757511.0
    4830 1566049631.0
    4944 6932599397.0
    4951 3978054193.0
    4957 4193414473.0
    4959 9341447377.0
    4976 3129860809.0
    4985 9988868741.0
    5018 7302163159.0
    5028 8193195167.0
    5041 8129741677.0
    5065 6543668009.0
    5071 8009806769.0
    5121 9409243237.0
    5130 7896907069.0
    5149 5082216889.0
    5151 8221688957.0
    5154 1688957383.0
    5160 7383798623.0
    5175 3776471651.0
    5180 7165122893.0
    5196 5881617557.0
    5278 2154134189.0
    5286 8994854447.0
    5300 7383162499.0
    5330 3863877343.0
    5333 3877343177.0
    5371 6609628049.0
    5388 1975988281.0
    5399 1332316663.0
    5443 2803504507.0
    5461 1058595487.0
    5470 7027908143.0
    5521 3033625423.0
    5532 7839449753.0
    5558 7119926063.0
    5561 9926063813.0
    5588 9833913077.0
    5614 6414428227.0
    5635 4745878477.0
    5641 8477872019.0
    5656 2807317679.0
    5680 7306057007.0
    5729 1798069411.0
    5747 4701304781.0
    5751 3047816437.0
    5774 4520116583.0
    5776 2011658393.0
    5784 9341965621.0
    5785 3419656213.0
    5787 1965621349.0
    5820 6904965209.0
    5841 2426482939.0
    5850 9728584783.0
    5880 6248246857.0
    5961 8320856611.0
    5997 7724602901.0
    6046 6455377991.0
    6074 8963995879.0
    6076 6399587947.0
    6108 9091451357.0
    6114 1357111369.0
    6129 1939325191.0
    6143 2082520261.0
    6153 8798531887.0
    6176 7781314969.0
    6180 3149699009.0
    6186 9009019211.0
    6191 1921169717.0
    6257 8951702989.0
    6263 2989392233.0
    6309 1228599371.0
    6312 8599371623.0
    6337 9038906449.0
    6349 4400619869.0
    6370 3275052983.0
    6372 7505298349.0
    6420 5039302133.0
    6468 5527939751.0
    6477 1754613953.0
    6478 7546139539.0
    6490 6833936383.0
    6523 5685338621.0
    6551 2328278921.0
    6571 4632295639.0
    6577 5639898989.0
    6606 3564622013.0
    6608 6462201349.0
    6616 4967151881.0
    6626 9097303811.0
    6654 6854066431.0
    6662 3193950979.0
    6671 9019069963.0
    6709 2292191393.0
    6711 9219139339.0
    6718 3391856803.0
    6729 4903982059.0
    6732 3982059551.0
    6745 2635353619.0
    6750 5361920419.0
    6783 9597783779.0
    6786 7783779023.0
    6798 2161727111.0
    6812 4343543947.0
    6829 5286240851.0
    6856 6986705431.0
    6880 5503323233.0
    6915 6627333799.0
    6919 3337995851.0
    7068 6487985561.0
    7121 7056387293.0
    7128 2931748723.0
    7133 4872332083.0
    7147 1230299113.0
    7158 7938627089.0
    7164 7089438799.0
    7174 3620162951.0
    7178 1629515413.0
    7219 6535761647.0
    7254 9653621323.0
    7296 7277605277.0
    7313 6148425551.0
    7343 2234157623.0
    7346 4157623361.0
    7369 5008656271.0
    7387 4658975141.0
    7425 6078154781.0
    7458 3315044521.0
    7464 4521274739.0
    7513 2071512491.0
    7550 6235189757.0
    7594 4239198629.0
    7603 9164219399.0
    7605 6421939949.0
    7621 3464684411.0
    7645 4437805133.0
    7648 7805133389.0
    7653 3338945257.0
    7656 8945257423.0
    7658 4525742399.0
    7679 8508555821.0
    7689 5725031071.0
    7737 4154205161.0
    7740 4205161841.0
    7776 9960783869.0
    7795 2884002691.0
    7801 2691041407.0
    7802 6910414079.0
    7808 4079288621.0
    7843 1206604183.0
    7859 3556725253.0
    7879 2910424877.0
    7910 3562226293.0
    7972 3398562647.0
    7991 6284250391.0
    7995 2503912757.0
    8005 7102840279.0
    8047 9670266407.0
    8089 4127033693.0
    8091 2703369313.0
    8128 4343476933.0
    8160 3014587687.0
    8189 9939361031.0
    8206 1528813843.0
    8217 9099042317.0
    8250 5297634757.0
    8254 6347574811.0
    8255 3475748119.0
    8279 1721008031.0
    8297 3090669203.0
    8312 2203322909.0
    8330 5142214477.0
    8366 7511173547.0
    8378 1855046449.0
    8403 8244625759.0
    8410 7591633303.0
    8414 6333039107.0
    8461 8747826569.0
    8491 3752239709.0
    8548 5827658483.0
    8554 8483588453.0
    8559 8845314277.0
    8568 7568790029.0
    8581 1702835297.0
    8703 7267507981.0
    8741 4669749923.0
    8758 9478024901.0
    8777 8281530911.0
    8780 1530911407.0
    8790 9073860251.0
    8804 4299581807.0
    8865 1860414263.0
    8910 6697583183.0
    8912 9758318327.0
    8923 3142517029.0
    8956 9275249603.0
    8972 6925650493.0
    8998 2934595889.0
    9007 9706953653.0
    9029 6544375589.0
    9063 4482465151.0
    9095 3754388569.0
    9151 9896959469.0
    9170 1865619673.0
    9199 8628692221.0
    9221 5436480229.0
    9226 8022967807.0
    9300 8012248261.0
    9303 2248261177.0
    9308 6117718589.0
    9347 1375560037.0
    9376 7830766709.0
    9404 5437090697.0
    9445 6144458123.0
    9487 4701412147.0
    9504 5105008019.0
    9522 3027634787.0
    9545 9307141223.0
    9553 2339086639.0
    9582 6431006383.0
    9598 3893415961.0
    9642 1438407007.0
    9657 4112373599.0
    9688 2352660127.0
    9701 4830840761.0
    9815 2358502007.0
    9927 4579310657.0
    9939 2955249887.0


    计算自然对数底e

    C    This program is free software: you can redistribute it and/or modify
    C    it under the terms of the GNU General Public License as published by
    C    the Free Software Foundation, either version 3 of the License, or
    C    (at your option) any later version.
    C
    C    This program is distributed in the hope that it will be useful,
    C    but WITHOUT ANY WARRANTY; without even the implied warranty of
    C    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    C    GNU General Public License for more details.
    C
    C   You should have received a copy of the GNU General Public License
    C    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    C
    C Author: Cheng GONG, gongchengym@sina.com 
    C Date: 2011-040-04
    C e=1+1/1!+1/2!+1/3!+1/4!+1/5!+...+1/n!
    
    implicit real*8(a-h,o-z)
    parameter(nk=10000,np=100000)
    dimension ns(nk),na(nk),nt(nk),nprime(np/10)
    
    
    C calculate how many digitals.
    C s=1.0
    C do i=1,5000
    C s=s+log10(i*1.0)
    C end do
    C print *,s
    do i=1,nk
    na(i)=0
    ns(i)=0
    nt(i)=0
    end do
    na(1)=1
    ns(1)=2
    
    
    n=1
    do j=1,5000
    n=n+1
    do i=2,nk
    nd=mod(na(i-1),n)*10+nt(i) 
    nt(i)=nd/n
    na(i)=mod(nd,n)
    end do
    do i=1,nk
    na(i)=nt(i)
    ns(i)=ns(i)+nt(i)
    end do
    do i=nk,2,-1
    ns(i-1)=ns(i-1)+ns(i)/10
    ns(i)=mod(ns(i),10)
    end do
    end do
    
    
    open(60,file="e.txt")
    write(60,'(1a)'),"e=2."
    write(60,'(8x,77i1)')(ns(i),i=2,77)
    write(60,'(80i1)')(ns(i),i=78,nk)
    write(*,'(a)'),'The ten digital primes in e:'
    write(60,'(a)'),'The ten digital primes in e:'
    do i=2,nk-10
    C i=2
    tmp=0
    if(ns(i).ne.0) then
    do j=i,i+9
    tmp=tmp*10+ns(j)
    end do
    nst=sqrt(tmp)
    do it=2,nst
    if (mod(tmp,it).eq.0) then 
    goto 13
    end if 
    end do
    13 if (it.gt.nst) then
    write(*,'(i5,f15.1)'),i,tmp
    write(60,'(i5,f15.1)'),i,tmp
    end if
    end if
    end do
    
    
    
    
    close(60)
    
    
    stop
    end

    结果:

    e=2.
    7182818284590452353602874713526624977572470936999595749669676277240766303535
    47594571382178525166427427466391932003059921817413596629043572900334295260595630
    73813232862794349076323382988075319525101901157383418793070215408914993488416750
    92447614606680822648001684774118537423454424371075390777449920695517027618386062
    61331384583000752044933826560297606737113200709328709127443747047230696977209310
    14169283681902551510865746377211125238978442505695369677078544996996794686445490
    59879316368892300987931277361782154249992295763514822082698951936680331825288693
    98496465105820939239829488793320362509443117301238197068416140397019837679320683
    28237646480429531180232878250981945581530175671736133206981125099618188159304169
    03515988885193458072738667385894228792284998920868058257492796104841984443634632
    44968487560233624827041978623209002160990235304369941849146314093431738143640546
    25315209618369088870701676839642437814059271456354906130310720851038375051011574
    77041718986106873969655212671546889570350354021234078498193343210681701210056278
    80235193033224745015853904730419957777093503660416997329725088687696640355570716
    22684471625607988265178713419512466520103059212366771943252786753985589448969709
    64097545918569563802363701621120477427228364896134225164450781824423529486363721
    41740238893441247963574370263755294448337998016125492278509257782562092622648326
    27793338656648162772516401910590049164499828931505660472580277863186415519565324
    42586982946959308019152987211725563475463964479101459040905862984967912874068705
    04895858671747985466775757320568128845920541334053922000113786300945560688166740
    01698420558040336379537645203040243225661352783695117788386387443966253224985065
    49958862342818997077332761717839280349465014345588970719425863987727547109629537
    41521115136835062752602326484728703920764310059584116612054529703023647254929666
    93811513732275364509888903136020572481765851180630364428123149655070475102544650
    11727211555194866850800368532281831521960037356252794495158284188294787610852639
    81395599006737648292244375287184624578036192981971399147564488262603903381441823
    26251509748279877799643730899703888677822713836057729788241256119071766394650706
    33045279546618550966661856647097113444740160704626215680717481877844371436988218
    55967095910259686200235371858874856965220005031173439207321139080329363447972735
    59552773490717837934216370120500545132638354400018632399149070547977805669785335
    80489669062951194324730995876552368128590413832411607226029983305353708761389396
    39177957454016137223618789365260538155841587186925538606164779834025435128439612
    94603529133259427949043372990857315802909586313826832914771163963370924003168945
    86360606458459251269946557248391865642097526850823075442545993769170419777800853
    62730941710163434907696423722294352366125572508814779223151974778060569672538017
    18077636034624592787784658506560507808442115296975218908740196609066518035165017
    92504619501366585436632712549639908549144200014574760819302212066024330096412704
    89439039717719518069908699860663658323227870937650226014929101151717763594460202
    32493002804018677239102880978666056511832600436885088171572386698422422010249505
    51881694803221002515426494639812873677658927688163598312477886520141174110913601
    16499507662907794364600585194199856016264790761532103872755712699251827568798930
    27617611461625493564959037980458381823233686120162437365698467037858533052758333
    37939907521660692380533698879565137285593883499894707416181550125397064648171946
    70834819721448889879067650379590366967249499254527903372963616265897603949857674
    13973594410237443297093554779826296145914429364514286171585873397467918975712119
    56187385783644758448423555581050025611492391518893099463428413936080383091662818
    81150371528496705974162562823609216807515017772538740256425347087908913729172282
    86115159156837252416307722544063378759310598267609442032619242853170187817729602
    35413060672136046000389661093647095141417185777014180606443636815464440053316087
    78314317444081194942297559931401188868331483280270655383300469329011574414756313
    99972217038046170928945790962716622607407187499753592127560844147378233032703301
    68237193648002173285734935947564334129943024850235732214597843282641421684878721
    67336701061509424345698440187331281010794512722373788612605816566805371439612788
    87325273738903928905068653241380627960259303877276977837928684093253658807339884
    57218746021005311483351323850047827169376218004904795597959290591655470505777514
    30817511269898518840871856402603530558373783242292418562564425502267215598027401
    26179719280471396006891638286652770097527670697770364392602243728418408832518487
    70472638440379530166905465937461619323840363893131364327137688841026811219891275
    22305625675625470172508634976536728860596675274086862740791285657699631378975303
    46606166698042182677245605306607738996242183408598820718646826232150802882863597
    46839654358856685503773131296587975810501214916207656769950659715344763470320853
    21560367482860837865680307306265763346977429563464371670939719306087696349532884
    68336130388294310408002968738691170666661468000151211434422560238744743252507693
    87077775193299942137277211258843608715834835626961661980572526612206797540621062
    08064988291845439530152998209250300549825704339055357016865312052649561485724925
    73862069174036952135337325316663454665885972866594511364413703313936721185695539
    52108458407244323835586063106806964924851232632699514603596037297253198368423363
    90463213671011619282171115028280160448805880238203198149309636959673583274202498
    82456849412738605664913525267060462344505492275811517093149218795927180019409688
    66986837037302200475314338181092708030017205935530520700706072233999463990571311
    58709963577735902719628506114651483752620956534671329002599439766311454590268589
    89791158370934193704411551219201171648805669459381311838437656206278463104903462
    93950029458341164824114969758326011800731699437393506966295712410273239138741754
    92307186245454322203955273529524024590380574450289224688628533654221381572213116
    32881120521464898051800920247193917105553901139433166815158288436876069611025051
    71007392762385553386272553538830960671644662370922646809671254061869502143176211
    66814009759528149390722260111268115310838731761732323526360583817315103459573653
    82235349929358228368510078108846343499835184044517042701893819942434100905753762
    57767571118090088164183319201962623416288166521374717325477727783488774366518828
    75215668571950637193656539038944936642176400312152787022236646363575550356557694
    88865495002708539236171055021311474137441061344455441921013361729962856948991933
    69184729478580729156088510396781959429833186480756083679551496636448965592948187
    85178403877332624705194505041984774201418394773120281588684570729054405751060128
    52580565947030468363445926525521370080687520095934536073162261187281739280746230
    94685367823106097921599360019946237993434210687813497346959246469752506246958616
    90917857397659519939299399556754271465491045686070209901260681870498417807917392
    40719459963230602547079017745275131868099822847308607665368668555164677029113368
    27563107223346726113705490795365834538637196235856312618387156774118738527722922
    59474337378569553845624680101390572787101651296663676445187246565373040244368414
    08144887329578473484900030194778880204603246608428753518483649591950828883232065
    22128104190448047247949291342284951970022601310430062410717971502793433263407995
    96053144605323048852897291765987601666781193793237245385720960758227717848336161
    35826128962261181294559274627671377944875867536575448614076119311259585126557597
    34573015333642630767985443385761715333462325270572005303988289499034259566232975
    78248873502925916682589445689465599265845476269452878051650172067478541788798227
    68065366506419109734345288783386217261562695826544782056729877564263253215942944
    18039943217000090542650763095588465895171709147607437136893319469090981904501290
    30709956622662030318264936573369841955577696378762491885286568660760056602560544
    57113372868402055744160308370523122425872234388541231794813885500756893811249353
    86318635287083799845692619981794523364087429591180747453419551420351726184200845
    50917084568236820089773945584267921427347756087964427920270831215015640634134161
    71664480698154837644915739001212170415478725919989438253649505147713793991472052
    19529079396137621107238494290616357604596231253506068537651423115349665683715116
    60422079639446662116325515772907097847315627827759878813649195125748332879377157
    14590910648416426783099497236744201758622694021594079244805412553604313179926967
    39157542419296607312393763542139230617876753958711436104089409966089471418340698
    36299367536262154524729846421375289107988438130609555262272083751862983706678722
    44301957937937860721072542772890717328548743743557819665117166183308811291202452
    04048682200072344035025448202834254187884653602591506445271657700044521097735585
    89762265548494162171498953238342160011406295071849042778925855274303522139683567
    90180764060421383073087744601708426882722611771808426643336517800021719034492342
    64266292261456004337383868335555343453004264818473989215627086095650629340405264
    94324426144566592129122564889356965500915430642613425266847259491431423939884543
    24863274618428466559853323122104662598901417121034460842716166190012571958707932
    17569698544013397622096749454185407118446433946990162698351607848924514058940946
    39526780735457970030705116368251948770118976400282764841416058720618418529718915
    40196882532893091496653457535714273184820163846448324990378860690080727093276731
    27581966563941148961716832980455139729506687604740915420428429993541025829113502
    24169076943166857424252250902693903481485645130306992519959043638402842926741257
    34224477655841778861717372654620854982944989467873509295816526320722589923687684
    57017823038096567883112289305809140572610865884845873101658151167533327674887014
    82916741970151255978257270740643180860142814902414678047232759768426963393577354
    29301867394397163886117642090040686633988568416810038723892144831760701166845038
    87212364367043314091155733280182977988736590916659612402021778558854876176161989
    37079438005666336488436508914480557103976521469602766258359905198704230017946552
    053
    The ten digital primes in e:
    100 7427466391.0
    124 7413596629.0
    150 6059563073.0
    172 3490763233.0
    183 2988075319.0
    202 1573834187.0
    215 7021540891.0
    219 5408914993.0
    255 6480016847.0
    296 9920695517.0
    310 1838606261.0
    314 6062613313.0
    323 3845830007.0
    400 1692836819.0
    439 4425056953.0
    441 2505695369.0
    474 5490598793.0
    506 1782154249.0
    508 8215424999.0
    517 9229576351.0
    537 9519366803.0
    538 5193668033.0
    548 1825288693.0
    578 8294887933.0
    600 1730123819.0
    618 4039701983.0
    646 4804295311.0
    668 8194558153.0
    670 9455815301.0
    688 1332069811.0
    703 6181881593.0
    706 1881593041.0
    710 5930416903.0
    729 1934580727.0
    744 3858942287.0
    782 4841984443.0
    820 1978623209.0
    857 3140934317.0
    871 3640546253.0
    893 8887070167.0
    902 7683964243.0
    922 4563549061.0
    1016 3343210681.0
    1017 3432106817.0
    1036 7880235193.0
    1065 3041995777.0
    1123 4716256079.0
    1147 5124665201.0
    1209 5695638023.0
    1217 2363701621.0
    1314 4833799801.0
    1330 2278509257.0
    1351 2648326277.0
    1374 2772516401.0
    1421 6318641551.0
    1474 7546396447.0
    1520 8958586717.0
    1522 5858671747.0
    1541 7573205681.0
    1590 8816674001.0
    1608 8040336379.0
    1617 9537645203.0
    1640 5278369511.0
    1684 6234281899.0
    1697 7332761717.0
    1711 8034946501.0
    1734 4258639877.0
    1739 3987727547.0
    1742 7727547109.0
    1829 2549296669.0
    1832 9296669381.0
    1836 6693811513.0
    1872 2481765851.0
    1888 3644281231.0
    1898 4965507047.0
    1900 6550704751.0
    1932 8668508003.0
    1943 8532281831.0
    1947 2818315219.0
    1960 3735625279.0
    1963 5625279449.0
    1979 4188294787.0
    1996 3981395599.0
    2028 8462457803.0
    2060 2626039033.0
    2062 2603903381.0
    2149 3946507063.0
    2166 5466185509.0
    2171 8550966661.0
    2177 6661856647.0
    2181 8566470971.0
    2183 6647097113.0
    2205 6262156807.0
    2207 6215680717.0
    2250 5968620023.0
    2264 8588748569.0
    2276 2200050311.0
    2277 2000503117.0
    2290 9207321139.0
    2303 3293634479.0
    2322 2773490717.0
    2325 3490717837.0
    2326 4907178379.0
    2360 5440001863.0
    2373 9149070547.0
    2402 9669062951.0
    2428 5236812859.0
    2457 9833053537.0
    2460 3053537087.0
    2463 3537087613.0
    2465 3708761389.0
    2466 7087613893.0
    2494 7223618789.0
    2495 2236187893.0
    2622 3370924003.0
    2690 5442545993.0
    2691 4425459937.0
    2698 9376917041.0
    2771 2231519747.0
    2787 6967253801.0
    2836 4421152969.0
    2853 8740196609.0
    2906 9639908549.0
    2929 6081930221.0
    2946 3300964127.0
    2950 9641270489.0
    2953 1270489439.0
    2958 8943903971.0
    2960 4390397177.0
    2962 9039717719.0
    2973 1806990869.0
    2974 8069908699.0
    3003 3765022601.0
    3163 8816359831.0
    3185 1174110913.0
    3206 6629077943.0
    3215 3646005851.0
    3264 5182756879.0
    3308 5838182323.0
    3316 2336861201.0
    3343 8585330527.0
    3350 5275833337.0
    3356 3337939907.0
    3382 9887956513.0
    3429 6481719467.0
    3432 1719467083.0
    3456 7906765037.0
    3525 4410237443.0
    3537 7093554779.0
    3562 3645142861.0
    3572 7158587339.0
    3597 9561873857.0
    3632 5611492391.0
    3638 2391518893.0
    3640 9151889309.0
    3644 8893099463.0
    3650 9463428413.0
    3657 4139360803.0
    3659 3936080383.0
    3670 9166281881.0
    3676 1881150371.0
    3681 5037152849.0
    3712 6807515017.0
    3713 8075150177.0
    3737 3470879089.0
    3742 7908913729.0
    3762 5159156837.0
    3814 6192428531.0
    3821 5317018781.0
    3833 2960235413.0
    3911 3316087783.0
    3936 4229755993.0
    3937 2297559931.0
    3970 5383300469.0
    4035 7407187499.0
    4058 4414737823.0
    4063 3782330327.0
    4066 2330327033.0
    4095 2857349359.0
    4104 9475643341.0
    4150 8487872167.0
    4162 6701061509.0
    4185 8733128101.0
    4187 3312810107.0
    4203 2237378861.0
    4230 3961278887.0
    4236 8887325273.0
    4242 5273738903.0
    4272 7960259303.0
    4323 7460210053.0
    4343 3850047827.0
    4395 5143081751.0
    4401 1751126989.0
    4440 8324229241.0
    4501 6382866527.0
    4530 4392602243.0
    4576 6690546593.0
    4607 1364327137.0
    4618 8884102681.0
    4703 6996313789.0
    4704 9963137897.0
    4706 6313789753.0
    4708 1378975303.0
    4714 5303466061.0
    4718 4660616669.0
    4723 1666980421.0
    4740 5605306607.0
    4752 8996242183.0
    4757 4218340859.0
    4797 7468396543.0
    4859 9715344763.0
    4868 3470320853.0
    4876 5321560367.0
    4936 9719306087.0
    4961 3613038829.0
    4975 4080029687.0
    4989 1170666661.0
    4998 1468000151.0
    5017 5602387447.0
    5034 7693870777.0
    5039 7077775193.0
    5105 6797540621.0
    5119 8064988291.0
    5125 8291845439.0
    5132 4395301529.0
    5153 5498257043.0
    5176 5312052649.0
    5183 6495614857.0
    5201 6206917403.0
    5246 9451136441.0
    5247 4511364413.0
    5318 1232632699.0
    5329 1460359603.0
    5349 3684233639.0
    5370 1161928217.0
    5399 8802382031.0
    5409 9814930963.0
    5440 4568494127.0
    5480 9227581151.0
    5494 1492187959.0
    5518 6698683703.0
    5527 3730220047.0
    5641 6534671329.0
    5654 5994397663.0
    5656 9439766311.0
    5685 8370934193.0
    5721 9459381311.0
    5735 3765620627.0
    5751 4903462939.0
    5772 1648241149.0
    5812 6629571241.0
    5815 9571241027.0
    5820 4102732391.0
    5889 2468862853.0
    5890 4688628533.0
    5959 9011394331.0
    6025 3883096067.0
    6034 7164466237.0
    6046 2264680967.0
    6086 7595281493.0
    6105 1126811531.0
    6148 3459573653.0
    6156 5382235349.0
    6204 4517042701.0
    6207 7042701893.0
    6209 4270189381.0
    6215 9381994243.0
    6238 5776757111.0
    6254 8164183319.0
    6258 1833192019.0
    6298 2778348877.0
    6312 5188287521.0
    6319 5215668571.0
    6320 2156685719.0
    6366 5278702223.0
    6418 1710550213.0
    6442 3444554419.0
    6509 1959429833.0
    6552 9481878517.0
    6586 1984774201.0
    6595 1418394773.0
    6661 9265255213.0
    6725 7823106097.0
    6748 4623799343.0
    6762 6878134973.0
    6798 9091785739.0
    6841 5686070209.0
    6873 1739240719.0
    6899 7901774527.0
    6938 6855516467.0
    6942 5164677029.0
    6969 3467261137.0
    6975 1137054907.0
    7022 4118738527.0
    7036 2259474337.0
    7045 7378569553.0
    7058 6246801013.0
    7062 8010139057.0
    7174 4836495919.0
    7184 5082888323.0
    7197 5221281041.0
    7221 2913422849.0
    7259 1502793433.0
    7282 3144605323.0
    7325 2372453857.0
    7363 1289622611.0
    7429 1265575973.0
    7465 8576171533.0
    7485 5720053039.0
    7515 9757824887.0
    7531 5916682589.0
    7583 4785417887.0
    7594 8227680653.0
    7650 2056729877.0
    7708 8846589517.0
    7722 1476074371.0
    7788 6984195557.0
    7793 9555776963.0
    7922 8635287083.0
    7970 7453419551.0
    8030 9214273477.0
    8066 6406341341.0
    8094 7644915739.0
    8110 1704154787.0
    8139 5147713793.0
    8141 4771379399.0
    8150 9147205219.0
    8168 6137621107.0
    8298 9512574833.0
    8302 5748332879.0
    8306 3328793771.0
    8308 2879377157.0
    8355 8622694021.0
    8382 3604313179.0
    8390 7992696739.0
    8399 9157542419.0
    8425 4213923061.0
    8506 1375289107.0
    8540 7518629837.0
    8556 2244301957.0
    8605 5578196651.0
    8606 5781966511.0
    8659 2544820283.0
    8664 2028342541.0
    8687 1506445271.0
    8726 5484941621.0
    8730 9416217149.0
    8755 1406295071.0
    8765 8490427789.0
    8794 3567901807.0
    8817 3087744601.0
    8831 2688272261.0
    8834 8272261177.0
    8875 3426426629.0
    8903 8335555343.0
    8949 3404052649.0
    9013 6847259491.0
    9033 8454324863.0
    9051 8466559853.0
    9054 6559853323.0
    9092 4271616619.0
    9095 1616619001.0
    9099 6190012571.0
    9107 7195870793.0
    9121 6969854401.0
    9156 4464339469.0
    9183 9245140589.0
    9212 9700307051.0
    9231 4877011897.0
    9298 6534575357.0
    9302 5753571427.0
    9322 8464483249.0
    9323 4644832499.0
    9350 9327673127.0
    9360 5819665639.0
    9362 1966563941.0
    9375 9617168329.0
    9473 4814856451.0
    9528 5841778861.0
    9533 7886171737.0
    9656 8151167533.0
    9665 3327674887.0
    9686 9701512559.0
    9700 7270740643.0
    9701 2707406431.0
    9760 3018673943.0
    9769 3971638861.0
    9814 8921448317.0
    9819 4831760701.0
    9832 8450388721.0
    9842 2364367043.0
    9847 6704331409.0
    9878 6590916659.0
    9889 1240202177.0
    9924 3800566633.0
    9935 4884365089.0
    9955 3976521469.0
    9981 9870423001.0

  • 2007-07-12-三个圆柱体相交部分的体积

    三个圆柱体相交部分的体积 2007-07-12 22:30:50
    分类:
    下午和一个兄弟一起做了这个题目。

    就是求三个轴心分别沿正交XYZ轴的半径为一的圆柱体相交部分的体积。

    下面是用Matlab编程的源程序和结果:

    clear();
    for i=1:10
        N=1000000;
        n=0;
        x=0;y=0;z=0;
        for j=1:N
            x=rand;
            y=rand;
            z=rand;
            if x*x+y*y<=1
                if y*y+z*z<=1
                    if x*x+z*z<=1
                        n=n+1;
                    end
                end
            end
        end
        v(i)=8*n/N;
    end
    v
    mean(v)

    结果:

    v =
      Columns 1 through 7
        4.6910    4.6828    4.6829    4.6895    4.6921    4.6810    4.6913
      Columns 8 through 10
        4.6886    4.6881    4.6866

    ans =
    4.6874

    基本思想就是在第一象限0<=x<=1,0<=y<=1,0<=z<=1的一个正方体里面投点,然后判断所投的点是不是在三个圆柱所围个的体积里面,如果在,则计数器n数值加1。总共投N个点。这样根据大数定理,点落在所求体积内的概率为第一象限内所求体积与正方体体积之比。n/N=V1/1*1*1.
    所求的体积为第一象限体积V1的8倍。所以V=8*n/N.(N=1000000)
    所得结果为4.6874.

    现在我们来求该部分的精确结果:

    求该体积的积分比较麻烦:
    我们可以看到所求体积在8个象限里面是对称的,所以先求出在第一象限里面的体积。
    联立x^2+y^2=1,y^2+z^2=1,x^2+z^2=1三个圆柱方程,我们可以得到三个圆柱的交点为
    (sqrt(2)/2,sqrt(2)/2,sqrt(2)/2).再分析第一象限里面体积,我们可以知道该部分的体积又可以分成三部分。每一部分为交点与xyz坐标轴上单位1的点所夹的部分。该部分又可分为对称的两部分。
    第一部分为0<=y<=sqrt(2)/2,0<=z<=y,y<=x<=sqrt(1-y^2)围成的体积。
    该部分体积可以积分:
    Integrate[y*(Sqrt[1 – y^2] – y), {y, 0, Sqrt[2]/2}]
    所以所求体积为:
    Integrate[y*(Sqrt[1 – y^2] – y), {y, 0, Sqrt[2]/2}]*6*8=8(2-sqrt(2))=4.68629.

    以上为在Mathmatics里面用积分求出来的所求体积的精确结果。