Chapter2_Basics of C and C++_part2
Chapter2_Basics of C and C++_part2
© HĐC 2024.1
Content
statement1
false false
statement2 condition true statement1
initial
statement statement
true update
condition
condition true statement statement
false true
false condition statement
false
Declared in <stdio.h>
Control string: a character array defines the format of
input/output string
Expressions: contain data to be presented
Variables: variables store input data (may be provided by
users)
& (ampersand): required symbol
%[flags][width][.precision][length]specifier
specifier Output Example
d or i Signed decimal integer 392
u Unsigned decimal integer 7235
o Unsigned octal 610
x Unsigned hexadecimal integer 7fa
X Unsigned hexadecimal integer (uppercase) 7FA
f Decimal floating point, lowercase 392.65
F Decimal floating point, uppercase 392.65
e Scientific notation (mantissa/exponent), lowercase 3.9265e+2
E Scientific notation (mantissa/exponent), uppercase 3.9265E+2
g Use the shortest representation: %e or %f 392.65
G Use the shortest representation: %E or %F 392.65
a Hexadecimal floating point, lowercase -0xc.90fep-2
A Hexadecimal floating point, uppercase -0XC.90FEP-2
c Character a
s String of characters sample
p Pointer address b8000000
Nothing printed.
n The corresponding argument must be a pointer to a signed int.
The number of characters written so far is stored in the pointed location.
% A % followed by another % character will write a single % to the stream. %
width description
Minimum number of characters to be printed. If the value to be printed is shorter than this
(number) number, the result is padded with blank spaces. The value is not truncated even if the result is
larger.
The width is not specified in the format string, but as an additional integer value argument
*
preceding the argument that has to be formatted.
%[flags][width][.precision][length]specifier
.precision description
For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value
to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated
even if the result is longer. A precision of 0 means that no character is written for the value 0.
For a, A, e, E, f and F specifiers: this is the number of digits to be printed after the decimal point (by default, this
.number is 6).
For g and G specifiers: This is the maximum number of significant digits to be printed.
For s: this is the maximum number of characters to be printed. By default all characters are printed until the
ending null character is encountered.
If the period is specified without an explicit value for precision, 0 is assumed.
The precision is not specified in the format string, but as an additional integer value argument preceding the
.*
argument that has to be formatted.
int main()
{
printf ("Characters: %c %c \n", 'a', 65);
printf ("Decimals: %d %ld\n", 1977, 650000L);
printf ("Preceding with blanks: %10d \n", 1977);
printf ("Preceding with zeros: %010d \n", 1977);
printf ("Some different radices: %d %x %o %#x %#o \n",
100, 100, 100, 100, 100);
printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416,
3.1416);
printf ("Width trick: %*d \n", 5, 10);
printf ("%s \n", "A string");
return 0;
}
int numPushups;
sub-specifier description
An optional starting asterisk indicates that the data is to be read from the
* stream but ignored (i.e. it is not stored in the location pointed by an
argument).
Specifies the maximum number of characters to be read in the current
width
reading operation (optional).
One of hh, h, l, ll, j, z, t, L (optional).
length This alters the expected type of the storage pointed by the corresponding
argument (see below).
%[*][width][length]specifier
specifiers
int main ()
{
char str [80];
int i;
return 0;
}
int scanfCount;
scanfCount = scanf(“%d”, & fahrenheit);
/* if scanfCount is not equal to 1 at this point,
the user has made some kind of mistake.
Handle it. */
It’s a must!
Examples:
cout.precision(8);
cout << 1234.56789 << ' ' << 1234.56789 << ' ' << 123456 << '\n';
cout.precision(4);
cout << 1234.56789 << ' ' << 1234.56789 << ' ' << 123456 << '\n';
// This produces:
// 1234.5679 1234.5679 123456
// 1235 1235 123456
cout.width(4);
cout.fill('#');
cout << "ab"; // print ##ab
#define PI 3.14159
#define ARRAYSIZE 10
const double Pi = 3.14159; /* Preferred */
enum {ARRAYSIZE = 10}; /* Preferred */
Speed
Implementation as a function, the code is copied to the program
before being compiled
It is not really effective with program running on PC
Common code
Macro enable to work with all kinds of data type (int,
double…)
int max(int x, int y) {
return x > y ? x : y;
}
#define SQR(x) x * x
Example:
int a = 7;
b = SQR(a+1);
will be replaced by
b = a+1 * a+1;
Solution: use parentheses to avoid the confusion
Example
b = ABS(a++);
would become
b = (((a++)<0) ? -(a++) : (a++));
Solution: do not use these operators in the macro
#define TIMELOOP(CODE) { \
t0 = clock(); \
for (i = 0; i < n; ++i) { CODE; } \
printf("%7d ", clock() - t0); \
}
Its usage would be:
TIMELOOP(y = sin(x));
WAIT_OBJECT_0;
#elif defined(__QNX__)||defined(__linux__)
if(flock(fd,LOCK_EX|LOCK_NB) == -1)
return 0;
else
return 1;
#endif
C provides operators
To change each bit individually
To perform operations which are usually available in Assembler
only
The C program with bitwise operation can run in
different OS, however most of these kind of programs
are written to work in specific hardware
6 bitwise operators in C:
& | ^ ~ << >>
These operators are applicable with the data types: char,
short, int, long.
They can be used for floating point arithmetic
5 bit assignment operators
&= |= ^= <<= >>=
Bit assignment operators are similar to arithmetic
assignment operators
z &= x | y;
z = z & (x | y);
In another way:
enum {
FIRST = 1 << 0,
SECND = 1 << 1,
THIRD = 1 << 2,
FORTH = 1 << 3,
ALL = ~(~0 << 4)
};
The last line is used to set/reset a group of bit
1111 1111 /* ~0 */
1111 0000 /* ~0 << 4 */
0000 1111 /* ~(~0 << 4) */
Structure Union
struct example union example
{ {
char X; // size 1 byte char X; // size 1 byte
float Y; // size 4 bytes float Y; // size 4 bytes
} }
X Y X&Y
1 byte 4 byte
5 byte 4 byte
Total size of all members
ready
error
write_protected
disk_spinning command error_code sector_number
struct Disk_Register
{
unsigned int ready:1; // 1 bit field named “ready”
unsigned int error:1; // 1 bit field named “error”
unsigned int wr_prot:1;
unsigned int dsk_spinning:1;
unsigned int command:4; // 4 bits field named “command”
unsigned int error_code:8;
unsigned int s:1;
}
Assuming that we have a 32-bit register with the above parameters
© HĐC 2024.1 Chapter 2: Basic of C & C++ 93
Bit Field Example 1
struct Disk_Register
{
unsigned int ready:1 ; // 1 bit field named "ready"
unsigned int error:1 ; // 1 bit field named "error"
unsigned int wr_prot:1 ;
unsigned int dsk_spinning:1 ;
unsigned int command:4 ; // 4 bits field named "command"
unsigned int error_code:8 ;
unsigned int sector_no:16 ;
};
E.g.:
#include <stdio.h>
typedef union {
float f;
struct {
// Order is important. Here the members of the union data tructure
// use the same memory (32 bits). The ordering is taken from LSB
// to MSB.
unsigned int mantissa : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
} raw;
} myfloat;
// Driver Code
int main()
{
// Instantiate the union
myfloat var;
// Get the real value
var.f = -2234.32425;
return 0;
}
#include <stdio.h>
int main(void) {
union {
float f;
unsigned char b[sizeof(float)];
} v;
v.f = 3.1415926535897932384626433832795F;
size_t i;
printf("%.20f is stored as ", v.f);
for (i = 0; i < sizeof(v.b); ++i) {
printf("%02X%c", v.b[i], i < sizeof(v.b) - 1 ? '-':'\n');
}
v.f = 0.0;
v.b[0] = 0xdb;
v.b[1] = 0x0f;
v.b[2] = 0x49;
v.b[3] = 0x40;