Notes after reading C primer plus
Data and C##
Definitions:
**Byte: **The C language defines a byte to be the number of bits used by type char , so one can have a system with a 16-bit or 32-bit byte and char type.
**Char: **C guarantees that the char type is large enough to store the basic character set for the system on which C is implemented.
**Size of Integer Types: **C guarantees only that short is no longer than int and that long is no shorter than int. The idea is to fit the types to the machine.
Suffix
l/L for long type constant
ll/LL for long long type(if the system supports)
Adding u/U before or after l/L indicates that the integer is unsigned.
Suffixes above are for integers, below for floating-point numbers
f/F for float type
l/L for double type
Header File Referred To
limits.h
stdint.h
inttype.h
Portable Types: stdint.h and inttype.h
1.exact-width integer types
Take int32_t as an example.
The type int32_t is an alias for a certain type in the system. The compiler will do it for you.
The header file(stdint.h) on a system that uses a 32-bit int could define int32_t as an alias for int . A different system, one with a 16-bit int and a 32-bit long , could define the same name, int32_t , as an alias for int . Then, when you write a program using int32_t as a type and include the stdint.h header file, the compiler will substitute int or long for the type in a manner appropriate for your particular system.
2.minimum width types
These are designed to save the space. Like the exact-width integer types, these are alias, too.
This set of names promises the type is at least big enough to meet the specification and that no other type that can do the job is smaller. For example, int_least8_t will be an alias for the smallest available type that can hold an 8-bit signed integer value.
3.fatest minimum width types
A example will surffice.
For example, the int_fast8_t will be defined as an alternative name for the integer type on your system that allows the fastest calculations for 8-bit signed values.
Plus: In some cases, only the biggest possible integer type in a system will do. intmax_t and uintmax_t will help you.
C99 and C11 provide assistance with the input and output of these types, which is defined in the header file inttypes.h.Notice that inttype.h includes the header file stdint.h.
#include <stdio.h>
#include <inttypes.h> // supports portable types
int main(void)
{
int32_t me32; // me32 a 32-bit signed variable
me32 = 45933945;
printf("First, assume int32_t is int: ");
printf("me32 = %d\n", me32);
printf("Next, let's not make any assumptions.\n");
printf("Instead, use a \"macro\" from inttypes.h: ");
printf("me32 = %" PRId32 "\n", me32); //PRId32 is defined
//as a string
return 0;
}
Question: Why Portable Types?
The same type name doesn't necessarily mean the same thing on different systems, which is not such a good thing.
Floating-point numbers
The constant 4e16 is a double type number, though it can fit in the type long.
new expression of floating-point constants:
Since C99, C has a new format for expressing floating-point constants. It uses a hexadecimal prefix ( 0x or 0X ) with hexadecimal digits, a p or P instead of e or E , and an exponent that is a power of 2 instead of a power of 10. Here’s what such a number might look like:
0xa.1fp10
The a is 10 in hex, the .1f is 1/16th plus 15/256th ( f is 15 in hex), and the p10 is 2^10 , or
1024, making the complete value (10 + 1/16 + 15/256) x 1024, or 10364.0 in base 10 notation.
Not all C compilers have added support for this feature.
Character Strings and Formatted Input/Output
Operators, Expressions, and statements
Assignment:The left side of the = sign must refer to a storage location.
sizeof:C says that sizeof returns a value of type size_t .
++:Be careful to use it.
side efects and sequence point:
Now for a little more C terminology: A side effect is the modification of a data object or file. For instance, the side effect of the statement
states = 50;
is to set the states variable to 50 . Side effect? This looks more like the main intent! From the standpoint of C, however, the main intent is evaluating expressions. Show C the expression 4 + 6 , and C evaluates it to 10. Show it the expression states = 50 , and C evaluates it to 50. Evaluating that expression has the side effect of changing the states variable to 50 . The increment and decrement operators, like the assignment operator, have side effects and are used primarily because of their side effects.
Similarly, when you call the printf() function, the fact that it displays information is a side effect. (The value of printf() , recall, is the number of items displayed.)
ctype.h:This header file contains some function prototypes to analyzing characters.
alternate spellings : iso646.h:
Note that not every language include the symbols used in C. This header file allows you to use and in stead of &&, or instead of ||.
order of evaluation:
Remember the order of evaluation in C is from left to right.
if (expression1 && expression2)
{
//do something
}
if the expression1 is false the program won't evaluate the expression2. Things go similiarly with ||.
they are not functions!
Typically, getchar() and putchar() are not true functions, but are defined using preprocessor macros, a topic we’ll cover in Chapter 16 , “The C Preprocessor and the C Library.”
buffers:
For buffered input:
The characters you type into the computer is stored in a buffer(a temporary storage) until you press the ENTER key. This enables you to edit the characters before you send them to the program.Functions like scanf() and printf() are buffered input functions.
For unbuffered input:
They are preferred for some interactive programs. Functions like _getch() and getche() are unbuffered input functions. _getch() is unechoed function and getche() is echoed function.
files, stream, and keyboard input
When a program reads a file, it doesn't read the file directly. It reads stream.
Conceptually, the C program deals with a stream instead of directly with a file. A stream is an idealized flow of data to which the actual input or output is mapped. That means various kinds of input with differing properties are represented by streams with more uniform properties. The process of opening a file then becomes one of associating a stream with the file, and reading and writing take place via the stream.
Therefore the differences between the ways of various system can be handled by the specific implementations of C. You can contrate on the code itself.
redirection
Typically, the input is from the keyboard and the output is to the screen. But as mentioned above, the program actually reads the stream, not files themselve and not the keyboard itself. So we can make a program read from a file and output to the screen.
operator: < > >> |
echo_eof < words
The < symbol is a Unix and Linux and DOS/Windows redirection operator. It causes the words file to be associated with the stdin stream, channeling the file contents into the echo_eof program.
The operator > does the opposite thing.
Of course you can conbine these two operators like this:
echo_eof < mywords > savewords;
echo_eof > savewords < mywords;//the order doesn't matter
For >> and |
Unix, Linux, and Windows/DOS also feature the >> operator, which enables you to add data to the end of an existing file, and the pipe operator ( | ), which enables you to connect the output of one program to the input of a second program. See a Unix book, such as UNIX Primer Plus, Third Edition (Wilson, Pierce, and Wessler; Sams Publishing), for more information on all these operators.
Note that these operators are all used in command line or terminal.
C Control Statements:Looping
C Control Statements:Branching and Jumps
Character Input/Output and Input Validation
printf()(Details)
The convertion specification %zd is used to print variables of size_t type.
The * modifier with scanf() and printf() :
For printf()The * is used when you don't want to define the field width.
printf("%*.*f", width, precision, fnum);
The * serves quite a different purpose for scanf()
scanf("%*d %*d %d", &n);
//input:1 2 3
//n = 3, the number 1 and 2 are skipped
scanf()
The return value of scanf() is the number of items it successfully reads.
Functions
compile programs with 2 or more source code files
You can use cc /gcc or other compilers
To compile two files to get one program:
gcc file1.c file2.c
You can also do this:
gcc file1.c ofile2.o
Then the file1.c is conpiled and linked with ofile2.o
Array and Pointers
Varieble-Length Array
They need to have the automatic storage
class, which means they are declared either in a function without using the static or extern
storage class modifiers ( Chapter 12 ) or as function parameters.
To declare a function with VLA arguments
int sum2d(int rows, int cols, int ar[rows][cols]);// ar a VLA
int sum2d(int ar[rows][cols], int rows, int cols); // invalid order
int sum2d(int, int, int ar[*][*]);//valid
The C99/C11 standard says you can omit names from the prototype; but in that case, you need to replace the omitted dimensions with asterisks.
Literal
Literals are constants that aren’t symbolic. For example, 5 is a type int literal, 81.3 is a type double literal, 'Y' is a type char literal, and "elephant" is a string literal.
Compound literal
For arrays, a compound literal looks like an array initialization list preceded by a type name that is enclosed in parentheses.
(int [2]){10, 20}; // a compound literal
(int []){50, 20, 90};
// a compound literal with 3 elements
string literal
Character string constants are placed in the static storage class, which means that if you use a string constant in a function, the string is stored just once and lasts for the duration of the program, even if the function is called several times. The entire quoted phrase acts as a pointer to where the string is stored. This action is analogous to the name of an array acting as a pointer to the array’s location.
/* strptr.c -- strings as pointers */
#include <stdio.h>
int main(void)
{
printf("%s, %p, %c\n", "We", "are", *"space farers");
return 0;
}
-------
output:
We, 0x100000f61, s
If the same string literal is used in a program more than once, the compiler has the freedom to store the literal used in more than one place in one or more places. When you declare a string array like this
char nama[] = "charles";
the literal "charles" is stored twice, first the literal is stored in the static storage, and then the program makes a copy of it and stores it in the storage which the array occupies.
Change a literal
What will happen if you do this?
char * p = "hello";
p[1] = 'k';
Your compiler may allow you to do this but under current C standard, the behavior of such action is undefined. Such a statement could, for example, lead to memory access error.(Reason can be found in the "freedom" mentioned before)
Character Strings and String Functions
Storage Classes, Linkage, and Memory Management
File Input/Output
Structures and Other Data Forms
Bits Fidding
The C preprocessor and the C library
Advanced Data Representation
Functions
Versions
1.The C99 and C11 allow you to make the name of an identifier as long as you want, but the compiler will only the first 63 words as significant.
2.The _Bool type is a C99 addition.(If you find that you can use bool type in your program, that's from c++)
C99 also provides for a stdbool.h header file. This header file makes bool an alias for _Bool
and defines true and false as symbolic constants for the values 1 and 0. Including this header
file allows you to write code that is compatible with C++, which defines bool , true , and false
as keywords.
Appendix
Precedence of Operators
. operator has higher precedence than & operator