 Today we are going to discuss a different kind of data type which requires the understanding of the concept of a pointer. This is not a natural concept in modern programming and in fact even object oriented programming languages like Java and all do not provide for an explicit pointer type of data handling. However C++ which emerges out of the traditional C uses the notion of pointers extensively. In fact as we shall see later in the lecture invoking functions by passing on parameters by reference requires us to understand and use pointers. Curiously the string variables which we have used so far in the class were just like a float or a double or an integer we would define a variable called string and assign any string value to it. We never bothered so far about how a large or small string could be accommodated in a single variable. We have never put an upper bound on the number of characters in a string that we insert in a string variable. Whereas we have upper bounds on integers, floating point numbers, double, etc, etc. It is important for us to understand the notion of capacity of storage, the notion of addresses of storage elements and that is what we shall look at in this lecture. Effectively what we are going to discuss is the representation of data objects inside a computer. So when now we talk about a computer we are talking about the real machine. We shall have another lecture later to describe the notion of hardware and system software but today we are just going to look at how the data is actually represented inside the machine. So essentially we will look at bits, bytes and memory locations, specifically look at the data type called care. This is not a type we have introduced so far at all. So this is a new data type as far as we are concerned. We shall look at how the care type of data is handled, how character strings are handled using care type of data and what are essentially pointers which are essentially references to the addresses of the locations which contain values. We will specifically look at parameter passing by value, parameter passing by reference and a function call where we use the pointers rather than the values. So this is how the actual data is represented. The machine comprising of electronic components specializes in using devices which can exist in one of the two states only like a stretch which can be either on or off. There is no intermediate position typical. So similarly the digital electronics permits you to have devices which are called transistors in a state of zero or in a state of one. Zero and one are notional. They are actually represented by physical variables such as voltage levels. So certain voltage and below that could be zero, certain voltage and above that could be one or vice versa. In fact in the modern electronic circuits the entire game is played through electronic circuits which can combine the so called logical levels of zero and one or high voltage and low voltage through hand gates, OR gates, NAND gates, etcetera, etcetera to provide for variety of combinations that you can make out of the zeros and ones. A more complex circuit would result in a circuit for adding two binary numbers, subtracting binary numbers. In fact addition and subtraction is hardly distinguished because computers used what is known as the one's complement and two's complement notion for representing negative numbers. We are not going to those details right now. Suffice it to say that any data within the machine is actually represented using only two symbols. Zero and one. There is no third symbol. So naturally if you wish to represent larger values such as decimal numbers. For example we need more binary digits or bits. BIT bit stands for binary digit, is a short form for binary digit. For example if I want to represent number four it could be represented by one zero zero. Number five would be represented by one zero one. You are all familiar with binary representation of numbers? Not a very enthusiastic yes. So you have not studied binary representation. A binary representation is very much like a decimal representation where the base is two and not ten. So worthwhile to quickly look at that. Here is a representation of decimal number strain because you have ten symbols, zero to nine. You write them in the unit position. You have exhausted the symbols. So if you want to write the next value which we verbally call ten, that ten will have to be represented by going to the next position. Writing one there and writing a zero here again which is the first symbol. After that the next number eleven is written as one one then one two and so on. So basically you keep incrementing this position till you exhaust the symbols. Then you increment the next position by one and again start incrementing the unit position and so on. This is the decimal system. If you add an octal system, an octal system will have only eight digits. Zero, one, two, three, four, five, six, seven. These are the seven symbols in an octal digit. An octal meaning base eight system. A base eight system does not recognize any symbol beyond seven. Zero, one, two, three, four, five, six, seven. That's it. So there's eight, nine, etc. Do not exist in an octal system. So obviously the next value that you want to write here which is eight as we conventionally call it will be written as one zero. Then when you go on one, one, one, two, etc. At one seven you will again exhaust these symbols. So the next value will be written as two zero. So just as a decimal system is represented. Suppose you have two digits, you would call it d one into ten to the power zero plus d two into ten to the power one plus so on. This is the decimal system. The octal system on the other hand will be written as d one into eight to the power zero plus d two into eight to the power one plus so on. So look at this one zero. One zero will mean one into eight to the power one plus zero into eight to the power zero. So one zero is actually eight. One one is actually nine. Two zero is sixteen. One seven is actually fifteen in octal system. So this is the way you represent numbers in different system. Suppose you had an hexadecimal system where the digits are zero, one, two, three, four, eight, nine, a, b, c, d, e, f. How many symbols? Sixteen symbols because you have the base as sixteen. So you can write a number wherein again the representation will be d one into sixteen raised to zero. Sorry d plus d two into sixteen raised to one plus so on. So what will be the decimal value of a number a eight hexadecimal? What is the decimal value of this number? It is eight into sixteen raised to zero which is eight plus a into sixteen raised to one. A is how much? Numerically decimal value is ten because this represents nine, a represents ten, b represents eleven, c represents twelve, etc. So a actually represents ten. Ten into the power sixteen is how much? So this is equal to one sixty eight. So that is how you would represent different numbers in different number systems. Coming back to binary number system it is much simpler because you have only two symbols, zero, one. Now you want to write the next number which is numerically as we understand is is value two. We have no symbol left. So what do we do? Like we did in the decimal system, if you see here what did we do? We went up to nine and we exhausted the symbols. We wrote one here and wrote zero here. Exactly that is what you will do here. So this is binary representation of two. You carry on with this one zero, next number is one one. But after that there is no other symbol. So this becomes zero. After that there is no other symbol. This becomes zero and then you write one here. So that is how the binary number system you can easily work out what will be the different values and so on. What I have tried to do here in this slide is to just show exactly some sample value. So this is zero zero zero zero zero zero zero one is one, zero one zero is two, zero one one is three and so on. Naturally the largest number that you can represent using three binary bits is zero because all one one one. Smallest number is zero, largest number is seven. The total number of numbers that you can represent with three bits is two to the power three. Just as total number of numbers that you can represent with three decimal digits is ten to the power three. Thousand numbers zero to nine nine nine. Similarly here zero zero zero to one one one. The next number naturally you have to write as one zero zero zero and so on. It should be very obvious that when my numbers become large the number of bits that I will need will be larger and larger and larger. Typically eight such bits are grouped together to form what is known as a byte. In fact the common unit of measurement of memory capacity of a computer is always a byte. This is the smallest unit in which you measure the computer's memory. Nobody measures it in bits but bits are grouped together and there is a historical reason why a group of eight bits is called a byte and why not a group of six bits or why not a group of 48 bits or why not a group of 137 bits. Any number could have been chosen. People chose eight bits to represent a byte for a reason. We shall see that reason later. So the computer, the machine actually has a memory comprising of a large number of bytes. Each of the bytes has a unique address. Just like our homes in a colony but homes are larger, smaller but each home has a unique address. In computer memory a byte is a home. All homes are exactly identical. Each home can contain eight bits and each home has a unique number, a unique identifier. That unique identifier is called the address of that byte. Most machines are byte addressable. For certain representations it is not conducive to use a single byte. It should be obvious that some of the values that we deal with cannot be represented in a byte. For example, suppose I want to use some numerical values. I want to represent 1258. Can I represent it in the eight-bit byte? No, 8-bit byte, the largest number in an 8-bit byte is 0 to 255, not sufficient. So what I do? I extend the binary representation and take a 2-byte representation or a 4-byte representation or an 8-byte representation. We had roughly touched upon this topic when we discussed the maximum values represented by our integer, float and double and long kind of types. There at that time we had roughly calculated the number of decimal digits that can be held in integer values and the number of digits of precision that you can have in floating point and double degree. But we look at it from a decimal angle. Actually what happens internally is the entire arithmetic is binary or some form of binary, octal or hexadecimal. Hexadecimal is more popular because when you consider exponents, instead of considering them as power of 2, considering them power of 16, permits you to have very large exponents. The same bits will represent a much larger value if the base is 16. However, the precision depends entirely upon the number of bits that you have for mantissa or the number of digits that you have in an integer or long will again depend upon the number of bits that you have for the procedure. Along on short of the story is that 8 bits are never sufficient to represent meaningful numerical values and therefore, computers group multiple of bytes together and these bytes could be said 2 or 4 bytes can be used to represent integers, 4 or 8 bytes can be used to represent floating point numbers. So, consider this int m and float a3. This is an array. This array has of 3 elements a0, a1, a2. Now, consider how the memory is allocated in Dumbo's drawers. We had seen this model earlier. There will be a drawer which will contain let's say value 573. It will be tagged as m. This drawer is tagged as m. Three consecutive drawers will be tagged as a0, a1, a2. These are the memory locations and these are the values. Now, if the address of m, notice that what m is? Can the value 573 be stored in 1 byte? Answer is no. In fact, when we say integer m, depending upon the implementation of C++ compiler, the memory allocated will be either 2 bytes or 4 bytes. Similarly, depending upon the implementation of float, float will generally be 4 bytes. Assume that the computer representation that we are talking about for our C++ compiler uses 4 bytes for integers and 4 bytes for floating point. Now, as I said, I have here m and a0, a1, a2. Let us write down in terms of the memory map, in terms of bytes. How exactly will this look like? Let us say this is 10000 bytes and this is where the value of m begins. As you know, m is defined as integer. That means it will require 4 bytes. So the value of m will occupy 4 consecutive bytes. And these 4 bytes are to be considered as if there is a sequence of 0010, etc., etc., 1011, whatever, whatever, whatever, whatever. All of this considered to be a single binary number is the value of m. But the m itself begins its existence from byte number 10000, which are arbitrarily chosen to be some address of a byte. However, the next variable n does not begin at 10000. It will begin at 10000, 4. I am deliberately using these numbers as decimal numbers. So it is as if we have 1 byte houses in a colony. Each house has a unique number. But by definition, certain values will take more than one house to live. An integer will take 4 consecutive houses. A float will take another 4 consecutive houses. A double will take 8 consecutive houses. Now whether m is allocated memory immediately before n or somewhere else, it does not matter. But all 4 bytes of m must have consecutive houses because the bits must be interpreted consecutive. Usually in C++, when you declare memory, almost all the variables that you have declared, in the order in which you have declared, they get allocated memory. So consequently, you will have m allocated here, m allocated next 4 bytes, and this will be 4567. The next is array A. The a0 element, please remember the array A is float. Each element requires 4 bytes. So a0 itself will begin 1008 and so on. Is this notion clear of memory allocation? Now inside my C++ program, whenever I say m equal to something, what the C++ compiler does is it calculates that something in the binary format naturally and puts that something into these 4 locations. When I say m is equal to p plus q, it does the same thing with. How does it know where to keep this value? m is after all a symbol that I have used. The C++ compiler, when it is looking at your program, the process of compilation comprises of the following. Memory allocation and freezing memory locations in computer's memory where the listed variables of your program will finally reside. So consequently it is C++ which assigns the memory locations actually. It says I require 4 locations for m, 4 for n, 4 for a0, if there is 8 for double, etc. And these are the addresses of those memory locations. So consequently the address of m is 10000. But address of n is not 10000, 1 but 10000, 4. What does this depend upon, this displacement? This depends upon size of the variable. So if the variable is integer or double or float, the size could vary. As I said, the size could depend upon the compiler. Integer for example could be implemented in 2 bytes or 4 bytes. How will you know? If at all you have to find out. As we shall see later, you might have to find out. There is a special function available in C++. If you just say size of m, the size of m looks at the type of m and returns the number of bytes that m will occupy in the computer's memory. So it will return 2 or 4 or 8 or 20, whatever be the size. So it is a useful function. Why are we going through all these details here? We are going through all these details because ordinarily we refer to these contents of memory locations by the nice names that we choose for them, m, n, a0, a1, etc. However, there are occasions when we may want to refer to these contents by the actual addresses. And why would we like to do that? Why would we like the actual addresses to be handled? After all, what do we bother about? As long as m and n mean whatever we refer to. Let me skip to another slide which is much later and motivate you to understand why these are required. Consider parameter passing to functions. So let me give you the same example here. Imagine I have written a function like this, integer function sum, int a, int b. I don't have to do any computation here because I want to add them and find it out. It's obviously an artificial function. I don't need a function to add to the numbers. I could do that directly by a simple arithmetic expression. But this is just to illustrate the point. So if this was the function, I can simply say return a plus b. This will mean that the value that is returned by this function call which is an integer value will be the value of a plus b. In the main program, what I do is I write int m, n and s. I read in the value of m and n. I invoke this function sum m, n. And the resultant value which the function will return, I am assigning it to s which I print out. It's a normal way of invoking function. Now observe what is happening here. When I say sum m, n, the value of m is transferred to the corresponding variable integer a here. The value of n is transferred to the corresponding value of b here. And these values which have been transferred are added to get one single value written. So that is how I get back s. This is called passing parameters by value. So the parameter value is located and that value is passed. That is the reason why instead of m or n I can write a constant value or I can write an expression which will be evaluated. Its value will be copied there. This is as if I have a variable m which starts here 1, 2, 3, 4 bytes and a variable n which starts here 1, 2, 3, 4 bytes and then I have this s which starts here. Something like this. This is my memory allocation for the main program. Imagine as if in the function I have a similar allocation for a and b. So effectively what is happening is this value of m is actually transferred to the value of a. This value of n is transferred to the value of b. And the computations happen on these two values. And the return value which is returned by this statement is returned back into this expression. So when I say s is equal to some m, n. m, n goes there into a and b. a and b is added and the return value becomes the value of this entire expression by the way. This whole expression is replaced by the return value which is then gets assigned to s and so on. This is called value passing by value. Please note that this works perfectly alright when I have functions which are to return only one result value. Whether it is sum of 2 numbers or sum of an array of 1000 numbers or an average of 1000 numbers as long as a single value is to be returned. A single string, a single number, this function call is perfectly fine. But what if I have to calculate 2 values and return them or 3 values and return them or 1000 values and return them. This mechanism is not good enough. That is what I have tried to explain in this slide. What do we do if we need to get back more than one value upon return? More importantly, how do arrays get passed to a function come back with modified values? You remember that I had in one of the slides given you an example of a function which reads a large amount of data into an array and returns the number of students for whom the data has been read. Technically the single value which was returned was the number of students. That is the single integer value and that is the return value of that function. So all of us assume that it is perfectly fine because the single value has been returned. What all of us forgot to ask is that look the same function was reading data from input and pushing it into various elements of the array and we presume somehow that when we come back to the main program all the array elements will continue to contain the values with the functional array. Strictly speaking in passing by values no such thing can be imagined. Anything that happens inside the function on variables that I have passed on from here there is no reflection back. Arrays is an exception because arrays are always passed through a pointer or reference and not by value. We need to understand what it means by passing a reference rather than a value. Effectively let's go back to this example here. If this is my mechanism where the value of m is copied into a and then this function operates upon it there is no mechanism for me to get back the change value from here. Consider for example instead of returning these values I wanted to swap these values. What is the value in m? I want to put it in n. What are the values in n? I want to put it in m. I can write a main program to do that by using a temporary variable. I can initiate temp2 equal to m then say m is equal to n, n is equal to temp. The two values will get swapped. But suppose I wrote a function where you send me two values and I will return back swap values. I can't do it because I can't return two values. However if I say that instead of passing the parameters by value as in this mechanism if I could somehow pass on the address of this m and the address of this m which is called a pointer if somehow I could pass this pointer and indicate to this function that look buddy what you are getting is not an integer variable value but you are getting a pointer then it will tell this function that while I use these parameters I am not supposed to copy the values and use them but rather directly use the pointer and the value pointed out by that point. That means effectively there is no separate memory allocation that this function should do for such parameters which are passed as pointers. But it says rather use the original position itself in the memory wherever the main function is. Naturally if then in the process the function modifies any one of these parameters obviously the original values will be modified because there does not exist any copy. All operations are done on the original thing itself. So this is the advantage of passing by reference where I say I am not passing the value but I am passing a pointer to the reference. However I need additional notation. How do I represent pointers? How do I tell the function that I am not sending a value and sending a pointer reference to you? These are some of the issues that we need to check which we shall see now. So in short the normal memory allocation is done in the order of appearance and as I said in actual practice the addresses would invariably for typical implementation be like this. If the first location has an address 10,000 then the next location for n will have the address 10,004 because m will be allocated 4 consecutive bytes n will be allocated 4 consecutive bytes a0 will be allocated 4 consecutive bytes and so on. Notice that all the other elements are always allocated consecutive bytes. So while m and n technically can be anywhere a0, a1, a2, etc. will never be anywhere they will always be together. In terms of data representation so we just notice the following. Pointers are nothing but such addresses. What should be the maximum value of address, minimum value of address? After all that will depend upon the type of computer you have. Some computers have very large memory and therefore they have the address space. It is almost like saying how big is the housing colony? If the housing colony has only 1,000 houses 3 digit address should be sufficient 0, 0, 0, 9, 9 but if the colony has 10,000 houses I will require 4 digit address. If the colony has million houses I will require so many digits. So depending upon the size of the colony the address, number of digits in the address will vary. If I say that address is my pointer then I will have to worry about the value in the pointer. However a C++ compiler takes care of that. Whenever it compiles it allocates sufficient memory for the pointer so that the address within the scheme of the machine that it is dealing with that addressing space is sufficient. So we don't have to worry about it. Consequently we shall see how we can refer to this pointer without ever bothering to know its actual value. After all if my program is compiled after somebody else's program the starting address could be 20,000. Tomorrow I recompile it the starting address could be 5000. It is not as if the computer's memory is perpetually reserved for me. Any program which is executing will occupy memory as we shall see later on. Memory is dynamically allocated. So the base address or the starting address could always change. What is important is once the base address is fixed base address plus 4 is this that plus 4 is this and therefore we leave it to C++ compiler as to what is the actual value of such addresses. Suffice it to say all that we want is ability to refer to an address value as a pointer and pass on that pointer to some function or some part of the code in my program. So that I can refer to a value via the pointer rather than referring to it by M or N alone. That continues to be feasible. This value is always represented by M or N or A0 but it is additionally represented by an address which we shall call the pointer. In the same way let me describe two useful data types which are supported by C++ each occupies one byte. One is called bool which stands for boolean and the other is called char which is different from string. Char is a variable which contains a single byte one byte only. The type bool is used to represent the truth value of our comparison. So logical comparison remember which results into true or false. Now these true or false can be kept as a value of a different data type called the boolean data type or bool. So if I define bool answer one, answer two and then I will say int x equal to 25 some arbitrary initialization. Suppose I say answer one equal to true please note that answer one or answer two once it is defined of the type bool then it can have only one of the two values true or false the plain words t r u e f a l s e these are not arbitrary words of your choice these are reserved keywords of C++ so they mean true or false in the comparison sense so true is the value assigned for this. I can assign a value answer two equal to x less than 25 ordinarily such an assignment would not make sense because x less than 25 is a question which we will ask in the statement or wide statement but apparently a question can be asked as a part of the expression C++ evaluates that expression to a value true or false in this particular case x is equal to 25 so obviously x less than 25 will result in false consequently answer two will become false answer one is forcibly assigned a value true at any point in time in my program I say if answer one something something why answer two something something so wherever a boolean value is expected to arise in a condition checking I can use a boolean variable with either a pre-assigned value or recomputed value in short a boolean value is a natural and acceptable result of any expression evaluation it will be true or false and this is represented by zero or non-zero values that we shall see later the character that you see on your terminal or keyboard again has a unique representation it is represented by an internal code typically you use ASCII codes these ASCII codes are available on internet on most of the textbooks as I said Kuhun's book at the end the first appendix gives you ASCII codes which are 8-bit codes for all numbers represented in decimal the 8-bit codes for typical letters of this small a has a code value of 97 small z has a code value of 122 you can conclude that small b will have a code value of 98 small c will have a code value of 99 etc because b is greater than a, c is greater than b and so on and z is greater than y so a to z all values are numerically aligned similarly capital a to capital z is in the range 65 to 90 you remember the new line character that you write which you write as backslash n that has a value representation of 10 a blank space is represented by 32 these are numerical values notice that all these values are between 0 to 255 because ASCII code is less than 8-bit so an 8-bit byte is sufficient to store a character now one can declare variables in a program of the type care for example you can say care later 1 just like you say int y or float x you can say care later 1 care later 2 note however that this is not a string please note when you define a string the assignment use a string within double a first profit a care variable always has a single character as a value and it is always written in single apostrophe single quotation mark so later 2 equal to y is a correct representation later 2 equal to double quote y double quote is not correct that is a string that is not a character value of course there are some rules by which some conversions will happen automatically so please note that the strings that we used where a different kind of items all together there are not variables really there are objects there are instances of an object class called string but in terms of the variables like integer float or whatever what we have are the characters now using these characters can we make strings the answer is yes and traditionally cc++ strings have been made out of such things only so far we have used the type string for example we say string student name is equal to let's say Rajesh Mashruwala you all remember this kind of assignment this is a string in the c++ string object sense so actually string represents a class of objects and not just a simple data type there is nothing like a simple data type in string of string in c and therefore in classical c++ only when you have a natural data type that you can define operators on it notice that when we said string is a class we define concatenation of string by saying str1 plus str2 and so on in natural way in which strings have been represented in c of the traditional way is to use a cal array that means you use an array of 60, 70, 100, 200 2000 elements in which you stuff consecutive characters of a string and say that is my string this is an artificial representation and there is an additional artificiality when you put such characters in an array of correct cards then to indicate that my string has ended because the name for example Rajesh Mashruwala has 17 characters including this blank Deepak Phatak will have different number some other name will have different character how do you indicate that a string has ended so in the artificial mechanism a string would be ended by pushing a backslash 0 value in the location immediately after the last character so suppose Rajesh Mashruwala has 17 characters actual positions occupied in that array will be 18 positions and the last position will contain a backslash 0 this is completely artificial this is not how any common sense string representation will happen but this is how c programming did c string representation and this is how the c++ continues to represent strings so apart from the object to a string about which we shall see later there is a basic way of representing character string and in this lab you shall be using character strings to handle some of the data so character strings as in character arrays here are some additional aspects about this suppose char sname 60 please note as I said this can hold 59 characters of a string only because an additional character is required to hold backslash 0 backslash 0 is called null and therefore these strings are called null terminated strings there are special representations in cc++ in short you define a character array just like int array or float array you define char array char sname 60 means effectively I am going to use this sname array to store a string which may contain at most 59 characters s0 to s58 s59 which is the 60th element will contain backslash 0 in case the array has less than 59 characters then I will put the backslash 0 immediately after the last character that means I will know if I start looking at this array right from the beginning the moment I see backslash 0 I know my string has terminated there although the array might have more number of elements left so we cannot now say sname equal to rajesh muswala please understand this this is illegal because sname is not string sname is an array and an array cannot be defined as single value like that each element has to be assigned a different value so each location has to be assigned a value for example sname 0 is R sname 1 is E etc sname 17 is backslash 0 because rajesh muswala has 16 characters such strings are called null terminated strings highly artificial representation however extremely concise representation a fairly clever representation and a large number of ready made functions to operate upon such representation is what is available however please note that C++ does not bother about array overflow so if you have an index let's say sname i now if i becomes 500 and your array is declared as sname 60 tough luck something else gets chewed up in your program so that is your responsibility as usual but since a string stored in this fashion is not a predefined data type normal operations cannot be performed even for normal operations i will have to write programs consider this program which will find the length of string stored in sname please note that we could find the length of the string in a string type of object by putting that object not something as a function reference to that object but in this case we will have to write functions in the conventional sense here is the way you will calculate length start with length equal to 0 assume that sname has the necessary value for i equal to 0 to sname not equal to backslash 0 keep modifying i++ please notice that you are not doing any action here you are merely looking at each and every character stored in the sname array sname 0, sname 1, sname 2, sname 3 you don't want to bother about that character is you have to find out you have to count the number of characters up to backslash 0 so the fall condition terminates when this you find the backslash 0 and you will come out of it when you come out whatever is the value of i is the length of the string because the last element will contain backslash 0 in decimal number that will be the length of the string because the actual occupation starts from 0th element please note however that suppose there is no valid string in that array and there is no backslash 0 then this will become an infinite loop going over the entire memory of the computer again and again and again because there is no other way to stop this so please understand the responsibility that you need to follow when you use such things I have listed in these slides important functions from C string library so if you just say hash include C string all these functions will get included some of the functions are string copy for example if you say s1, s2 s2 is copied into s1 you can't say s1 equal to s2 by the way in object class string you could say string 1 equal to string 2 but when you are s1 and s2 as such artificial arrays you say string copy another copy exists called string n copy where you give a count so that means only those many characters of s2 are copied into s1 there is a string cat or concatenation this is basically saying that s1 is equal to s1 plus s2 and you have string n cat where it is s1 equal to s1 plus first count characters of s2 so this is partial concatenation strl s1 it returns the length of s1 this is exactly the function that we just saw strcmp it lexicographically compares strings s1 and s2 remember in a program we wrote str1 greater than str2 directly that is because such string comparisons of objects could be done because objects know how to handle it but I can't compare two arrays whether one array is greater than another array or not but when I have used this special mechanism to represent strings as null terminated character array then I can use this function which will compare s1 and s2 in lexicographic sense and it will return a negative number if s1 is less than s2 it will return a zero if s1 is equal to s2 and positive other one so I can actually make string comparisons str str is actually searching or string within another string so let's say s1 is abraka dabraka and s2 is ra so abraka dabraka I will find two arrays there essentially this will return a pointer to the first occurrence of the second string in that array similarly strchr looks searches for a single character instead of the complete array s2 the complete string s2 main copy, copies count characters from s2 into s1 this you can actually go to the c++ help online and find out all of these there are several functions which examine or change a single character these are also extremely important functions for example you are looking at a line of text that you have input consider the compiler itself which is reading your program the program is nothing but a series of alphabets opening bracket, closing bracket, opening brass, less than, comma, semi-colon all these symbols are going somebody has to make sense out of it you can write programs to make sense out of such text provided you can look at every character and do something meaningful these are usually useful functions for looking at such things for example is all number or is alpha these will check you give a character as a parameter to it it will check whether that parameter is between a to z capital or small to check whether it is alpha if it is a control character, control a, control b if it is digit 0 to 9 is it graphical, graphical means any printable character is it lowercase, is it uppercase is it a punctuation mark is it a full stop, comma, exclamation all those are automatically checked e space, this does not check for blank space that is silly because blank space can be compared this stands for white space so you know if you have a stream of characters coming in on your CIL then you can examine each character and if you check whether e space then it will match with any blank space it will match with any new line character any tab all of these which are known as white spaces this will be matched there are innumerable additional functions which you can use meaningfully I leave it to you to look at these possibilities and do the lab assignment this will be the last assignment today just one announcement we will skip the location I am looking at the pointers and the references later I hope you have formed teams of 4 members already any people who have not formed teams yet can you raise your hands okay you got up to Wednesday if you remember correctly to finalize your teams and the team names and the team leader names must be intimated I must have this consolidated list because I am planning a meeting of all team leaders and batch coordinators if you recall batch coordinators are individuals who are chosen by the 5 team leaders from amongst themselves so each lab batch has 5 teams each lab batch must have 5 teams by the way if some lab batch has less than 5 teams because there are fewer students and 5 students have compiled together then they must recompile them and break them into 3 students teams but each lab group must have 5 teams make sure that you do that and all the leaders so each team will have 1 leader since there are 5 teams per lab group and there are 40 lab groups there will be exactly 200 leaders I want exactly 200 people in the FC Koli auditorium on Sunday in case a particular leader of a team is unable to come the leader may request any other member of the team to come but under no circumstances there should be more than 1 member from any team because the space there is limited we shall be discussing on Sunday morning from 10 to 12 briefly the 4 projects which have to be done and immediately between 12 to 1230 the 5 team leaders of every batch have to get together there itself on the spot discuss for 5 minutes and fill up a form for the priority of the lab that they would like this to be first choice this to be second choice this to be third choice this to be fourth choice what I guarantee is that every lab batch will get at least one of the 4 choices that is trivially true ok we will meet on Thursday thank you