---
tags: CS50’s Introduction to CS
---
# Week 2
## More Details of the Compiler
1. The First Step: Source Code

2. The Second Step: Assembly Code

3. The Third Step: Machine Code

## Array
1. Definition: An array is a data structure containing a number of data values, all of which have the same type.
2. Declaration & Initializatio:
1. To declare an array, we must specify the type of the array's elements and the number of elements:
```c
int a[10];
```
* ※Using a macro to define the length of an array is an excellent practice:
```c
#define N 10
...
int a[N];
```
2. To initialize an array, we need to write the elements inside a pair curly brackets.
```c
int a[10]={1,2,3};
```
If the initializer is shorter than the array, the remaining elements of the array are given the value 0.
3. If the initializer is present, the length of the array may be omitted.
```c
int a[]={0};
```
4. C99's designated initializer:
```c
int a[]={[2]=29,[10]=25};
```
5. Variable-Length Arrays: In C99 the length of an array can be put variables. But notice that VLAs can't have an initializer and static storage duration.
6. Using const in definition can make the elements unable to change.
3. Subscripting:
1. The elements of an array of length n are indexed from 0 to n-1.
2. a[i] is a lvalue.
3. If a subscript goes out of range, the program's behavior is undefined.
4. Using sizeof() with Arrays
1. sizeof() can determine the size of an array in bytes.
2. sizeof(a)/sizeof(a[0]) can get the length of the array.
5. Multidimensional Arrays:
1. To declare a multidimensional array, we need to write extra brackets:
```c
int a[1][1];
```
2. To initialize a multidimensional arry, we need to write nested one-dimension arrays:
```c
int a[2][2]={{1,1},{1,1}};
```
Notice that only the first value in the brackets can be omitted.
## String
1. Definition: A string is an array of characters with '\0' as its end.
2. String Literals:
1. Definition: A sequence of characters enclosed within double quotes.
2. How to Create a String Literal: Double quote a sequence of characters.
* ※A sequence of characters inside double quotes is represented by a pointer, while a character inside single quotes is reprsented by an interger.
4. Continuing a String Literal:
1. The backslash character can be used to continue a string literal from one line to the next.
```c
printf("abcdef\
ghi");
```
2. When two or more string literals are adjacent, the compiler will join them into a single string.
```c
printf("abcdef""ghi");
```
4. How String Literals Are Stroed:
1. When a C compiler encounters a string literal of length n, it sets aside n+1 bytes if memory for the string.
2. Since a string literal is stroed as an array, the compiler treats it as a pointer of type char *.
5. Operations on String Literals: A string literal is constant which means it can't be modified.
3. String Variables:
1. Declaration:
```c
char s1[6];
char *s2;
```
2. Initializing a String Variable:
1. How to Initializing a String Variable:
1. char s1[6]={'H','e','l','l','o','\0'};
2. char s2[6]="Hello";
3. char *s3 = "Hello";
2. If the initializer is too short, the compiler adds extra null characters.
3. The declaration of a string variable may omit its length.
3. Array Version and Pointer Version:
```c
char s1[6]="Hello";
char *s2="Hello";
```
1. In the array version, the characters stored in the string cabe modified, while in the pointer version, the pointer points to a string literal which means it can't me modified.
2. In the array version, s1 is an array name, while in the pointer version, s2 is a variable that can point to other string.
* ※To make a pointer point to a string variable, we need to create a string variable by an array, and make the pointer point to the string variabel.
* ※Using an uninitialized pointer variable as a string is a serious error.
4. Reading and Writing Strings
1. Writing Strings
1. printf():
1. The Conversion Specification:
1. %s allows printf to write a string.
2. %m.ps:
1. %.ps: pis the number of characters to be displayed.
2. %ms: %ms will display a string in a field of size m. If the string has fewer than m characters, it will be right-justified within the field. To force left justification instead, we can put a minus sign in front of m.
2. printf writes the characters in a string one by one until it encounters a null character.
2. puts():
```c
puts(str);
```
After writing a string, puts always writes an additional new-line character.
2. Reading strings
1. scanf():
1. %s allows scanf to read a string into a character array.
2. When scanf is called, it skips white space, then reads characters and stores them in str until it encounters a white-space character or a new-line character.
3. scanf always stores a null character at the end of the string.
2. gets():
```c
gets(str);
```
1. It doesn't skip white space before starting to read input.
2. It reads until it finds a new-line character.
3. It discards the new-line character instead of storing it, and the null character takes its place.
* ※scanf() and gets() have no way to detect when it's full, so they may store characters past the end of the array, causing undefined behavior.
3. fgets():
```c
char *fgets(char *str,int n,FILE *stream)
```
1. str: The address that the input stores in.
2. n: The maximum characters that can be stored.
3. stream: The file address where the input is from.
* ※stdin means the input is typed by the user.
4. Programmers Often Write Their Own Input Function
1. Issues to consiter:
1. Should the function skip white space before beginning to store the string?
2. What character causes the function to stop reading?
3. What should the function do if the input string is too long to store?
2. Example:
Suppose we need a function that
1. doesn't skip white-space characters,
2. stops reading at the first new-line characters, and
3. discards extra characters.
```c
int read_line(char str[],int n)
{
int ch, i=0;
while((ch=getchar()!='\n'))
if(i<n)
str[i++]=ch;
str[i]='\0';
return i;
}
```
5. Using the C String Library
1. Illegal Operation in C
1. Copting a string into a character array using the = operator is illegal.
2. Attempting to compare strings using a relational or equality operator is legal but won't produce the desired result.
2. Functions:
1. strcpy & strncpy
```c
char *strcpy(char *dest, const char *src);
char * strncpy(char *dest, const char *src, size_t n);
```
1. A call of strcpy that stores src in dest;
2. strcpy won't check that src fit in the array pointed to by dest, if it doesn't, undefined behavior occurs.
3. strncpy has a third argument that limits the number of characters that will be copied, so calling strncpy is safer, albeit slower.
4. strncpy will leave str1 without a null character if the length of src is greater than or equal to the size of dest.
5. A safer way to use strncpy:
```c
strncpy(str1,str2,sizeof(str1)-1);
str1[sizeof(str1)-1]='\0'
```
2. strlen:
```c
size_t strlen(const char *s);
```
1. size_t is a typedef name that represents one of C's unsigned integer types.
2. strlen returns the length of a string s, not including the null character.
3. strcat & strncat:
```c
char *strcat(char *s1, const char *s2);
char *strcat(char *s1, const char *s2, size_t n);
```
1. strcat appends the contents of the string s2 to the end of the string s1.
2. It return s1(pointer).
3. strcat(str1,str2) causes undefined behavior if the str1 isn's long enough to accommodate the characters from str2.
4. strncpy has a third argument that limits the number of characters that will be copied, so calling strncpy is safer, albeit slower.
5. strncat will terminate s1 with a null character, which isn't included in the third argument.
4. strcmp:
```c
int strcmp(const char *s1, const char *s2);
```
1. strcmp compares the strings s1 and s2, returning a velue less than, equal to, or greater than s2.
If the return value
1. is less than 0, then s1 < s2.
2. equals to 0, then s1 = s2.
3. is more than 0, then s1 > s2.
3. As it compares two strings, strcmp looks at the numerical code for the characters in the strings.
6. Arrays of Strings:
```c
char str[][8]={...};
char *str[]={...};
```
1. The number of rows in the array can be omitted, but we must specify the number of columns.
7. Command-Line Arguments
1. Introductions: When we run a program, we'll often need to supply it with information. This may include a file name or a switch that modifies the program's behavior
2. How to Obtain Access to Command-Line Arguments:
```c
int main(int argc, char *argv[])
{
...
}
```
1. argc: The number of command line arguments.
2. argv: An array of pointers to the command-line arguments.
1. argv[0] points to the name of the program.
2. argv[1] through argv[argc-1] point ti the remaining command-line argument.
3. argv[argc] is always a null pointer-a special point that points to nothing.
3. Typically, a program that expects command-line arguments will set up a loop that examines each argument in turn.
```c
int i;
for(i=1;i<argc;i++)
printf("%s\n",argv[i]);
```