C编程方法学的内附英文_武汉理工大学出版

C编程方法学的内附英文

The text of C Programming Methodology

TIOBE is specialized in assessing and tracking the quality of software.
The C programming language is a popular and widely used programming language for creating computer programs.
Programmers around the world embrace C because it gives maximum control and efficiency to the programmer.
If you are a programmer, or if you are interested in becoming a programmer, there are a couple of benefits you gain from learning C.
It's ubiquitous, closer to the hard-ware, and used to create other languages and operating systems.
System programming (in pure C) or specialized areas when working with languages that are extensions of or closely related.
Knowing C gets you closer to the hardware, to better understand how things work on the system level.
It's an important, foundational language that requires you to understand the full stack of the technology.
Language abstraction pyramid
Human language
5th Generation: ???
4th Generation: OOP Languages, C++, Java
3th Generation: Structured Languages, C, Fortran
2nd Generation: Assembly Language
1st Generation: Machine Language, 010101011
The strategy of learning C is step-by-step approach, first laying a sound foundation on programming concepts, control statements, and functions.
The fundamental of C programming is a stepping stone that will prepare you to embark on the journey of learning other programming language.
A program is a set of instructions for a machine to accomplish a specific task or solve a specific problem.
Program is an algorithm written in a language a computer can execute.
Computers do not understand the intention of a program.
Computers do what you tell them, not what you meant to tell them.
Programs must be precise.
Programs must be detailed.
Programs must be debugged...
Steps in Creation of a Program:
* Define the problem.
* Find an algorithm to solve the proble.
* Express the an algorithm in a computer language and store in one or more files.
* Compile the files to create a program. (Most languages)
* Run the program.
* Test and Correct the program.
Structured programming is a programming paradigm aimed on improving the clarity, quality, and development time of a computer program by making extensive use of subroutines, block structures and for and while loops.
At a low level, structured programs are often composed of simple, hierarchical program flow structures.
These are sequence, selection, and repetition.
"Sequence" refers to an ordered execution of statements.
In "selection" one of a number of statements is executed depending on the state of the program.
In "repetition" a statement is executed until the program reaches a certain state, or operatons have been applied to every element of a collection.
An algorithm is a step by step process used to carry out some function.
Algorithms are often expressed in pseudo-code.
There are no real standards for expressing algorithm in pseudo-code.
The preprocessor will find a file with the name "stdio.h" and the contens of that file will be included as part of the program.
Preprocessor directives begin with # symbol as the first non-blank character on the line.
In this program, the directive defines the "printf()" function.
"printf()" function instructs the computer to print the string of messages marked by the quotation marks on the screen.
Preprocessing occurs before a program is compiled.
Its actions are the inclusion of other files, definition of symbolic constants and macros, conditional compilation of program code and conditional execution of preprocessor directives.
Whenever the preprocessor sees the symbolic constant it substitutes the replacement string.
This happens to the program before the actual compiler sees it.
The "#define" is a preprocessor directive.
The first term is an identifier (a symbolic constant) being defined to the preprocessor, the second term is a replacement string.
Macro substitution: "#define", which is the most common usage, it can define symbolic constants, function, rename string stitching and other Functions.
Keywords are words (like identifiers) that have a special meaning to the compiler and cannot be used in your programs for other purposes.
Only the exact spelling of keywords is reserved.
For example, "auto" is reserved but "AUTO" is not.
Usually, identifier names are case sensitive, so "Big" and "big" are two different identifiers.
Good programming style is to choose meaningful names.
"main" is a special identifier.
It names the function which will be given control when a program is invoked.
The "printf()" function prints information on the screen.
Arguments are passed to functions within parenthesis.
The symbol "%d" is called a conversion specification or format.
"3, 4, 5" are other parameters to the "printf()" function.
The control string has formats that tell "printf()" about subsequent paremeters.
In this case, "%d" tells "printf()" that the next argument is an integer and should be displayed as an integer.
"scanf()" is a function that reads input from the keyboard.
It takes multiple arguments, the first is a control string, the rest are identifiers that should receive the keyborad input.
Note the "&" must precede the variable name.
It is a common but deadly mistake to forget it.
This is a tough one to spot and difficult to debug, so be careful.
The "scanf()" function needs its format to match the type of argument.
The conversion characters are "%c", "%d", "%f", "%lf" and "%s" and they match char, decimal integer, float, double, and string.
The "printf()" function call returns the number of characters printed.
"printf()" doesn't return the number of "items" output like the "scanf()" family of functions do for input.
It returns the actual character count.
The "scanf()" function call returns the number of arguments it read from the input.
In this case, if a value was read into the identifier x, "scanf()" will return 1.
/* comment This is not part of executable program. */
/*
   This is one of many ways to write comments.
   If you wish, you can put comments here.
*/
A comment is ignored by the compiler and serves to document the program for a human reader.
In C, comments begin with the pair of symbols "/*" and end with the pair "*/" or    
 (since C99) following "//" until the end of the line, and can be anywhere in your program.
Comments can span several line within your C program..
/*
   This is a very simple  C program.
   Run it, you will see the result.
*/
//   This is a very simple  C program.
//   Run it, you will see the result.
Programs can be highly readable and understandable or they can be intelligible.
It is best just now if you simply adopt the styles presented by tutor, when you are a seasoned programmer, you can develop your own style.
(1) Meaningful names.
(2) White space to separate parts of statements.
(3) Consistent habits regarding indentation.
Indentation conveys controlling statements in control flow.
Some Commom Coding Errors
* Quoting problems. (unmatched quotes, mismatched quotes, incorrect quotes)
* Unending comments.
* Forgetting semicolons.
* Unmatched or mismatched braces or parenthese.
* Control strings not matching the arguments in "printf()", "scanf()", and other similar functions.
* Forgetting "&" in arguments to "scanf()".
* Loss of fractions due to use of int instead of float.
* Inconsistent lengths (e.g. double vs. float) between formats and arguments in "scanf()" and "printf()".
Syntax Error
Runtime Error
Logic Error
Unchecked Error
Well began, half done.
Programming Exercises at the end of each chapter provide you with opportunities to apply the skills on your own.
The trick of learning programming is
* practice,
* practice,
* and practice.
9. Write a single C statement for each of the following:
    a. Print the value of the double variable y with two digits after the decimal point.
    b. Print a six-digit integer that contains the remainder when integer x is divided by integer y.
    c. Read an integer and a floating-point number from the keyboard into the integer j and the double z, respectively.
    d. Set identifier a to itself minus the value of identifier b, and subtract one from the current value of b. (Remember to use one statement.)
In the C programming language, data types refers to an extensive system for declaring variables of different types.
The language itself provides basic arithmetic types and syntax to build array and compound types.
Basic data types are also known as "fundamental" or "built-in" to the language.
These include integers, floating-point numbers, and characters.
Derived types, also known as "compound" types, are created from the set of basic types, and include arrays, structures, unions, and enumerations.
The C language provides many basic types.
Most of them are formed one of the four basic arithmetic type identifiers in C (char, int, float and double), and optional specifiers (signed, unsigned, short, long).
The value of a constant is given at COMPILE time, and (of course) cannot be changed.
Integer constants, floating point constants, character string constants and enumeration constants are all constants.
In computer programming, a constant is an identifier whose associated value cannot typically be altered by the program during its execution.
Many programming languages make an explicit syntactic distinction between constant and variable symbols.
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.
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 in exponential form.
While representing using decimal form, you must include the decimal point, the exponent, or both and while representing using exponential form, you must include the integer part, the fractional part, or both.
The signed exponent is introduced by e or E.
Character literals are enclosed in single quotes and 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').
Escape Sequences, a combination of two characters that produces a special effect within a text string.
The 1st character is always a backslash '\'.
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.
A "#define" line defines a symbolic name or symbolic constant to be a particular string of characters:
#define name replacementList
Thereafter, any occurrence of name (not in quotes and not part of another name) will be replaced by the corresponding replacement text.
The name has the same form as a variable name: a of characters; it is not limited to numbers.
A variable is nothing but a name given to a storage area that our programs can manipulate.
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.
The name of a variable can be composed of letters, digits, and the underscore character.
It must begin with either a letter or an underscore.
Upper and lowercase letters are distinct because C is case-sensitive.
All variables must be declared before use.
A declaration specifies a type, and contains a list of one or more variables of that type.
A variable may also be initialized in its declaration.
If the name is followed by an equals sign and an expression, the expression serves as an initializer.
A pointer is a variable whose value is the address of another variable, ie. direct address of the memory location.
Like any variable or constant, you must declare a pointer before you can use it to store any variable address.
'&' (address operator) is a unary operator that returns the address of its operand.
The '&' operator only applies to objects in memory: variables and array elements.
It cannot be applied to expressions, constants, or register variables.
The unary operator '*' is the indirection or dereferencing operator; when applied to a pointer, it accesses the object the pointer points to.
C provides two unusual operators for incrementing and decrementing variables.
The increment operator "++" adds 1 to its operand, while the decrement operator "--" subtracts 1.
The expressions "++i" (prefix increment) and "i++" (postfix increment) both cause the variable i to be incremented.
However, the expressions have different values.
When you write "++i", the increment occurs before the expression is evaluated.
When your write "i++", i is incremented after the expression is evaluated.
If you are writing a statement to increment i, the prefix operator is preferred.
The comma operator is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value (and type).
The use of the comma operator is distinct from its use in function calls and definitions, variable declarations, enum declarations, and similar constructs, where it acts as a separator.
We can overrule the conversion rule by using casts.
These are explicit conversions.
To cast an expression you precede the expression with the parenthesized type you wish the expression to have.
Note, the thing being cast does not have its type changed.
The cast is a unary operator, like negation, and it has the same precedence.
To tell us how large an object is in C, the language provides the sizeof operator.
Note this is a unary operator like minus, and has the same precedence.
In the integrated enviroment of VC++ 6.0, compiling a program should use the combination key ___, running a program should use the key ___.
C language is composed by ___, the source program includes at least ___ function.
In C, the first character of variable name must be ___ or ___.
Among VC++ 6.0, the scope of int variable's value is between ___ to ___.
How many bytes are required on int float type ___ and char data type ___.
Among VC++ 6.0, how many bytes are required on variable b for statement ___ unsigned long b.
In combination operation of float, char and int data type, the type of final result is ___.
The value is ___ for expressing "3 * 5", "3 / 5" and is ___ for expressing "x = 2 % 9".
For x = 4, y = 3, the value of "(x>y)?x:y" is ___.
Without flow of control statements, programs would always start at the main function, and perform each executable statement exactly once in order from top to bottom.
Suppose you wanted to accept 10 integers from the user, add them and print the result.
Without flow of control you might have a very simple program with a lot of variables.
The flow of control through a program is modified by control flow statements: if, if-else, while, for, do-while, break, continue, switch.
Some of these statements evaluate an expression for truth (non-zero) value.
Control flow is dependent on the value of the expression.
These statements are if, if-else, while, for, and do-while.
The other statements (break, continue, etc.) modify the control unconditionally.
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.
The braces that surround the statement of a function are one obvious example; braces around multiple statements after an if, else, while, or for are another. 
(Variable can be declared inside any block; we will talk about this later in this chapter.)
There is no semicolon after the right brace that ends a block.
There are a number of statements (if, if-else, while, for, and do-while) that evaluate an expression and modify the control dependent on the value of the expression.
These expression use the returned values of functions, identifiers, the operators we have already seen (arithmetic, assignment), as well as relational and logical operators.
Relational operators take expressions as operands and evaluate to type int.
They will always evaluate to either 1 (true), or 0 (false).
The logical operator '!' is called the negation operator.
It is an unary operator because it has one operand.
Don't confuse negation with unary minus.
'!!a' is not the same as 'a', e.g. "!!5 == 1".
The binary logical operators "&&" and "||" act on pairs of expressions and has value of type int with a value of 0 or 1.
An expression containing "&&" or "||" is evaluated according to the rules of precedence and associativity.
The evaluation stops as soon as the value is known.
So if the operands contain expressions with side-effects, they may or may not be performed.
Rule of thumb: try to aviod side effects when writing operands of these operators.
The conditional operator is also known as ternary operator.
It is called ternary operator because it takes three arguments.
The conditional operator evaluates an expression returning a value if that expression is true and different one if the expression is evaluated as false.
Single selection statement----a single-entry and single-exit structure:
Either performs an action when the condition is true OR skip/ignore the action when the condition is false.
Compound Statements are needed when more than one statements are in the body of an if, which require a pair of brace { } to enclose the set of statements.
Double selection statement: It selects between two different actions.
Multiple selection statement takes an action when evaluating each selection statement in sequence until the condition is first met.
We use each else-if to select one from among the alternatives.
When any of the else-if conditions is satisfied, all the remaining else-if's are skipped.
The last else, the one without if is the default case.
First expression is evaluated, control then passes to the case label having matching constant value, otherwise, control passes to the default label.
You usually want to use break statements inside switches.
Remember: more all statements following the matching case label will be executed.
The defualt statement need not be the last in the switch.
The break statement causes an immediate exit from the switch.
Because cases serve just as labels, after the code for one case is done, execution falls through to the next unless you take explicit action to escape.
"break" and "return" are the most common ways to leave a switch.
A break statement can also be used to force an immediate exit from while, for, and do loops, as will be discussed later in this chapter.
A repetition statement allows you to specify that an action is to be repeated while some condition remains true.
The expression is evaluated.
If it is non-zero, statement is executed and the expression is reevaluated.
This cycle continues until the expression finally becomes zero, at which point the loop is terminated.
Execution of the program then continues with the statement that follows the program statement.
The while looping statements discussed make a test of the conditions before the loop is excuted.
Therefore, the body of the loop might never be executed at all if the conditions are not satisfied.
The while loops test the termination condition at the top.
By contrast, the 2nd loop, the do-while, tests at the bottom after making each pass through the loop body.
The body is always executed at least once.
The body statement is executed, then conditional expression is evaluated.
If it is true, body statement is evaluated again, and so on.
When the conditional expression becomes false, the loop terminates.
The do statement is simply a transposition of the while statement, with the looping conditions placed at the end of the loop rather than at the beginning.
* It's important that the program does not proceed until the user types in a valid option.
* The general way is to check the user's input and keep asking until a valid value is typed in.
* A do loop is needed because you want it to execute at least once (you want it to ask the user for a response at least once).
Golden Section
If we take the ratio of two successive numbers in Fibonacci's series, (1, 1, 2, 3, 5, 8, 13, ...) and we divide each by the number before it, we will find the following series of numbers:
...
It is easier to see what is happening.
The ratio "fib(i-1)/fib(i)" seems to be settling down to a particular value, which we call the golden ratio or the golden number.
It has a value of approximately 0.618034.
The three expressions that are enclosed within the parenthese (initialization_expression, loop_condition, and loop_expression) set up the environment for the program loop.
The statement that immediately follows (which is, of course, terminated by a semicolon) can be any valid C program statement and constitutes the body of the loop.
The first expression of the for statement, labeled initialization_expression, is used to set the initial values before the loop begins.
As you can see, an assignment is a valid form of an expression.
The second  expression of the for statement the condition that are necessary for the loop to continue.
In other words, looping continues as long as this condition is satisfied.
The final expression of the for statement contains an expression that is evaluated each time after the body of the loop is executed.
In summary, execution of the for statement proceeds as follows:
(1) The initial expression is evaluated first.
This expression usually sets a variable that will be used inside the loop, generally referred to as an index variable, to some initial value such as 0 or 1.
(2) The looping condition is evaluated.
If the condition is not satisfied (the expression is FALSE), the loop is immediately terminated.
Execution continues with the program statement that immediately follows the loop.
(3) The program statement that constitutes the body of the loop is executed.
(4) The looping expression is evaluated.
This expression is generally used to change the value of the index variable, frequently by adding 1 to it or subtracting 1 from it.
(5) Return to step (2).
The original problem that Fibonacci investigated (in the year 1202) was about how fast rabits could breed in ideal circumstances.
The number of pairs of rabbits at the start if each month is 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
Sometimes when executing a loop, it becomes desirable to leave the loop as soon as a certain condition occurs (for instance, you detect an error condition, or you reach the end of your data prematurely).
The break statement can be used for this purpose.
Execution of the break statement causes the program to immediately exit from the loop it is executing, whether it's a for, while, or do loop.
Subsequent statements in the loop are skipped, and execution of the loop is terminated.
Execution continues with whatever statement follows the loop.
If a break is executed from with in a set of nested loops, only the innermost loop in which the break is executed is terminated.
The continue statement is similar to the break statement except it doesn't cause the loop to terminate.
Rather, as its name implies, this statemernt causes the loop in which it is executed to be continued.
At the point that the continue statement is executed, any statements in the loop that appear after the continue statement are automatically skipped.
Execution of the loop otherwise continues as normal.
The continue statement is most often used to bypass a group of statement inside a loop based upon some condition, but to otherwise continue execution of the loop.
In while and do-while statements, the loop-continuation test is evaluated immediately after the continue statement is executed.
In the for statement, the increment expression is executed, then the loop-continuation test is evaluated.
Earlier, we said that the while statement could be used in most cases to represent the for statement.
The one exception occurs when the increment expression in the while statement follows the continue statement.
In this case, the increment is not executed before the repetition-continuation condition is tested, and the while does not execute in the same manner as the for.
C allows to use one loop inside another loop, it's called nested loop.
A note on loop nesting is that you can put any type of loop inside of any other type of loop.
For example a for loop can be inside a while loop or vice versa.
Note that, with a nested loop, the inner loop runs through its full range of iterations for each single iteration of the outer loop.
A break in a nested loop just takes the program out of the inner loop; to get out of the outer loop requires a second break.
A common use for nested loops is to display data in rows and columns.
One loop can handle, say, all the columns in a row, and the second loop handles the rows.
In the preceding example, the inner loop did the same thing for each cycle of the outer loop.
You can make the inner loop behave differently each cycle by making part of the inner loop depend on the outer loop.
For example, alters the last program slightly by making the ending values of the inner loop depend on the cycle number of the outer loop.
Random numbers are sometimes used in generating test data for programs.
Many programs are programs that use random number functions to generate probabilities.
In C, you can obtain apparently random numbers by invoking the function "rand()".
This function returns pseudo random numbers in the system dependent interval.
The loop is a powerful programming tool.
 You should pay particular attention to three aspects when setting up a loop:
* Clearly defining the condition that causes the loop to terminate;
* Making sure the values used in the loop test are initialized before the first use;
* Making sure the loop does something to updata the test each cycle.
Computers represent all data internally as sequences of bits.
Each bit can assume the value 0 or the value 1.
On most systems, a sequence of 8 bits forms a byte (the standard storage unit for a variable of typechar).
Other data types are stored in larger numbers of bytes.
The bitwise operators are used to manipulate the bits of integral operands (char, short, int and long; both signed and unsigned).
Unsigned integers are normally used with the bitwise operators.
C provides six operators for bit manipulation; these may only be applied to integral operands, that is, char, short, int, and long, whether signed or unsigned.
Unary (one's complement), all 0 bits are set to 1 and all 1 bits are set to 0.
Bitwise "AND", the bits in the result are set to 1 if the corresponding bits in the two operands are both 1.
Bitwise "inclusive OR", the bits in the result are set to 1 if at least one of the corresponding bits in the two operands is 1.
Just as it's useful to be able to turn on particular bits without disturbing the other bits, it's useful to be able to turn them off.
Sometimes you might need to turn on particular bits in a value while leaving the remaining bits unchanged.
You can turn on the 1 bit while leaving the others unchanged with the bitwise "OR" operator.
Bitwise "exclusive OR", the bits in the result are set to 1 if exactly one of corresponding bits in the two operands is 1.
Toggling a bit means turning it off if it is on, and turning it on if it is off.
You can use the bitwise "exclusive OR" operator to toggle a bit.
The idea is that if b is a bit setting (1 or 0), then 1^b is 0 if b is 1 and is 1 if b is 0.
Also 0^b is b, regardless of its value.
Therefore, if you combine a value with a mask by using ^, values corresponding to 1s in the mask are toggled, and values corresponding to 0s in the mask are unaltered.
Left shift, shifts the bits of its left operand to the left by the number of bits specified in its right operand.
Bits vacated to the right are replaced with 0s; 1s shifed off the left are lost.
Right shift, shifts the bits of its left operand to the right by the number of bits specified in its right operand.
Performing a right shift on an unsigned integer causes the vacated bits at the left to be replaced by 0s; 1s shifted off the right are lost.
Right shifting is machine dependent.
Right shifting a signed integer fills the vacated bits with 0s on some machines and with 1s on others.
Suppose x=0 and y=1 what is x after evaluating the expression "(y>0) && (1>x++)"?
D. None of the above.
Analyze the following code.
A. The code has a syntax error because "&&" must be "||".
B. y becomes 1 after the code is executed.
C. y becomes -1 after the code is executed.
A. The symbol x is always printed.
B. The value of variable x is always printed.
C. Nothing is printed because x > 0 is false.
As int a=3, b=4, c=5;, the value of the expression "a||b + c&&b - c" is ___.
For x=4, y=3;, the value of "x>y?x:y" is ___.
If a=2, b=3, c=-1, d=5; the value of the expression as below is: ___.
When it's not known in advance how many times a set of statements will be repeated, a(n) ___ value can be used to terminate the repetition.
A variable that accumulates the sum of several numbers is a(n) ___.
Find and correct the errors in the following C program.
My teacher's address is #123 Beijing Road, Shanghai.
Write a program that computes the Piecewise-defined Function as below:
Write a program that reads in values for a, b and c and finds the roots of the polynomial ax^2 + bx + c = 0.
Write a program to generate and display a table of n and n^2, for integer values of n ranging from 1 to 10.
Be certain to print appropriate column headings.
An online retailer sells five different products whose retail prices are shown in the following table:
Write a program that reads a series of pairs of numbers as follows:
(a) Product number
(b) Quantity sold for one day
Your program should use a switch statement to help determine the retail price for each product and then calculate and display the total retail value of all products sold last week.
Write a program to compute compound interest using the for statement.
Consider the following problem statement:
A person invests 1000.00 in a savings account yielding 5% interest.
Assuming that all interest is left on deposit in the account, calculate and print the amount of money in the account at the end of each year for 10 years.
Use the following formula for determining these amounts:
a = p(1 + r)^n
where
p is the original amount invested (i.e., the principal)
r is the annual interest rate
n is the number of years
a is the amount on deposit at the end of the nth year.
Write a program that reads in the side of a square and then prints that hollow square.
Your program should work for squares of all side sizes between 1 and 20.
For example, if your program reads a size of 5, it should print:
*****
*   *
*   *
*   *
*****
C programming language provides a data structure called the array, which can store a fixedsize 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 arrary as a collection of variables of the same type.
An array is a data type that uses subscripted variables and makes possible the representation of a large number of homogeneous values.
An array can be thought of as a simple variable with an index, or subscript, added.
The brackets "[]" are used to contain the array subscripts.
A one-dimensional array declaration is a type followed by an identifier with a bracketed constant integral expression.
The value of the expression, which must be positive, is the size of the array.
It specifies the number of elements in the array.
The array subscripts can range from 0 to "size-1".
The lower bound of the array subscripts is 0 and the upper bound is "size-1".
In C, arrays can be initialized.
Every variables at the defined array are taken random number.
Array can be initialized with whole variables or part of variables, can be assigned in later statements also.
In a array, other variables are all of zero (0) since part of variables are assigned.
An array initializer is a set of values written within braces and separated by commas.
An array may be declared without a size provided it is initialized to a series of values.
If you omit the size of the array, an array just big enough to hold the initialization is created.
If an initializer list is shorter than the array, the remaining elements are set to 0.
We use one dimensional arrays, when we have homogeneous data that we wish to treat in a general fashion.
Use a one-dimensional array when only one other identifier is needed to determine which value in the array we are interested in.
Use a two-dimensional array if two other identifier are needed to determine the value of interest.
Real computer memory has only one dimension, i.e. each location is identified with only one component of address.
In C, or any other computer language supporting arrays with dimension sizes greater than one, two-dimensional arrays simulate the effect of using two components of address.
To do this, the array is mapped into consecutive memory with row 0's value first, then row one's values, etc.
You can think of this as a set of one dimensional arrays holding the column values as a single value in the row's values.
There is no limit in the language as to the number of dimensions that an array may be given.
Each dimension requires a size specifier within a pair of brackets.
Example:
"int b[2][3][4];" causes the compiler to reserve space for 2 arrays of 3 arrays of 4 integers in contiguous memory.
Thus 24 contiguous integers are reserved.
There is no limit in the language as to the number of dimensions that an array may be given.
Each dimension requires a size specifier within a pair of brackets.
A storage mapping function is used to translate an array reference into a pointer reference.
The string in C programming language is actually a one-dimensional array of characters which is terminated by a null character '\0'.
Thus a null-terminated string contains the characters that comprise the string followed by a null.
Actually, you do not palce the null character at the end of a string constant.
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, such as "strlen()", "strcat()", "strcmp()", "strlow()" and "strupr()".
Pointers do not have to point to single variables.
They can also point at the cells of an array.
Once we have a pointer pointing into an array, we can start doing pointer arithmetic.
You can add an integer to a pointer.
It increases the location of the pointer exactly as if the pointer were an array and the subscript was increased by the same amount.
You can even subtract pointers to get the change of array subscript.
When you're doing pointer arithmentic, you have to remember how big the array the pointer points into is, so that you don't ever point outside it.
Working with character arrays:
1. Print 'a' ... 'z', 'A' ... 'Z';
2. Initialize lower_letter[], and upper_letter[];
3. Print the contents of arrays.
Working with an array:
1. Declaration an array,
2. Initialize the elements of array to the even integers from 2 to 20,
3. Output all of element of the array, one each line.
forename, surname.
Let A1 and A2 be two arrays, containing N1 and N2 values.
All values in A1 are different, same in A2.
Let A3 be another array, whose dimension is supposed to be greater that N1+N2.
1. Write a program that copies all values in A1 and A2 into A3.
2. Same question but A3 may not contain twice the same value.
Shifts in an array.
Let A be an initialized array of integers and let N be its actual number of elements.
Write the algorithmic instructions that:
1. Insert an integer V after the existing elements.
2. Remove the last element, under the assumption that there is at least one element.
3. Insert an integer V at index k (k is supposed to be valid).
4. Remove the element at index k (k is supposed to be valid).
5. Achieve a simple circular permutation (each element is moved towards its neighbour).
We assume that a boolean variable, ToTheRight, exists and says whether the elements should be shifted right or left.
The heart and soul of C programming is the function.
A function represents a piece of code that is a building block in the problem---solving process.
Functions, called modules, allow programmers to modularize a program.
Functions support structured programming and offer the following advantages:
* Hierarchical flow control;
* Break large tasks into smaller ones;
* Easy to maintain;
* Improve software reusability.
A C program consists of one or more functions, the most important of which is the function "main()" where execution starts.
When a function is called, the code within the body of that function is executed, and when the function has finished executing, control returns to the point at which that function was called.
There are two kinds of parameters, formal parameters and actual parameters.
They are called "parameter" because they define information that is passed to a function.
Formal parameters are parameters as they appear in function declarations.
Actual parameters are parameters as they appear in function calls.
A parameter cannot be both a formal and an actual parameter, but both formal parameters and actual parameters can be either value parameters or variable parameters.
The value in expression is calculated when the return statement is encountered, this value is return to the calling function.
The type of the expression in a return statement must match the type of the function shown in the definition header.
If the function has type void, then expression will be empty.
Function Prototype
A function prototype offers a view of how to use the desired function, passing input arguments, receive a return value with known type.
We have seen call-by-reference when we use the "scanf()" function.
Values supplied by the calling function as parameters cannot be updated by the called function.
When we want a called function to updata an identifier in the calling function, we pass it a pointer to the identifier.
Call-by-value is still in effect, the called function cannot update the calling function's pointer, but it can dereference the pointer to refer to the memory location of the calling function's identifier.
It can update the value at that memory location, in effect implementing call-by-reference.
The effect of call-by-reference is accomplished by:
a. Declaring a function parameter to be a pointer.
b. Using the dereferenced pointer in the function body.
c. Passing an address as an argument when the function is called.
A recursion call can result in many more recursive calls because the problem is dividing a sub-problem into sub-problems.
For a recursive calling to terminate, the problem must eventually be reduced to a stopping case.
When the problem reaches a stopping case, the function returns a result to its caller.
The caller then performs a computation and returns a result to its own caller.
The original problem can now be solved.
The extent within the program code where a given variable is visible and can be referenced is called the variable's scope.
Local variables scope is confined within the block or function where it is defined.
When execution of the block starts the variable is available, and when the block ends the variable "dies".
A block is a compound statement having declarations.
For example, a function body is a block.
Global variable is defined at the top of the program file and it can be visible and modified by any function that may reference it.
Global variables are initialized automatically by the system default value.
Every variable and function in C has two attributes: type and storage class.
The four storage classes are: auto, extern, register, static.
By far the most common storage class for variables is automatic.
However, the programmer needs to know about all the storage class.
They all have important uses.
Variable that are created when they are declared and destroyed at the end of a block are called automatic variables because they are automatically created and destroyed.
Variables are automatic by default.
In the automatic storage class, variable is stored in memory, default value is garbage value, scope is local to the block, and life is within the block in which the variable is defined.
Static declarations have important and distinct use.
The more elementary use is allowing a local variable to retain its previous value when the block is reentered.
This is contrast to ordinary automatic variables, which lose their value upon block exit and must be reinitialized.
In the static storage class, variable is stored in memory, default value is zero, scope is local to the block, and life is value of the variable persists between different function calls.
The storage class register tells the compiler that the associated variables should be stored in high-speed memory registers, provided it is physically and semantically possible to do so.
In the register storage class, variable is stored in CPU registers, default value is garbage value, scope is local to the block, and life is within the block in which the variable is defined.
We cannot use register storage class for all types of variables.
In the extern storage class, variable is stored in memory, default value is zero, scope is local to the block, and life is as long as the program execution doesn't come to an end.
The main role of the preprocessor is built-in functionally for a resource by pretreatment equivalent replacement, the most common pretreatment: file contains, conditional compilation, layout control and marco replacement.
Conditional compilation: #if, #ifndef, #ifdef, #endif, #undef is also more common pretreatment, compile selectively selection, comment out the specified code version control, prevent duplication of files contained function.
Common Programming Errors with Functions:
* Reliance on automatic variables retaining their value between calls to a function.
* Failure to initialize variables within functions.
* Passing parameters in wrong order.
* Incorrect terminating conditions on recursive function calls.
Write a C function that has two parameters, the first parameter is an integer array, the second parameter is an integer indicating the size of the array.
Your function should return a double whose value is the average of the array of integers.
(The average will be the total divided by the number of intergers, which in this case is the second parameter.)
Write a C function that takes as input three floats prints them, one per line in sorted order (from lowest ti highest) and returns an integer.
The returned value is a number identifying the medium of the three values, i.e. neither the min or the max.
For example, if it receives 3.4, 5.1 and 2.4 as input, it prints:
2.4
3.4
5.1
and return 1.
(The first value, 3.4, lies between 2.4 and 5.1)
Pointer array: First, it is an array, the array elements are pointers, the array how many bytes determined by the array itself.
It is the "save pointer array" for short.
Array of pointers: First of all it is a pointer to an array.
In the 32-bit systems it will always be accounted for 4 bytes.
As for how much of it points to an array of bytes, do not know.
It is a "pointer to the array" for short.
C provides a special feature of pointer to a function.
As you know that every function defined in C language have a base address attached to it.
This base address acts as an entering point into that function.
This address can be stored in a pointer known as function pointer.
The pointer to a function is the declaration of pointer that holds the base address of the function.
One of the big uses for function pointers in C is to call a function defined at run-time.
malloc--->memory allocation
calloc--->contiguous allocation
So far, the compiler reserves storage for our data at compile time.
Dynamic memory allocation refers to requesting storage be reserved at execution time (When the program is running).
Dynamic memory allocation is most commonly used when we don't know the sizes for arrays when a program is built, but it can be used.
Dynamic memory is acquired through the "calloc()" or "malloc()" library functions.
Prototypes for these functions are in "stdlib.h", you must include this if you use dynamic memory allocation.
Dynamic memory is released for reuse by invoking the "free()" library function.
Once acquired by "malloc()" or "calloc()", storage stays in effect for the duration of the program unless released by free.
The storage may be in use long after the function that acquired it has completed.
You can neglect to free memory, if your program is small, but it is a better habit to always explicitly free dynamically allocated memory.
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 specially 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.
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, otherwise 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 ''.
Input three words between "I" and "you", such as "miss", "remember".
The make three sentences using "I", "you" and the words input.
Ex: "I miss you."
Using array of pointers to do this exercise.
Modify the program of exercise 2.
Read there words from command line.
Structure is a user-defined type.
A structure is a collection of one or more variables, possibly of different types, grouped together under a single name for convenient handling.
(Structures are called "records" in some languages, notably Pascal.)
Structures help to organize complicated data, particularly in large programs, because they permit a group of related variables to be treated as a unit instead of as separate entities.
Pointers and structures facilitate the formation of more complex data structures such as linked lists, queues, stacks and trees.
Keyword "struct" introduces the structure definition.
The identifier "Test" is the structure tag, which names the structure definition and is used with "struct" to declare variables of the structure type---e.g., struct Test.
Variables declared within the braces of the structure definition are the structure's members.
Members of the same structure type must have unique names, but two different structure types may contain members of the same name without conflict.
Structure members can be variables of the primitive data types (e.g., int , float, etc.), or aggregates, such as arrays and other structures.
Each structure definition must end with a semicolon.
In ANSI C automatic structures can be initialized, in traditional C only static and external structures can be initialized.
To initialize a structure, follow the variable name in the definition with an equal sign and a brace-enclosed, comma-separated list of initializers.
If there are fewer initializers in the list than members in the structure, the remaining members are automatically initialized to 0 (or NULL if the member is a pointer).
Two operators are used to access members of structures: the structure member operator (.)---also called the dot operator---and the structure pointer operator (->)---also called the arrow operator.
The structure member operator accesses a structure member via the structure variable name.
The structure pointer operator and structure member operator, along with parentheses (for calling functions) and brackets ([]) used for array subscripting, have the highest operator precedence and associate from left to right.
Note: ANSI C allows the assigment "a = b" if a and b are the same type of structures.
The assignment is interpreted as a member by member assignment.
Traditional C does not allow this type of assignment.
Structures may be passed to functions by passing individual structure members, by passing an entire structure or by passing a pointer to a structure.
Traditional C only allows passing a pointer to a structure as an argument.
In ANSI C, the structure itself can be passed too.
(Often use of the pointer is better, because a copy of the entire structure is placed on the stack when the structure is passed).
You can pass structures just as you can pass variables of any other type---int, float, char, arrays---to functions.
When structures or individual structure members are passed to a function, they're passed by value.
Therefore, the members of a caller's structure cannot be modified by the called function.
Arrays of structures are automatically passed by reference, like all other arrays.
Structures with pointer-member that refer to the containing structure type are known as selfreferential structures.
Structure that contains a pointer to a structure of the same type can be linked together to form useful data structures such as lists, queues, stacks and trees.
Use a linked list instead of an array when you have an unpredictable number of data elements or your list needs to be sorted quickly.
In computer science, a linked list is a data structure consisting of a group of nodes which together represent a sequence.
Under the simplest form, each node is composed of a datum and a reference (in other words, a link) to the next node in the sequence; more complex variants add additional links.
This structure allows for efficient insertion or removal of elements from any position in the sequence.
A linked list whose nodes contain two fields: an integer value and a link to the next node.
The last node is linked to a terminator used to signify the end of the list.
Singly linked lists contain nodes which have a data field as well as a next field, which points to the next node in the linked list, begins with a pointer to the first node, terminates with a null pointer, only traversed in one direction.
A union is a derived data type---like a structure---with members that share the same storage space.
For different situations in a program, some variables may not be relevant, but other variables are---so a union shares the space instead of wasting storage on variables that are not being used.
A union definition has the same format as a structure definition.
In a declaration, a union may be initialized with a value of the same type as the first union member.
The union definition is normally placed in a header and included in all source files that use the union type.
The number of bytes used to store a union must be at least enough to hold the largest member.
Unions may not be compared using operators "==" and "!=" for the same reasons that structures cannot be compared.
In most cases, unions contain two or more data types.
Only one member, and thus one data type, can be referenced at a time.
It's your responsibility to ensure that the data in a union is referenced with the proper data type.
A file is data stored in secondary storage.
This is usual a hard disk connected to the computer bus by means of some interface.
Accessing data in files is much slower than from memory, but files are more permanent and can be larger.
So what exactly is the difference between text and binary modes?
Well, the difference is that text files contain lines (or records) of text and each of these has an end-of-line marker automatically appended to the end of it whenever you indicate that you have reached the end of a line.
Binary files are not broken up into separate lines or records so the end-of-line marker is not written when writing to a binary file.
This pointer, called the file pointer, points to a structure that contains information about the file, such as the location of a buffer, the current character position in the buffer, whether the file is being read or written, and whether errors or end of file have occurred.
Users don't need to know the details, because the definitions obtained from <stdio.h> include a structure declaration called FILE.
C opens a file by linking it to a stream so you don't specify whether the file is to be opened in binary or text mode on the open statement.
Instead the method that you use to read and/or write to the file determines which mode you are using.
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.
If a file that does not exist is opened for writing or appending, it is created if possible.
Opening an existing file for writing causes the old contents to be discarded, while opening for appending preserves them.
Trying to read a file that does not exist is an error, and there may be other causes of error as well, like trying to read a file when you don't have permission.
If there is any error, "fopen()" will return NULL.
The function "fclose()" is the inverse of "fopen()", it breaks the connection between the file pointer and the external name that was established by "fopen()", freeing the file pointer for another file.
Since most operating systems have some limit on the number of files that a program may have open simultaneously, it's a good idea to free the file pointers when they are no longer needed.
Random access means we can move to any part of a file and read or write data from it without having to read through the entire file.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
武汉理工大学的Java实验课程中,包含了网络编程的内容。网络编程是指利用计算机网络进行信息交流和资源共享的编程技术。在这门课程中,学生将学习如何使用Java语言进行网络编程,以实现跨网络的数据传输和通信。 首先,学生将了解计算机网络的基本概念和网络编程的原理。他们将学习TCP/IP协议族和UDP协议的基本知识,了解套接字(Socket)编程的基本原理和使用方法。 然后,学生将学习使用Java提供的网络编程API,如Socket和ServerSocket类来实现网络通信。他们将学习如何创建客户端和服务器端的程序,通过网络进行数据传输和交互。学生将学习如何使用TCP协议建立可靠的连接和进行可靠的数据传输,以及如何使用UDP协议进行快速的数据传输。 在实验课中,学生将深入学习网络编程的高级主题,如多线程编程、并发编程和异步编程。他们将学习如何实现多个客户端与服务器的并发通信,如何处理并发访问造成的竞争条件和线程安全问题,以及如何利用非阻塞IO实现异步编程。 此外,学生还将学习如何使用Java的网络编程库,如Java NIO(New IO)和Java IO(Input/Output)类库,来简化网络编程的实现和提高程序的性能。 通过这门实验课程,学生将能够掌握Java网络编程的基本原理和技术,具备使用Java进行网络编程的能力。这将为他们今后从事与网络相关的软件开发工作奠定基础,并为他们提供更好的就业竞争力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

James_Xue_2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值