1.Character data type.

Declaration and initialization of a character data
type variable.
-Character variable is defined to be of type char. For example: char ch; One character variable
occupies a single byte which contains the code for the character. This code is a numeric value
and depends on the character coding system being used (is machine-dependent). The most
common system is ASCII (American Standard Code for Information Interchange). In C language
does not exist data type string and therefore do not exist variables of string type but it is
possible to process strings. A string in C language represents a set of characters stored in
statically or dynamically allocated 1-D array of character type and terminated by null byte (null
character) and such a set of characters is considered as one object - a string.
A char can be initialized :
For example: char ch = ’b’

2.Functions for inputting a char from the keyboard.
1. scanf( “%c”, &ch); Note using of format specification %c for character type variable;
2. ch = getchar( ); Note that after pressing a character key on the keyboard it is necessary to
press also the Enter key, because function getchar( ) uses buffer memory of console as the
function scanf( ) does;
3. ch = getch( ); Note that function getch( ) does not use buffer memory what is way after
pressing a character key its value is directly assigned to corresponding character variable ch
without additional pressing the Enter key;
4. ch = getche( ); Function getche( ) defers from function getch( ) only by showing on the
screen a character (echo) introduced from keyboard as functions scanf( ) and getchar( ) do.
Scanf and getchar are in the <stdio.h> , and getch + getche are in <conio.h>

3.Functions for outputting a char from the keyboard
Output (writing) a character on the screen is performed by using standard functions
printf( ), putchar( ) declared in header file stdio.h and function putch( ) declared in header
file conio.h. For example:
printf(“%c”, ch); or putchar(ch); or putch(ch); for output on the screen a character
stored in the character variable ch;
printf(“%c”, ‘A’); or putchar(‘A’); or putch(‘A’); for output on the screen character A;
printf(“%c”,‘\n’); or putchar(‘\n’); or putch(‘\n’); for moving the cursor at the beginning of
the new line.

4.One dimensional array of characters and strings in C language.
In C language does not exist data type string and therefore do not exist variables of string type
but it is possible to process strings. A string in C language represents a set of characters stored
in statically or dynamically allocated 1-D array of character type and terminated by null byte
(null character) and such a set of characters is considered as one object - a string.
1-D statically allocated character array can be initialized as any array during declaration 1) by
assigning to it a string literal as we just considered before

1.char color[10] = “blue”
2) by assigning to it a set of characters ended by null byte.
For example: char color[10] = {‘b’, ‘l’, ‘u’, ‘e’, ‘###BOT_TEXT###’};

5.Functions to input a string from keyboard.
We can use the function that is stored in the <stdio.h> file „gets(str)”
It’s a function that returns a variable which points to the start of the string.
Input (reading) a string of characters from keyboard is performed by using standard function
scanf( ) and gets( ) declared in header file stdio.h. For example, a string can be introduced
from keyboard as follows:
scanf( “%s”, str);
or
gets(str); where str is the string name (name of character
array or pointer for dynamic array where the string is stored).
Note using of format specification %s in function scanf( ) call and absence of ampersand &
before str in both function calls, because name of string is a pointer( an address). It is also
important that function scanf( ) inputs(reads) a string from keyboard only till the first space, but
function gets( ) can input a string with spaces. It is recommended before functions scanf( ),
getchar( ) and gets( ) calls to use the function fflush(stdin) call for clearing the buffer
memory.

6.Functions to output a string on the screen.
The functions printf() and puts() can be used to output a literal on the screen. But if we
need to output a string that has a pointer pointing to it’s start we can do it like this
printf(“%s”, str); or puts(str);
Output (writing ) a string of characters on the screen is performed by using standard
functions printf( ) and puts( ) declared in header file stdio.h. For example:
printf(“%s”, str); or puts(str); for output on the screen a string named str (name of
character array or pointer for dynamic character array where the string is stored);
printf(“Hello, my friends!\n”); or puts(“Hello, my friends!”); for output on the screen
the string Hello, my friends! and for moving the cursor at the beginning of the new line.
printf(“\n\n”); or puts(“\n”); for output one blank line and for moving the cursor at the
beginning of the new line.

7.Standard library functions for character and string processing.
Character and string processing.

: strcpy(s1. Ex.h are: strlen( ) – to determine string length (returns number n of characters in the string str). Most of them are formed from one of the four basic arithmetic type specifiers in C (char.unsigned. And there are data types defined by user : structures and unions.h (character handling library for character processing). Ex.: strupr(str). s2). stdlib. Ex. s2). 8. Ex. k<0 if string s1 < string s2 (upper in dictionary) and k>0 if string s1 > string s2 (lower in dictionary). Ex.: strlwr(str). stricmp( ) – this function is the same as strcmp( ) but not case sensitive. and optional specifiers (signed.: n=strlen(str). strrev( ) – to reverse the characters in string str. int. The C language provides many basic types. strcat( ) – to join (concatenate) string s1 and string s2 together in one string s1. float and double). Data types in C 1.For character and string processing in C language can be used different functions from standard library header files ctype. strcmp( ) – to compare string s1 and string s2 (returns k=0 if strings are the same. strcpy( ) – to copy (assign) contents of string s2 to string s1.Classification of data types in C Language. strlwr( ) – to convert all characters in string str from uppercase to lowercase. Descriptions and examples of using of these functions presented in the Help option of Main menu of Turbo C++ compiler.h (general utilities library for string conversion functions) and string. Ex.: strcat(s1. s2). Ex. Fundamental Data Types o Integer types o Floating Type o Character types 2. short.: k = stricmp(s1. .h (string handling library for string processing). s2). Ex. The most useful functions for string processing from header file string. long) .: k=strcmp(s1. strupr( ) – to convert all characters in string str from lowercase to uppercase.: strrev(str). Derived Data Types o Arrays o Pointers o Structures o Enumeration Syntax for declaration of a variable data_type variable_name.

o The typedef can be easily changed later. nCourses. } STUDENT.Data types defined by user in C language Data types defined by user in C language are of 2 types. Here are two examples of the struct and typedef specifications: struct student {char name[40]. Use of typedef with structs  typedef is a powerful tool that allows programmers to define and then use their own data types. For example:  typedef int Integer. These define new data type names struct student and STUDENT and declare variables of structure type. *ps. studentID. allowing its use throughout the program.  Integer nStudents. Using typedef statement. which would then affect all variables of the defined type. Basicly structures and unions are used if a user wants to group many variables together . float average. st2 .  There are a few benefits of using typedef with simple types such as the example above:   o For readability. "Integer" may be easier to understand than "int"." ). such as structs: . st2 .Declaration of Struct data type specifications and variables. struct student st1. float average. int clas.  Note that in the typedef statement. int year. CL[26]. Structures and unions. ( say to "typedef long int Integer. These statements usually occur just after the #include statements in a program. 10. CL[26]. STUDENT st1.9. but they are of different types . so he cannot use arrays. the newly defined type name goes in the place where a variable name would normally go. A structure type is usually defined near to the start of a program using the struct statement or the typedef statement.*ps. int clas. thus he uses Structures and Unions. typedef struct student {char name[40]. However the real benefit of typedef comes into play with complex data structures. int year. The purpose of typedef is to form complex types from more-basic machine types and assign simpler names to such combinations. }.Data type Struct.

Accessing data fields within structs  The dot operator ( period ) is used to access named fields within struct variables: john. Both the same unnamed type // Illegal. sptr is of type 'pointer to struct country'. In the example above. Different types.nClasses = 4. . Access operation to the fields of structure. *sptr. sptr->population = 0. o ( Note: There is a potential problem if the structs contain pointers. Assigning one struct to another  If two variables are of the same struct type. both of the same type // Also legal. Database in form of 1-D array of stuctures. Fields of struct data type. Fields in a structure can be referenced by following the name of the structure by a dot and the name of the field.gpa. and sptr->population is of type integer. alice = charlie. sptr = &Russia. Using typedef statement. both of the same type // Still legal. struct country Russia. o See the variable definitions above to see why some of these are invalid. You can also declare a pointer to type 'struct country' and use that to reference the fields in a structure of that type. alice = bill. 1-D array of structures. totalGPA += sue. See below for details. Set of operations on database.population = 0.11. then they can be directly assigned one to the other. even though identical 12. // Legal. Russia is of type 'struct country‘. In this case. mary = carla. France. ) joe = sue. you follow the pointer name by an arrow and the name of the field.

reading (loading) elements of array from file. 13. An array of structures in C language can be used for storing and processing information of the same elements (structure objects) in a simple database. sorting elements of array. other operations related to determine some information (statistics) from database. 12. 11. deleting an element from array. Usually order and number of these function calls (order and number of options needed to perform) depend on and are . All these operations (options) can be implemented in a C language program for an array of structures database processing by creating corresponding number of functions (subprograms) and then by calling them from main( ) function in some order. freeing memory dynamically allocated for array. } STUDENT. It is possible to define an array of structures for example if we are maintaining information of all the students in the college and if 100 students are studying in the college. 10. 8. modifying an element of array. 5. and are a good way of storing lists of data with regular fields. dynamic memory allocation for an array of n elements of the given structure. We can define an array S of structures as shown in the following example. int year. such as databases. swapping two elements of array. input elements of array of structures from keyboard. int clas. writing (saving) elements of array in file. output elements of array on the screen. 4. STUDENT S[100]. inserting an element into array. 6. 7. 3.Arrays of structures are possible. 9. float average. For creating a database using an array of structures we have to determine a set of operations on it. searching an element in array. Usually this set of operations on an array of structures database can be represented as follows: 1. 2. typedef struct student { char name[40]. appending an element to the end of array. 14.

What is why it is necessary to develop appropriate user interface for communication between user and program. output elements of array on the screen. 6. writing (saving) elements of array in file. searching an element in array. 2. Usually order and number of these function calls (order and number of options needed to perform) depend on and are determined by user during a working session with database. . inserting an element into array. swapping two elements of array. Infinit loop and switch statment for menu of operations on 1-D array of tructures An array of structures in C language can be used for storing and processing information of the same elements (structure objects) in a simple database. 10. modifying an element of array. sorting elements of array. All these operations (options) can be implemented in a C language program for an array of structures database processing by creating corresponding number of functions (subprograms) and then by calling them from main( ) function in some order. other operations related to determine some information (statistics) from database. 4. 5. 9.determined by user during a working session with database. deleting an element from array. input elements of array of structures from keyboard. 8. “while( 1 ) // infinite while loop { clrscr( ). 12. freeing memory dynamically allocated for array. 3. 7. 14. Usually this set of operations on an array of structures database can be represented as follows: 1. What is why it is necessary to develop appropriate user interface for communication between user and program. puts(“\n \t \t menu:\n”). reading (loading) elements of array from file. 11. appending an element to the end of array. dynamic memory allocation for an array of n elements of the given structure. 13. 13. For creating a database using an array of structures we have to determine a set of operations on it.

You can contain unions within structures. char discount.-----------. …… “ 14. or structures within unions.puts(“\n 1. the C union is an unwieldy mechanism. either numeric or character data. Declaration of union specification and variables. Either way. or to handle a single field that could contain. Data type union. typedef struct transaction { int amount. | | V | | . A union is the equivalent of an assembler org or a COBOL REDEFINE. union { int count. dynamic memory allocation ”). char name[4]. Using typedef statement. for example. The syntax for unions is identical to that for structures. } Transaction. puts(“\n 2. } udata. input an array from keyboard”). You can use either typedef's or instream definitions: simply replace the word struct with the word union. It allows you to handle an area of memory that could contain different types of variables. A union definition has the following form: >>-union--+-identifier--------------------------+-------------->< | . A union might be used to group different record layouts from the same file. A union type definition contains the union keyword followed by an optional identifier (tag) and a brace-enclosed list of members.

a certain field is written and the subsequently read field is deliberately different. while valuable in certain circumstances. therefore. int y.'-+------------+--{----member--. the size of its largest data member. } tPoint. Differenses between struct and union variables. The size of an object of a union is. } gives | a | | b | +-----+ struct { int a. The size of an object of a struct is.-+--}-' '-identifier-' A union declaration has the same form as a union definition except that the declaration has no brace-enclosed list of members. A union member definition has same form as a variable declaration. therefore. all variable definitions that refer to that union must be placed within the statement that defines the data type. If a tag is not specified. like a point object consisting of two integers. comes at a great cost of safety: the program logic must ensure that it only reads the field most recently written along all possible execution paths. Once a tag is specified. float b. all of its data members are stored in contiguous memory locations. An example illustrating this point is: +-----+-----+ gives | a | b | +-----+-----+ ^ ^ | | memory location: 150 154 | ˇ +-----+ union { int a. the size of the sum of all its data members. The list of members provides the data type with a description of the objects that can be stored in the union. Fields of union data type. Difference between Union and Structure A union is a class all of whose data members are mapped to the same address within its object. In a structure. those being the x and y coordinates: typedef struct { int x. 15. This gain in space efficiency. The exception is when unions are used for type conversion: in this case. // x and y are separate . The identifier is a tag given to the union specified by the member list. } Structures are used where an "object" is composed of other objects. float b. any subsequent declaration of the union (in the same scope) can be made by declaring the tag and omitting the member list. Access and assignment operations for union data type.

this feature is unique to C compilers.  easier to read. typedef struct { tType typ. Recall that all preprocessor directives or commands begin with a #. Lets look at #define in more detail #define Use this to define constants or any macro substitution. // typ is separate. Preprocessor directives #include and #define. end we can do: #define begin { #define end } During compilation all occurrences of begin and end get replaced by corresponding { or } and so the subsequent C compilation stage does not know any difference!!!.. 16.  easier to modify  C code more transportable between different machine architectures.. Use as follows: . }. } tVal.. INT } tType. such as a type-less storage system: typedef enum { STR. // ival and sval occupy same memory.. Macro-definition and pseudo-function The C Preprocessor Recall that preprocessing is the first step in the C program compilation stage -. Use of the preprocessor is advantageous since it makes:  programs easier to develop. union { int ival. char *sval. For example to replace { .Unions are typically used in situation where an object can be one of many things but only one at a time. The preprocessor more or less provides its own language which can be a very powerful tool to the programmer. The preprocessor also lets us customise the language. } block statements delimiters by PASCAL like begin .

The argument list is enclosed in parentheses and must immediately follow the macro name. They are only active for the duration of a single source file starting when they are defined and ending when they are undefined (using #undef). redefined..y) ((x) > (y) ? (x) : (y)) Macro Caveats:  Macro definitions are not stored in the object file.#define <macro> <replacement name> For Example #define FALSE 0 #define TRUE !FALSE #include This directive includes a file into code. The use of #define should thus be limited unless absolutely necessary. "file" looks for a file in the current directory (where program was run from) Included files usually contain C prototypes and declarations from header files and not (algorithmic) C code (SEE next Chapter for reasons) Macros with arguments must be defined using the #define directive before they can be used. #define is primarily used to handle compiler and platform differences.g. Spaces are not allowed between and macro name and open parenthesis.  Macro definitions you wish to use in multiple source files may be defined in an include file which may be included in each source file where the macros are required. E. Today. a define might hold a constant which is the appropriate error code for a system call. . It has two possible forms: #include <file> or #include "file" <file> tells the compiler to look where system include files are held. or when the end of the source file is found. Usually UNIX systems store files in usr include directory. typedef statements and constant variables can often perform the same functions more safely. For example: #define MAX(x.

the file for writing data. int y = ABSOLUTE_VALUE( x++ ). w.txt”. This way. fp=fopen(“filename”.the file for appending data. is used as a communication link between the operating system and the program.the file for reading data . The file data is opened for reading and results is opened for writing. fp1=fopen(“data. fp2=fopen(“results. The third statement verifies if function fopen( ) returned NULL pointer and if so it means that file was not opened. This pointer. Because of side-effects it is considered a very bad idea to use macro functions as described above. In case the file results already exists. If we want to store data in a file in the external memory. 17. If you're not careful. its contents are deleted and the file is opened as a new file. the entire macro is surrounded by parentheses. making it rather useful as a pseudofunction creator. The second statement opens the file named filename of corresponding mode by using standard function fopen( ) and determines the value of file pointer fp for the given file. File pointer. return. Also. Consider the following statements: FILE *fp1. the variable "x" is always within its own set of parentheses. it will be evaluated in whole.”w”). If file data does not exist fp1 recieves .. which points to the data stracture FILE that contains all the information about the file.Another feature of the #define command is that it can take arguments. Notice that in the above example. if(fp= =NULL){puts(“file was not oppend”).} The first statement declares the variable fp called file pointer to the structure data type FILE that is defined in the stdio.”mode”). *fp2. we must use the following general format for opening a file: FILE *fp.txt”. Opening a file. In these statements the fp1 and fp2 are created and assigned to open the files data and results respectively. Consider the following code: #define ABSOLUTE_VALUE( x ) ( ((x) < 0) ? -(x) : (x) ) . } It's generally a good idea to use extra parentheses when using complex macros. a. int x = -10.. while( ABSOLUTE_VALUE( x ) ) { . to prevent it from being contaminated by other code. you run the risk of having the compiler misinterpret your code.h.. before being compared to 0 or multiplied by -1.. The mode of file can be of three main kinds: r.”r”). int x = -1. Functions fopen() and fclose() for opening and closing a file.

For example: fprintf(fp. This statement would cause the reading of items of list conform the control string. The function call putc(ch.txt”. The control string is file output specifications. list).h supports the function to close a file of the following format: fclose(fp). Closing a file. The fprintf( ) and fscanf( ) formatted functions are identical to printf( ) and scanf( ) formatted functions except that they work on files. writes the character contained in character variable ch to the file associated with the pointer fp1. name. fp1 ). list may include variable. constant and string. &quantity”). fp2=fopen fclose(fp2). age.5). ”%s%d”. . The above program opens two files and closes them after all operations on them are completed. For example: fscanf(fp. Observe the following part of program: FILE *fp1 *fp2. item. (“results. The fprintf( ) and fscanf( ) formatted functions for writing in and reading from file. The general format of fscanf( ) function call is: fscanf(fp. The input output library stdio.txt”.”r”). A file must be closed as soon as all operations on it have been completed. The getc( ) and putc( ) functions are analogous to getchar( ) and putchar( ) functions and handle one character at a time. Here name is a character array.NULL pointer value and file is not opened. ”control string”. … fclose(fp1). ”control string”. The function fclose( ) closes the file associated with the file pointer fp.5 is a float constant. The first argument of theses functions is a file pointer fp which specifies the file to be used. similarly the function getc( ) is used to read a character from a file that has been opened in read mode and than to assign it to character variable ch = getc(fp2). list). Where fp is a file pointer associated with a file that has been opened for writing. The general form of fprintf( ) function call is: fprintf(fp. Once a file is closed its file pointer can be reversed on other file.2f\n”.”w”). “%s %d %. fp1=fopen (“data. age is an integer variable and 7. 7.

e. &score) != EOF) { fprintf(ofp. 18. suppose the input file consists of lines with a username and an integer test score.where item is a character array and quantity is an integer variable.. then fscanf() will not be able to read that line (since there is no integer to read) and it won't advance to the next line in the file. a FILE * for the file to be read/written.. int score. "%s %d\n".. score+10). Continuing our example from above. So. The bad thing about testing against EOF is that if the file is not in the right format (e.h that can be used to read or write files..list -----foo 70 bar 98 biz A+ . . and that each username is no more than 8 characters long. For this error.: in. testing the return value against EOF is one way to stop the loop. Functions for input and output operations using files.. fscanf() will not return EOF (it's not at the end of the file). "%s %d". except they require an extra first parameter. /* One extra for nul char. while (fscanf(ifp. */ ..g. like scanf(). The function fscanf().. username. username.. Note: There are other functions in stdio.list -----foo 70 bar 98 . it returns the special value EOF. In the process.g..  Reading from or writing to a file: Once a file has been successfully opened.. } . normally returns the number of values it was able to read in. we'll increase each score by 10 points for the output file: char username[9]. We might use the files we opened above by copying each username and score from the input file to the output file. Look them up in a good C reference. you can read from it using fscanf() or write to it using fprintf(). a letter is found when a number is expected): in... when it hits the end of the file. These functions work just like scanf() and printf(). However.

In other words. so our condition could be: while (fscanf(ifp. they will not detect the end of the file until they try to read past it.). it might cause an infinite loop if the format of the input file was not as expected. then the loop will end. Since our format is "%s %d".. } Note that. either because we are at the end of the file or some other problem occurred (e. &score) == 2) { . To use it in the above example. it sees a letter when it is trying to read in a number with %d). &score) != 2) break. username. "%s %d".) != EOF or feof(. you would do: while (!feof(ifp)) { if (fscanf(ifp. only on the one after it. It just takes a file pointer and returns a true/false value based on whether we are at the end of the file. if we get 2 values. we expect it to read in 2 values.. Another way to test for end of file is with the library function feof(). However.. fprintf(ofp. If we don't get 2 values. we can add code to make sure it reads in 2 values (as we've done above). In some cases. they will cause an infinite loop..Errors like that will at least mess up how the rest of the file is read. username. score+10)... "%s %d". "%s %d".g. Functions File access fopen opens a file (function) freopen open an existing stream with a different name (function) fclose closes a file (function) fflush synchronizes an output stream with the actual file (function) fwide switches a file stream between wide character I/O and narrow character I/O (function) setbuf sets the buffer for a file stream .. username. Now. like testing != EOF. the loop continues. they won't report end-of-file on the last valid read. One solution is to test against the number of values we expect to be read by fscanf() each time. Note: When you use fscanf(.

(function) setvbuf sets the buffer and its size for a file stream (function) Direct input/output fread reads from a file (function) fwrite writes to a file (function) Unformatted input/output Narrow character fgetcgetc gets a character from a file stream (function) fgets gets a character string from a file stream (function) fputcputc writes a character to a file stream (function) fputs writes a character string to a file stream (function) getchar reads a character from stdin (function) gets (until C++14) reads a character string from stdin (function) putchar writes a character to stdout (function) puts writes a character string to stdout (function) ungetc puts a character back into a file stream (function) Wide character fgetwcgetwc gets a wide character from a file stream (function) fgetws gets a wide string from a file stream (function) fputwcputwc writes a wide character to a file stream (function) fputws writes a wide string to a file stream (function) .

a file stream or a buffer (function) reads formatted input from stdin. a file stream or a buffer (function) vprintfvfprintfvsprintfvsnpri prints formatted output to stdout. a file stream or a buffer using variable argument list (function) File positioning ftell returns the current file position indicator (function) fgetpos gets the file position indicator (function) fseek moves the file position indicator to a specific location in a file (function) .getwchar reads a wide character from stdin (function) putwchar writes a wide character to stdout (function) ungetwc puts a wide character back into a file stream (function) Formatted input/output Narrow/multibyte character scanffscanfsscanf vscanfvfscanfvsscanf (C++11)(C++11)(C++11) printffprintfsprintfsnprintf (C++11) reads formatted input from stdin. a file stream or a buffer (function) vwprintfvfwprintfvswprintf prints formatted wide character output to stdout. a file stream or a buffer using variable argument list (function) prints formatted output to stdout. a file stream or a buffer (function) reads formatted wide character input from stdin. a file stream or a buffer using variable argument list (function) wprintffwprintfswprintf prints formatted wide character output to stdout. a file stream or a buffer ntf using variable argument list (function) (C++11) Wide character wscanffwscanfswscanf vwscanfvfwscanfvswscanf (C++11)(C++11)(C++11) reads formatted wide character input from stdin.

Bitwise operations in C language Bitwise operators are special types of operators that are used in programming the processor. The Bitwise operators supported by C language are listed in the following table. addition and division are done using the bitwise operators which makes processing faster and saves power. auto-removing file (function) tmpnam returns a unique filename (function) Types Defined in header <cstdio> Type Definition FILE type.fsetpos moves the file position indicator to a specific location in a file (function) rewind moves the file position indicator to the beginning in a file (function) Error handling clearerr clears errors (function) feof checks for the end-of-file (function) ferror checks for a file error (function) perror displays a character string corresponding of the current error to stderr (function) Operations on files remove erases a file (function) rename renames a file (function) tmpfile creates and opens a temporary. mathematical operations like: addition. including its multibyte parse state 19. then: . Assume variable A holds 60 and variable B holds 13. capable of uniquely specifying a position in a file. capable of holding all information needed to control a C I/O stream fpos_t non-array type. subtraction. In processor.

Operators for bitwise logical operations Four of the bitwise operators have equivalent logical operators. . They are equivalent in that they have the same truth tables. Bitwise Logical a & b a && b a | b a || b a ^ b a != b ~a !a has the same truth table as ^ but unlike the true logical operators. 1101 Binary XOR Operator copies the bit if it is set in one (A ^ B) will give 49 which is 0011 ^ operand but not both. Logical operators consider zero false and any nonzero value true. This works because ! on a zero always results in a one and ! on any nonzero value always results in a zero.Operator Description Example Binary AND Operator copies a bit to the result if it exists in (A & B) will give 12 which is 0000 & both operands. Another difference is that logical operators perform short-circuit evaluation. logical operators treat each operand as having only one value. 20. 0000 Binary Right Shift Operator. The table below matches equivalent operators and shows a and b as operands of the operators. either true or false. However. 0001 (~A ) will give -61 which is 1100 0011 Binary Ones Complement Operator is unary and has the ~ in 2's complement form due to a effect of 'flipping' bits. This is because a logical operator must treat any nonzero value the same. != The example below shows that the truth tables for these Bitwise and Logical operators are identical but also demonstrates how they act on their operands differently. Mixing T2 with T will show them being treated the same unless the operand NOTs around != are removed. The need to normalize operands for != can be demonstrated by introducing a char T2 = 0x02 and packing it in an array. To be used as a logical operator != requires that operands be normalized first. by itself != is not strictly speaking a logical operator. The left operands value is moved A << 2 will give 240 which is 1111 << left by the number of bits specified by the right operand. Binary Left Shift Operator. The left operands value is A >> 2 will give 15 which is 0000 >> moved right by the number of bits specified by the right 1111 operand. rather than treating each bit of an operand as an independent value. signed binary number. A logical not applied to both operands won’t change the truth table that results but will ensure all nonzero values are converted to the same value before comparison. 1100 (A | B) will give 61 which is 0011 | Binary OR Operator copies a bit if it exists in either operand.

The number of places to shift is given as the second argument to the shift operators. • Shifts bits of the operand to the right. • Bits shifted in through the MSB are or – always 0 if the number is unsigned – either 1 ("right shift arithmetic") x >> n 0 ("right shift logical") if the sign bit is 1 (i. the result of right-shifting a negative value is implementation-defined.21. /* 0010 1101 (logical shift) */ .e. For example. the left and right shift operators are "<<" and ">>". Operators for bitwise shifting operations In C-inspired languages. results in • b1 00011010 b2 01101000 104 26 Bits shifted out of the MSB are lost. In C. if b1 and b2 are unsigned char then b2 = b1 << 2. x = y << 2. Left shift • Literally shifts the bits of the operand to the left. signed) signed char x = -75. Left shift performs multiplication by 2^n. • For example. Right shift • Right shift is a little more complicated. respectively. and the result of left-shifting a signed value is undefined if the result cannot be represented in the result type. Notice b2 is equal to b1*4. assigns x the result of shifting y to the left by two bits. • Bits shifted out of the LSB are lost. bits shifted in through the LSB are always zero. /* 1011 0101 */ signed char y = x >> 2.

Note the error trapping to force the user to conform to the expected usage: #include <stdio. /* convert strings to integers */ n = atoi(argv[2]).argv[0]. The library function getopt() can perform simple parsing of command-line arguments. return 1.m. • It is usually preferred to use unsigned types for bitwise operations to avoid non-portable behaviour. see the listing in section 3c of the man pages. Above example is 45 on logical-shift machine.n. different on different machines). printf("%s received m=%i n=%i filename=%s\n".n. n. Traditionally these are declared as follows: main() int main(int argc. } m = atoi(argv[1]). return 0. } 23. 22. The first element in argv is always the name of the program itself. and -19 on an arithmetic shift machine. Dynamic memory allocation 1-D array To allocate dynamically a similar 1-D array having number of elements introduced from keyboard the following code is recommended: int *A./* 1110 1101 (arithmetic shift) */ • Result is implementation dependent (ie. • Note: right shift is equivalent to division by 2^n if operand is non-negative or machine uses arithmetic right-shift. printf(“Enter number of elements of array: “).argv[0]).char *argv[]) { int m. Argument of function main() Passing Arguments to main() is passed two arguments from the shell: an integer and a pointer to an array of strings.char *argv[]) Here argc (``argument count'') contains one plus the number of arguments passed to the program from the command line and argv (``argument vector'') contains a series of char pointers to these arguments. Here's a more simple example of passing two numbers and a string. if (argc != 4) { printf("Usage: %s m n filename\n". .h> /* for atoi() */ int main(int argc.argv[3]).h> #include <stdlib. so argc is always at least 1.

where void* is the type of function which represents void pointer type of returning value and size is the parameter variable name which represents the size of the block of memory needed in bytes. Static memory allocation is performed by compiler conform variable declaration statements for global and local variables. A = (int*) malloc( n* sizeof(int) ).h . if ( !A) { puts( “\n Memory was not allocated”). function malloc( ) returns the beginning address (of void pointer type) of the block of memory allocated. &n). during program execution. This is achieved by use of the function free( ). The function malloc( ) is the basic function used to allocate memory on the heap (on the free store) in C language. Memory allocated statically can not be reallocated or freed (deallocated) by program itself (by programmer). Functions malloc( ) and free( ). Dynamic memory is allocated from a large part of unused memory area called the heap (also called the free store ). reallocated and freed at runtime by using pointer variables just allocated statically before at compile time. Global variables. In C language dynamic memory allocation is performed by program itself (by programmer) using special functions of standard library header file stdlib. Its prototype is: void free ( void* p). Dynamic memory is allocated. If the allocation is performed successfully. Note that because malloc( ) function returns a void pointer it is recommended to cast the type of returning value of function malloc( ) to a needed pointer type especially for compatibility of C language programs with C++ language programs. // or using here return statement } After this code it is possible to use allocated memory having access to it by means of pointer A which can be used as name of dynamic array. accessed. the block is said to be ‘freed’). If the allocation is not performed successfully function malloc( ) returns the NULL pointer value to indicate that no memory was allocated and usually in this case the program execution is terminated. Memory allocated by malloc( ) function will continue to exist until the program terminates or the memory explicitly deallocated by the programmer ( that is. . managed.scanf(“%d”. Its prototype is: void* malloc(int size). but automatic memory class local variables (specified by keyword auto or by default) having lifetime of a function call are allocated on the stack (is a part of computer memory where data is added and removed in a Last-In-First-Out (LIFO) manner). Dynamic memory allocation is the allocation memory for the unnamed dynamic variables at runtime. Static memory allocation refers to the process of allocating memory for the named variables at compile time before the corresponding program is executed. There are 2 kinds of memory allocation in C/C++ languages: a) static memory allocation and b) dynamic memory allocation. constants (specified by keyword const) and static memory class local variables (specified by keyword static) having lifetime of a whole program are allocated in fixed memory. // or if (A == NULL) // or shorter A = (int*) malloc( n*sizeof(*A) ).

it is strictly recommended to assign NULL pointer value to the pointer p immediately after free( ) function call. the expression A[5] is equivalent to the expression * (A+5) both represents the value of the 6-th element of int type counted from the starting address A. that name of pointer p can be used as another name of array A. 8092 and 10502. which is an ordinary pointer. Therefore. supposing these two declarations: int A[20]. that these. could be represented as: . int * p. After free( ) function call. b) p=&A[0]. For example. unlike p. the following assignments would not be valid: A=p. this square brackets operator [ ] or the indexation operator is also a dereferencing operator known as offset operator. 24. the memory pointed to by p is not more available for the program and what is why. c = &b. After that. supposing the randomly chosen memory locations for each variable of 7230. The only difference is that we could change the value of pointer p by another one.where p is the void pointer parameter for the beginning address of the block of memory just allocated before by malloc( ) function or other functions used for dynamic memory allocation. so it operates as a constant pointer. expressions &A[5] and (A+5) are equivalent and both represent the address of the memory where this element is stored. Pointers to Pointers C allows the use of pointers that point to pointers. It dereferences the variable (name of array or pointer) it follows just as the dereferencing pointer operator * does after adding the subscript to the name of array and thus obtaining the memory address of the corresponding element. p and A would be the same and would have the same properties so. Well. point to data (or even to other pointers). and we cannot assign values to constants. we only need to add an asterisk (*) for each level of reference in their declarations: char a.so in fact they are the same concept. Therefore. Analogically. a = 'z'. A=A+1. Concerning 1-D arrays we used square brackets [ ] in order to specify the index (subscript) of an element of the 1-D array to which we wanted to refer. and an array can be considered a constant pointer. The following assignment operations would be valid and equivalent: a) p=A. In order to do that. b = &a.Pointers and Arrays In C/C++ languages the name (identifier) of an array is equivalent to the address of its first element . This. in its turn. whereas A will always point to the first of the 20 elements of type int with which it was defined. Because A is an array. char ** c. So. char * b. A is an array.

How will we keep track of those pointers? There are.*c has type char* and a value of 7230 . but with a size which we get to pick at run-time. Dynamically Allocating Multidimensional Arrays We've seen that it's straightforward to call malloc to allocate a block of memory which can simulate an array.h> int **array. p = NULL. which can be used in three different levels of indirection.// p has a NULL pointer value Do not confuse NULL pointers with void pointers. The new thing in this example is variable c. i < nrows. under the cells are their respective addresses in memory. "out of memory\n"). after all. and each row will therefore be represented by a pointer. exit or return } } . A null pointer is a value that any pointer may take to represent that it is pointing to "nowhere". each one of them would correspond to a different value: . Can we do the same sort of thing to simulate multidimensional arrays? We can.**c has type char and a value of 'z' A NULL pointer is a regular pointer of any pointer type which has a special value that indicates that it is not pointing to any valid reference or memory address. If we don't know how many columns the array will have. if(array == NULL) { fprintf(stderr. but we'll end up using pointers to pointers. either. So we want to simulate an array of pointers. array = malloc(nrows * sizeof(int *)). one for each row. we'll clearly allocate memory for each row (as many columns wide as we like) by calling malloc. exit or return } for(i = 0. 27. many of them. but we don't know how many rows there will be.c has type char** and a value of 8092 . if(array[i] == NULL) { fprintf(stderr. while a void pointer is a special type of pointer that can point to somewhere without a specific type. This is best illustrated with an example: #include <stdlib. and this will be a pointer to a pointer. i++) { array[i] = malloc(ncolumns * sizeof(int)). int * p. "out of memory\n").The value of each variable is written inside each cell. so we'll have to simulate that array (of pointers) with another pointer.

Here is a function which zeros out a pointer-to-pointer. (Just freeing the top-level pointer. In other words. The function also accepts the dimensions of the arrays as parameters. (This is a pretty nice result: although some completely different machinery. it becomes possible to write ``heterogeneous'' functions which don't have to know (at compile time) how big the ``arrays'' are.'' we must remember to free each of the chunks of memory that we've allocated. i < nrows. two-dimensional ``array'': void zeroit(int **array. it has nrows elements. involving two levels of pointer dereferencing. array. If we write array[i][j] we're asking for the i'th pointer pointed to by array. i. and then for the j'th int pointed to by that inner pointer. on the assumption This that we'll only be calling it with simulated. when it comes time to free one of these dynamically allocated multidimensional ``arrays.) Here's what the code might look like: for(i = 0. int ncolumns) { } function does accept a pointer-to-pointer-to-int. int nrows. we then fill in the pointers (all nrows of them) with a pointer (also obtained from malloc) to ncolumns number of ints. } } Finally. int ncolumns) { int i. if we did. If this isn't quite making sense. it points to a block of pointers. i < nrows. j < ncolumns. free(array). If we successfully allocate it. the storage for that row of the array. one for each row. (We must not call this function on arrays like the ``true'' multidimensional array a2 of the previous sections). is going on behind the scenes. . dynamically allocated multidimensional arrays. i++) free(array[i]). we can (just as for the one-dimensional case) use array-like syntax to access our simulated multidimensional array. j. dynamically-allocated two-dimensional ``array'' can still be accessed just as if it were an array of arrays. The function will look something like func2(int **array. i++) { for(j = 0. one function can operate on ``arrays'' of various sizes and shapes. j++) array[i][j] = 0. the simulated. so that it can iterate over them correctly. and would waste memory. a picture should make everything clear: array Once we've done this. dynamically allocated multidimensional arrays. wouldn't cut it. with the same pair of bracketed subscripts. int nrows. so that it will know how many ``rows'' and ``columns'' there are. for(i = 0. That first-level pointer is the first one we allocate. all the second-level pointers would be lost but not freed. with each element big enough to hold a pointer-to-int. or int *.) If a program uses simulated.is a pointer-to-pointer-to-int: at the first level.e.

In C/C++ languages values of subscripts start by 0. In mathematics arrays are known as matrices and are used for solving different problems. . Usually in computer programming are used one-dimensional (1-D) and two-dimensional (bedimensional) arrays (2-D). an array is a composed variable or a data structure. and for 2-D array type name[number of rows(lines)][number of columns]. Ex.: A[0] is the first element of an 1-D array named A. Array declaration and initialization The general form of an array declarations in C/C++ languages are following: for 1-D array is type name[size(length) of array or number of elements]. Dimension of an array depends on the number of integer values called indices (subscripts) used for determining the position of a given element and for accessing to the corresponding element. One of these kinds is an array. In C/C++ languages indices (subscripts) are enclosed in square brackets [ ] represented the indexation operator. As we defined before (see lecture 2) a composed or structured variable represents named location in the memory of computer. One subscript is used for indicating elements of 1-D array (vector) and two subscripts are used for elements of 2-D array(matrix). Arrays are very often used in programming for storing and processing data. C[2][3] is an element of the third row(line) and of the fourth column of an 2-D array named C.28. float B[50]. In mathematics 1-D arrays also called vectors represent special kind of matrices (2-D arrays) having only one line (row) or one column. which represents named set of values ( also called elements or components) of the same type. where more than one value can be stored. located in the memory of computer continuously one after one. Ex. In programming.: int A[20]. There are different kinds of composed variables which are also called data structures. B[3] is the forth element of an 1-D array named B.

2. Arrays can be initialized during declaration in such a way: int A[5]={3. 9. 2.-5.55 } }. Such functions are called recursive .3.{-5. 47.7. or float B[2][3]={ 3. A recursive function must have mandatory some condition to stop the recursion.5.5. otherwise it will call itself till stack overflow occurs. 9. Example: unsigned int Factorial (unsigned int a) { if (a<2) return a. 2. -5. 30. return a*Factorial(a-1). } .char C[10][30].3.55 }. 47. Recursive function A function can be called not only from by other function by also by itself. float B[2][3]={ {3.6. 0}. for example by input elements from keyboard or from existing file or by using special random function(program) for generating elements of an array.2. 0}. 0. Usually initialization of arrays is effectuated in run time by different ways.

in fact. the first return statement return a. In this way. In this case. ending up with the value required being returned to main(). This continues until the argument in the last call of the factorial() function is 1. Within the factorial() function itself. . is executed and the value 1 is returned to the previous call point. This call point is. the statement executed is: return a*Factorial(a-1). and the return can’t be completed until the value is returned from this call to the function factorial() with the argument 3. which can now calculate 2 * 1 and return to the previous call. This expression can’t be evaluated. and it calls factorial() again with the argument value 3 from within the arithmetic expression. because the argument is greater than 1. inside the second return in the factorial() function.The function factorial() gets called from main() with number having the value 4 as the argument. This is the second return statement in the function. the whole process unwinds.