# The Basics of C --- CS 130 // 2022-11-17 # C Progams ## An Example ```c #include "stdio.h" int main() { char name[20]; int age; printf("Hi! What is your name?\n"); scanf("%s", name); printf("Hello, %s, it is nice to meet you!\n", name); printf("What is your age?\n"); scanf("%d", &age); printf("Wow, %d is pretty old!\n", age); return 0; } ``` ```py # Python equivalent name = input("Hi! What is your name?\n") print("Hello,", name, "it is nice to meet you!") age = int(input("What is your age?\n")) print("Wow,", age, "is pretty old!") ``` ## First things to notice - **Python:** tab indicates code block - **C:** `{ }` indicates code block - white space doesn't matter - tabs are just for readability - **C:** all code needs to be in a function, `main` is executed first - **C:** most statements end with a semicolon `;` ## Variables and Types - In C, the **type** of a variable must be declared before it is first used ```c int x = 3 + 4; // Must give a type the first time ... x = x + 1; ``` ## Variables and Types - Integers ```c int x = 5; // usually 32-bits long y = -13; // usually 64-bits short z = 7; // usually 16-bits unsigned int u = 7; // makes number interpreted as positive ``` - Floating point ```c float f = 3.14; // usually 32-bits double d = -7.123; // usually 64-bits ``` ## Variables and Types - Character ```c char c = 'a'; // usually 8-bits ``` - No Boolean type---uses `int` instead + `0` means false + Any other `int` is true ## Comments - Uses `/* ... */` for multi-line comments - Uses `// ...` for single-line comments ```c /* This is a comment that spans multiple lines. Everything in-between is ignored */ int x = 10; // This is a single line comment. x = x + 5; // Everything after it is ignored. ``` ## Operators - C uses symbols `||`, `&&`, and `!` for Boolean expressions instead of `and`, `or`, and `not` ```py # Python code result = ((a > 0 or b > 0) and (c > 0)) == False ``` ```c int result = ((a > 0 || b > 0) && c > 0) == 0; ``` ## Operators - `a / b` behaves differently in C + Does **integer division** if both are integral + Does **floating point division** if one or both are floating point ## For Loops - In C, the `for` loop means something else entirely - The following two code blocks are equivalent ```c for (init; test; update) { body } ``` ```c init while (test) { body update } ``` ## For Loops - A common use is to iterate through an array ```c int arr[5] = {7, 3, 1, 2, 10}; for (int i = 0; i < 5; i++) { printf("The next value is: %d\n", arr[i]); } ``` ```py #Python code arr = [7, 3, 1, 2, 10] for i in range(10): print("The next value is:", arr[i]) ``` ## Arrays - Fixed size---they cannot be made smaller or larger - No way to check its size after creation - No index out of bounds checks ```c int arr[50]; // creates an array with 50 spots int val = arr[60]; // will happily try to do this printf("%d", val); ``` **Exercise:** put this in a file (and main function) and run - your compiler *may* give you a warning - you will still be able to run it ## Functions ```c #include "stdio.h" void swap(int v[], int k) { int temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; } void sort (int v[], int n) { for (int i = 0; i < n; i++) { for (int j = i - 1; j >= 0 && v[j] > v[j + 1]; j--) { swap(v, j); } } } int main() { int arr[5] = {7, 3, 1, 2, 10}; sort(arr,5); for (int i = 0; i < 5; i++) { printf("The next value is: %d\n", arr[i]); } } ``` # Exercises ## Exercise 1 - Write a program that asks the users to type in four numbers and prints the average of those four numbers ## Exercise 2 - Create a function `void reverse(int arr[], int n)` that takes an array with `n` elements and reverses the order of the elements - Test it out in a `main` function such as: ```c int main() { int arr[5] = {1, 2, 3, 4, 5}; reverse(arr, 5); for (int i = 0; i < 5; i++) { printf("The next value is: %d\n", arr[i]); } return 0; } ``` # Strings ## Strings - There is no **String** type in C - Strings are just arrays of type `char` ```c char str[20] = "abc"; printf("The string is %s", str); ``` - The above code is shorthand for the following: ```c char str[20]; str[0] = 'a'; str[1] = 'b'; str[2] = 'c'; str[3] = '\0'; // String terminating character ``` - The remaining 16 characters are unused ## Strings - Suppose we forget to include the `'\0'` character ```c char str[20]; str[0] = 'a'; str[1] = 'b'; str[2] = 'c'; printf("The string is %s", str); ``` - What do you think happens? - `printf` continues printing characters until it finds some random `'\0'` character in memory ## Strings - Very simple string operations now become complicated... - Suppose I want to concatenate two strings: ```c char s1[20] = "hello"; char s2[20] = "world"; char s3[20] = ??? // how do I concatenate s1 and s2? ``` - Manually copy all the characters into `s3`... ## Strings ```c char s1[20] = "hello"; char s2[20] = "world"; char s3[20]; int j = 0; // keeps track of the next spot in s3 for (int i = 0; s1[i] != '\0'; i++) { s3[j] = s1[i]; j++; } for (int i = 0; s2[i] != '\0'; i++) { s3[j] = s2[i]; j++; } s3[j] = '\0'; ``` ## Strings - Luckily, there is a `string.h` library with a few helpful functions that does some of this for us, but they just do the same thing as above ```c #include
char s1[20] = "hello"; char s2[20] = "world"; strcat(s1, s2); printf("The new string is: %s", s1); ``` ## Strings - Here is a common issue: ```c char s[3] = "abc"; int x = 10; printf("The values are %s and %d", s, x); ``` - We did not allocate enough space in `s` to store the string termination character `'\0'` ```c char s[4] = "abc"; int x = 10; printf("The values are %s and %d", s, x); ``` # Pointers ## Address-of Operator Try this out and discuss what you think is going on ```c #include "stdio.h" int main() { int var = 0; int arr[3] = {1,2,3}; printf("Address of var: %p\n", &var); printf("Address of arr[0]: %p\n", &arr[0]); printf("Address of arr[1]: %p\n", &arr[1]); printf("Address of arr[2]: %p\n", &arr[2]); } ``` ## Arrays are addresses ```c #include "stdio.h" int main() { int var = 0; int arr[3] = {1,2,3}; printf("Address of var: %p\n", &var); printf("Address of arr[0]: %p\n", arr); printf("Address of arr[1]: %p\n", arr+1); //does this add 1 or 4? printf("Address of arr[2]: %p\n", arr+2); } ``` ## Address vs. Pointer * A **pointer** is a variable that contains an address of some other thing in memory * Arrays *are* pointers in C ## Pointers - One of the most powerful features of C is declaring "pointers" to values - A **pointer** is a variable whose value is the address of a memory location - To declare a variable as a pointer, you use a `*` before the variable name: ```c int *p; // p contains an address to an int ``` ## Pointers - To get the memory address of a variable, we use `&`, the address operator ```c int x = 5; printf("Address of x is: %p\n", &x); int *p = &x; // p is pointing to x's memory location ``` - To access the value a pointer is "pointing to", you can **dereference** it using the `*` operator ```c int y = *p; // gets the int p is pointing to printf("p was pointing to %d\n", y); ``` ## Arrays are Pointers - In C, arrays are just **pointers** ```c int arr[10]; // arr is a pointer to the address of the // first element of the array ``` - You can use array notation on pointers and pointer notation on arrays ```c int *p = arr; // p points to what arr is pointing to p[0] = 100; // changes arr[0] to be 100 int x = *arr; // gets 100 back ``` ## Exercise 3 - Suppose we want to write a function that computes the average of a bunch of `double` values - What would the prototype of this function be? ```c double average(double arr[], int n) ``` - Finish writing the function # `printf` # `scanf` ## Exercise 4 - Write a program that asks the user to enter in 10 doubles, computes the average, and prints it off - Use an array and a loop to get input from the user - Use the `average` function to compute the average ## Exercise 5 - How can we modify this program so that the user can enter **any** number of inputs?