Week 2
Lecture 2
Compiling
Last time when when we ran make hello to compile hello.c, make is actually just a program that calls clang, a compiler named for the “C language”.
We can compile our source code, hello.c, directly by running the command clang hello.c in the terminal. This procudes a file a.out*, which stands for assembler output, the conventional, default file name for any program compiled directly with a computer. Run the file with ./a.out.
Adding command-line argument
clang -o hello hello.c
hello is the output filename, hello.c is the source code, -o means output
When the file uses CS50.h library
clang -o hello hello.c -lcs50
lcs50 tell the compiler to actually link in the cs50 machine code with the functions described by cs50.h
Four steps in compiling
-
preprocessing: replacing lines that start with a
#.clangwill copy and paste the contents of those header files (like prototypes of functions) into our program.//before #include <cs50.h> #include <stdio.h> //after ... string get_string(string prompt); ... int printf(string format, ...); ... -
compiling: converting our source code to assembly language
-
assembling: take the code in assembly and translate it to binary by assembling it. The instructions in binary are machine code, which a computer’s CPU can run directly
-
linking: combine all the machine code, including the compiled binary of our program and the previously compiled versions of libraries
Arrays
Basic syntax:
// individual element syntax
type name[size];
name[0] = value0;
name[1] = value1;
name[2] = value2;
...
// instantiation syntax
type name[size] = {value0, value1, value2,...};
// with instantiation syntax, the size can be omitted
type name[] = {value0, value1, value2,...};
While we can treat individual elements of arrays as variables, we cannot treat entire arrays themselves as variables. We cannot, for instance, assign one array to another using the assignment operator. Instead, we must use a loop to copy over the elements one at a time.
Note: Arrays are not passed by value in function calls. Rather, they are passed by reference. The callee receives the actual array, not a copy of it.
Chars
printf can print chars as integers, since each character is really stored as an ASCII value with zeroes and ones.
Strings
Strings are actually arrays of characters. In C, strings end with a special character, \0, or a byte with all eight bits set to 0, so our programs have a way of knowing where the string ends. This character is called the null character, or NUL. So, we actually need four bytes to store our string with three characters.
C's String Library
the function strlen in string library can be used to get the length of the string
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string s = get_string("Input: ");
printf("Output: \n");
for (int i = 0, n = strlen(s); i < n; i++)
{
printf("%c\n", s[i]);
}
}
Note: At the start of for loop, we can initialize more than one variables.
Use CS50's manual pages to find and learn about libraries and functions.
Command-line arguments
Basic syntax:
#include <stdio.h>
int main(int argc, string argv[])
{
...
}
argc: argument count, or number of arguments (words) typed in;argv[]: argument vector (or argument list), is an array of the arguments (words) themselves, and there’s no size specified since we don’t know how big that will be ahead of time. Every element stored in argv is a string.- The first argument,
argv[0],is the name of our program (the first word typed, like ./hello).
#include <cs50.h>
#include <stdio.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("missing command-line argument\n");
return 1;
}
printf("hello, %s\n", argv[1]);
return 0;
}
main function returns an integer value called an exit status. By default, our main function returns 0 to indicate nothing went wrong, while a non-zero exit status indicates some error to the system that runs our program. We don’t technically need to write return 0 explicitly at the end of our program since C will automatically return 0 for us.
Shorts
Functions
Function is a black box with a set of 0+ inputs and 1 output.
PAY ATTENTION TO WHERE THE INPUT_TYPE IS NEED AND WHERE IT'S NOT
// prototype, declare the function, need input_type reture_type function_name(input_type input_name); ... int main(void) { // call the function, dont' need input_type variable_type variable_name = function_name(input_name); } ... // define the function, same as prototype, but without semicolon reture_type function_name(input_type input_name) { ... }
Variables and Scope
Local variable: local variables in C are passed by value in function calls. when a variable is passed by value, the callee (the function that is receiving the variable) receives a copy of the passed variable, not the variable itself. That means that the variable in the caller (the function that is making the function call) is unchanged unless overwritten.
// no effect on foo
int main(void)
{
int foo = 4;
triple(foo);
printf("%i\n", foo);
}
int triple(int x)
{
return x *= 3;
}
Output: 4
// overwrites foo
int main(void)
{
int foo = 4;
foo = triple(foo);
printf("%i\n", foo);
}
int triple(int x)
{
return x *= 3;
}
Output: 12
Global variable: if we manipulate one variable in one function, the effect in that one function carries through to every other function.
float global = 4;
int main(void)
{
triple();
printf("%f\n", global);
}
void triple(void)
{
global *= 3;
}
Output: 12.000000
Lab 2
Note: isupper and islower function
These two functions are defined in <ctype.h> header file.
Syntax:
#include <ctype.h>
int isupper(char c);
This function returns a non-zero int if c is an uppercase letter and 0 if c is not an uppercase letter.
Pset 2
Caesar
Note 1:
How to convert a string to int
#include <stdlib.h>
int atoi(string s);
Note 2:
Check whether a character is alphabetic: isalpha
This function returns a non-zero int if c is alphabetical and 0 if c is not alphabetical.
Substitution
Note
How to test duplicate items in an array
// test duplicate characters
for (int m = 0; m < length; m++)
{
for (int n = m + 1; n < length; n++) // key point!
{
if (argv_2[m] == argv_2[n])
{
printf("No duplicate characters in key.\n");
return 1;
}
}
}