Presentation is loading. Please wait.

Presentation is loading. Please wait.

Strings, Line-by-line I/O, Functions, Call-by-Reference, Call-by-Value

Similar presentations


Presentation on theme: "Strings, Line-by-line I/O, Functions, Call-by-Reference, Call-by-Value"— Presentation transcript:

1 Strings, Line-by-line I/O, Functions, Call-by-Reference, Call-by-Value
CS 240 – Lecture 4 Strings, Line-by-line I/O, Functions, Call-by-Reference, Call-by-Value

2 C Strings – In Memory In C, a String isn't a native data type to the language. Instead, it is an abstraction placed over memory. Any sequence of characters in memory that ends in a '\0' or "null byte" is a valid C String. If housed in a variable, usually called a buffer, the string is only the part up to and including the '\0'. Address Value Variable 0x82ff6f80 'H' buffer[0] 0x82ff6f81 'i' buffer[1] 0x82ff6f82 '\0' buffer[2] 0x82ff6f83 *junk* buffer[3] 0x82ff6f84 buffer[4] 0x82ff6f85 buffer[5] 0x82ff6f86

3 C Strings – String Literals
To contain a C string, the most appropriate variable types are char* and char[] To indicate a string literal value, use the double-quote (") notation. char *buffer = "Hello World!"; char buffer[] = "Good Night!"; Be aware that on certain graphical text editors, the quotes are sometimes replaced with special oriented quote characters (“). Use ASCII double-quotes or the compiler will fail to recognize them. The difference between char* and char[] is that char[] variables can only be assigned when they are declared.

4 C Strings - Values Since strings are an abstraction over memory, passing string values around is different from other data types. String values are indicated by the address of their first character. This inherently makes them a char* value. String literals stored in char* variables are stored in the read-only data section of program memory. In a char[] variable, the program copies the string into editable memory allocated for the char[] variable. Print string values with printf("%s", str); Address Value 0x82ff6f80 *junk* 0x82ff6f81 'H' 0x82ff6f82 'i' 0x82ff6f83 '\0' 0x82ff6f84 0x82ff6f85 0x82ff6f86

5 C Strings – strlen function
Address Value 0x82ff6f80 *junk* 0x82ff6f81 'H' 0x82ff6f82 'i' 0x82ff6f83 '\0' 0x82ff6f84 0x82ff6f85 0x82ff6f86 To find the length of a string, it's equivalent to doing a search for the index of the null byte. In this case, we can use the strlen function which does just this. char *buff = … ; int length = strlen(buff); If buff was where "Hi" was in memory, then length would be 2.

6 Line-by-line I/O Many applications call for reading bulk content to be processed as a whole. For these types of applications, getting one character of input at a time is not helpful. For such applications, reading input line-by-line is far more meaningful and useful. The stdio.h has a number of options, but we're going to first talk about the one you're most likely be able to use on any system. fgets(buffer, maxlength, stream);

7 Line-by-line I/O – fgets, File Get String
The fgets function takes three arguments, the buffer, the maxlength, and the stream. fgets(buffer, maxlength, stream); The buffer is an array variable big enough to hold maxlength characters. The function will stop reading input after maxlength characters even if there are more. The stream is used to indicate the source; we'll talk more about this later. For now, use stdin for console input. Example usage: char buff[100]; fgets(buff, 100, stdin); printf("%s", buff);

8 Functions – Definition
To define a function, you need a number of things A return type A function name Function arguments (or empty parenthesis) A function body, a block statement to be run Any run of this function SHOULD have execute a return statement of the function's type. type name(type1 name1, …) { /* function body */ return value; }

9 Functions – Definition
Here is the standard definition for the two-value max function: int max(int a, int b) { if (a > b) return a; else return b; } This function return the larger of the two values given as arguments. int a = max(2, 6); /* a == 6 */

10 Functions – Call-by-value
When you call a function with variables as arguments, the function gets a copy of the values in those variables. It does not get access to the variables themselves. For example, int a = 2; int b = 3; int c = func(a, b); The function func is not able to make changes to the a and b variables outside of the function call. The memory addresses of variables a and b are unknown to func so it can't change them.

11 Functions – Call-by-reference
fgets and many other functions in the C programming language do something interesting that not many other languages do. fgets(buff, 100, stdin); As you may have noticed, fgets places a string value in buff even though it's return value wasn't stored there. This is because buff is an address to where fgets should store the string. This is called call-by-reference, when a function accepts an address rather than a normal value. This allows a function to cause "side-effects", changes to memory outside of the variables declared inside.

12 Functions – void type Some functions can be defined to be of type void. This indicates that they don't intend to return a variable and are only used for their side-effects. Example: void sayhello() { printf("Hello!\n"); } A void function without side-effects is a waste of time since it does nothing in the long-run.

13 Functions – swap function
void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } This function swaps the int values between to addresses in memory. void swap(int a, int b) { int temp = a; a = b; b = temp; } This function does nothing, since it is call-by-value and has no side-effects.

14 Review of char and int types
char type 8 bits, 1 byte Example: int type 32 bits, 4 bytes '\x5d' 93 ']' 0x6ace9718

15 Review on Numeric Literals
signed char literals Example: Will be treated as a value of type signed char signed int literals Will be treated as a value of type signed int '\x##' 0x########

16 Explicit Casting Casting is the act of converting an r-value from one type to another. In most cases, this results in a change in bit-length of the value. Example: In memory: Another example: Note, large  small drops bits char c = '\x55'; int i = (int) c; int i = 0x7fff9876; char c = (char) i;

17 Implicit Casting Just like Explicit Casting, but doesn't use the (type) operator. Example: The value of variable c must be converted to type (int) before arithmetic can be done between it and the value of variable i. char c = 100; int i = 100; printf("%d\n", c * i);

18 Negative Numbers To describe negative numbers, we need to make use of a property of binary arithmetic. Let's do this by first defining our first negative number: -1 Negative one (-1) is the number to which adding one (+1) will give us zero (0) There is only one such number: Note, adding +1 to that number actually gives us but we can't retain the carry. XXXX XXXX

19 One's Complement So, to define negative numbers in general, we need a few steps. First, we'll define the One's Complement operator (~): For any number, take it's binary representation and flip/toggle each bit. Examples: ~ ~ ~0x 0xbeefface ~0x 0xcafebabe

20 Two's Complement Using the One's Complement (~) we can define the Two's Complement as something we're familiar with: The Negative operator (–) The Two's Complement is equivalent to the One's Complement Plus One. Example: ~ = -87 = 87 ~ a9 56 56 + 01 57 \xa9 = -87 \x57 = 87

21 Fast One's Complement in Hex
Due to the fact that hex digits are just groups of four binary digits, we can perform One's Complement on them as a grouping. To perform One's Complement this way, switch hex digits (groups of 4 bits) horizontally. f 1 e 2 d 3 c 4 b 5 a 6 9 7 8 0000 1111 0001 1110 0010 1101 0011 1100 0100 1011 0101 1010 0110 1001 0111 1000

22 Casting Revisited (with Negative Numbers)
Now that we know how to represent negative numbers, there's an important behavior to describe in casting. The left-most bit of a numeric type is the Most Significant Bit (MSB) This bit corresponds to the sign of a number (positive or negative, +/–) When casting from a smaller signed type to a larger signed type, the sign expands across all added bits. Example: (int) 1 1 Note: This still corresponds to the same negative number!


Download ppt "Strings, Line-by-line I/O, Functions, Call-by-Reference, Call-by-Value"

Similar presentations


Ads by Google