CS 46 Lecture Notes #
August 27 #
#include <stdio.h>
int main()
{
printf("I <3 C\n");
}
#include <stdio.h>
int main()
{
for (int i)
{
printf("I <3 C\n");
}
}
#include <stdio.h>
int main()
{
printf("Enter your agge: ");
int age;
scanf("%d", &age); // scanf is expecting a decimal (base 10), and stores it in age
int dogAge = age * 7;
printf("You are %d dog years old \n", dogAge);
}
To compile:
Type clang file.c
where file is the name of the file
This will make a new file, to run this program type ./.a.out
where a.out is the name of the file created
#include <stdio.h>
int main()
{
printf("Enter two numbers: ");
int a, b;
scanf("%d%d", &a, &b);
printf("Average of %d and %d is: %d", a, b, (a + b) / 2)
}
Differences between Java and C
#include
is kind of like import but not exactly- No classes
- Not OO
- No public/private
- String is not a type
Primitive data types
Java | C |
---|---|
boolean | no equiavlent, use int |
char | char is a byte |
int | int is defined as a int with as many bits as the machine its running on, most natural data type |
double | same |
float | same |
byte | Use char |
short | half the size of an int |
long | double the size of an int |
August 29 #
Data types and syntax #
Primitive types
Java | C |
---|---|
int | int |
double | double |
char | no equivalent |
boolean | int |
byte | char |
String | char[] |
float | float |
C has unsigned intger types:
unsigned int
unsigned char
unsigned long
Same as java: braces semicolons if..else for while
Operators: +, -, *, / &&, ||, !
Conditionals can be applied to ints
int x = 5;
if(x) // 0 is a false value, anything else is true
{
printf("whee");
}
int a = 10, b = 0;
if (a || b)
{
printf("whop!");
}
int c = 0;
printf("%d", !c); // this prints a 1
int z = 10;
while(z--)
{
printf("foo");
}
printf and scanf are the 2 primary tools for getting information from a user and showing them information
printf(______) format
%d
is a integer
%f
is a float
%s
is a string (char array)
%li
is long int
%u
is unsigned int
#include <stdio.h>
int main()
{
printf("int is %li bytes\n", sizeof(int));
}
#include <stdio.h>
int main()
{
int width, height, depth;
printf("Enter width: ");
scanf("%d", &width);
printf("Enter height: ");
scanf("%d", &height);
printf("Enter depth: ");
scanf("%d", &depth");
int volume = width * height * depth;
printf("Volume is: %d", volume);
}
In C the variables are not initialized, it defaults to whatever was in memory at the moment in time.
September 3rd #
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int max = 100;
// #define max 100
int main()
{
srandom(time(NULL)); // seeds random number generator from system's time
int num) % max + 1;
printf("I have picked a random number between 1 and %d.\n", max);
printf("Can you guess it? ");
int guess;
scanf("%d", &guess);
do
{
if (guess)
{
printf("You got it!.\n");
}
else if (guess < num)
{
printf("Too low.\n");
}
else
{
printf("Too high!\n");
}
}
while (guess != num);
}
Includes can be in angle brackets <> or quotes “”. Quotes look in the current directory and angle brackets look in the system’s directories. const
is a constant that can’t be changed. #define
is an older way to do it, (ex. #define max 100
), no data type or equals sign, anywhere it sees the label max it’ll replace it with 100. Anything that starts with a hash mark is called a pre-processor directive.
Compiling steps
- .c -> pre-processor
- Any #define just swaps the term with the value
- compilers, turns into assembly
- linker, hooks up everything
- executable
September 10th #
arduino.cc, download IDE
#define
#
An example of how to use #define
#define DEBUG
int sum = 0;
for (int i)
{
#ifdef DEBUG
printf("i);
#endif
sum = sum + i;
}
typedef
works kind of like define but for data types
Java:
int[] arr = new int[10];
C:
int arr[10];
Brackets for arrays go after variable name.
Segmentation fault (core dumped):
- Happens when your program attempts to go outside of your memory segment.
October 1 #
10 foot view of the computer #
Memory is just an array of bytes. Programs/data both reside in memory.
Address of variables can be accessed with an &
Address of a is &a
and b is &b
A variable c
that can hold the address of an int:
int a;
int b;
int *c; // this is the address of an integer, not the interger itself
c = &b; // puts the address of b into the variable c
October 3 #
Pointers #
int x; // x holds an int
float y; // y holds a float
int *a; // a holds the address of an int
float *z; // z holds the address of a float
&x; // address of x
&y; // address of y
a = &x; // a is set to address of x
z = &y; // z is set to address of y
You can’t put the address of y
into a
because of loss of precision
int j = 6; // 6 is checked to be an int before putting it into j
int *k = &j; // legal
The compiler checks the right hand side first, then the left side then checks if they are compatable. (Static analysis)
October 10 #
Valid pointers #
Thing | Name | Type |
---|---|---|
int xy; | xy | int |
double abc; | abc | double |
char mp; | mp | char |
int broom[10]; | broom | int array or int pointer |
marp blee; | blee | marp |
char *flam; | flam | char pointer |
marp bomaz[5]; | bomaz | marp array or marp pointer |
short int max; | max | short int |
marp **z; | z | pointer to pointer to a marp, marp pointer pointer, pointer to marp pointer |
double floof[2], *mop; | floof, mop | double array, double pointer |
marp *whop[20]; | whop | array of marp pointers |
// Valid?
broom[4] = xy; // Valid
floof[1] = &abc; // Invalid
max = broom[2]; // Valid, with warning
flam[8] = "1234"; // Invalid
z = &whop[0]; // Valid
*floof = 4.8; // Valid
blee = &bomaz[2]; // Invalid
mop = floof; // Valid
flam = "hello"; // Valid
mp = flam[5]; // Valid
mp = &flam[4]; // Invalid
whop[10] = *z; // Valid
blah[5] is equivalent to *(blah + 5)
// Valid ways of invoking these functions?
void feet(int x);
feep(xy)
feep(broom[0])
feep(max)
feep(*broom)
feep(*(broom + 9))
char gabi(marp c);
mp);
*flam);
flam[4]);
marp asdf(int *a, marp *m);
blee);
**z);
*&blee);
struct gps
{
double lat;
double long;
};
This makes a new struct called gps that has 2 doubles inside
typedef struct gps gps;
gps here;
here.lat = 38.5;
here.lon = -121.3;
Or all at once:
typdef struct gps
{
double lat;
double long;
} gps;
Memory allocation:
address)
, this puts the memory into dynamic memory
#include <stdlib.h>
int *x) is called
int *y); // Another way to figure out how much you need
October 15 #
Core dumps #
To debug a core dump:
First recompile program with -g
flag, then run gdb ./recover core
String example:
#include <stdio.h>
#include <string.h>
int main()
{
char str[40];
printf("Enter a string: ");
gets(str);
printf("Length is: %lu\n, strlen(str));
}
Compiler warns that gets()
is dangerous because it will continue over the 40 chars set aside. fgets()
takes three parameters, name of string, how long, and where to get input from. It will compensate for the null term at the end and also compensates for the new line char at the end of the string. This differs from scanf()
with a %s
because scanf will stop when it hits a space.
Our own length functions:
int length(char * s)
{
int count = 0;
while (s[count] != '\0') // Checks against null char
{
count++;
}
return count;
}
int length2(char *s)
{
int count = 0;
while(s[count]) // Implicitally compares to 0
{
count ++;
}
return count;
}
int length3(char *s)
{
int count = 0;
while(*(s+count)) // Pointer arithmetic
{
count++;
}
return count;
}
int length4(char *s)
{
int count = 0;
while(*s) // Dereference s and increment it
{
s++;
count++;
}
return count;
}
int length5(char *s)
{
int count = 0;
while(*s++) // Post increment
{
count++;
}
return count;
}
int length6(char *s)
{
char *t = s;
while(*++s); // Pre increment and return difference
return s - t;
}
int length7(char *s)
{
int count;
for(count);
return count;
}
October 17 #
Version Control Systems #
Git commands:
git init
initializes local repo
git config
configures user’s information
git add <filename>
marks a file to commit
git commit -m "commit message"
commit ready files with a message
October 22 #
Working with files in C #
Use #include <stdio.h>
to work with files. A file is just a sequence of bytes. It has a beginning and an end.
Files can be “unstructured” or “structured”
- Unstructured: text files
- Structured: CSX, executables, JPEG, video
Structured files can be “record oriented”
- Fixed-sized records
- Array of structs
The FILE
struct keeps track of things like:
- Name of file
- Permissions
- Where you are in the file
When you read from a file, you start from the beginning, the FILE
struct keeps track fo how far you have ready, so the next time you read it resumes where you left off.
Operations on a file:
- Open
FILE * fopen(char *, char *);
- filename, mode (“r”, “w”, “a”)
- Returns a FILE * or NULL if there was a problem
- Read
- Use functions like
fscanf
andfgets
fscanf(fp, "format", variables);
fgets(char *, length, fp);
- Use functions like
- Write
fprintf(fp, "format", variables);
- Close
fclose(fp);
For example:
#include <stdio.h>
int main()
{
FILE * fp; // file pointer
fp); // opens a file called "test" for read
if (fp)
{
// This means the file didn't open correctly
printf("Can't open file\n");
exit(1);
}
}
#include <stdio.h>
#include <stdlib.h> // For exit command
int main()
{
FILE * fp;
fp);
if (!fp)
{
printf("Could not open file!\n");
exit(1);
}
fprintf(fp, "hello\n"); // Write to file
fclose(fp); // Close file
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[]) // Main now accepts command line parameters
{
if (argc)
{
fprintf(stderr, "Please enter a filename after the command\n");
exit(2);
}
FILE * fp;
fp);
if (!fp)
{
fprintf(stderr, "Can't open %s\n", argv[1]);
exit(1);
}
char line[500];
int count = 1;
while(fgets(line, 500, fp); != NULL)
{
printf("%d %s", count, line);
count++;
}
fclose(fp);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char * argv[])
{
if (argc < 3)
{
fprintf(stderr, "You must supply a file name\n");
exit(1);
}
FILE *in, *out;
in);
if (!in)
{
fprintf(stderr, "Can't open %s for reading\n", argv[1]);
exit(2);
}
out)
if (!out)
{
fprintf("Can't open %s for writing\n", argv[2]);
}
char line[500];
while (fgets(line, 500, in) != NULL)
{
if (strcmp(line, "pizza\n"))
{
fprintf(out, "Nice! %s", line);
}
else
{
fprintf(out, "%s", line)
}
}
fclose(in);
fclose(out);
}
October 24 #
/*
A program to count the number of spaces
The filename is given on the command line
*/
#include <stdio.h>
#include <stdlib.h> // For exit()
#include <string.h> // For strlen()
#include <ctype.h> // For isupper()
int main(int argc, char * argv[])
{
// Check number of command line arguments
if (agc < 2)
{
fprintf(stderr, "You must supply a filename\n");
exit(1);
}
// Open file for reading
FILE * fp);
if (!fp)
{
fprintf(stderr, "Can't open %s for reading\n", argv[1]);
exit(2);
}
// Read line by line
char line[5000];
int space_count = 0;
int cap_count = 0;
while(fgets(line, 5000, fp) != NULL)
{
// For each line, go char by char
for (int i)
{
// If its a space count++
if (line[i]) space_count++;
// if (line[i] >= 'A' && line[i] <= 'Z') cap_count++;
if (isupper(line[i])) cap_count++;
}
}
// Close the file
fclose(fp);
// Print the counts
printf("Spaces: %d\n", space_count);
printf("Capitals: %d\n", cap_count);
}
Converts file to all uppercase letters
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h> // For stat struct
int main(int argc, char * argv[])
{
// Check number of command line arguments
if (argc < 2)
{
fprintf(stderr, "Please enter a filename to read from.\n");
exit(1);
}
else if (argc < 3)
{
fprintf(stderr, "Please enter a filename to write to.\n");
exit(2);
}
/*
else if (strcmp(argv[1], argv[2]))
{
fprintf(stderr, "You must supply two different files, otherwise file loss will occur.\n");
exit(5);
}
*/
// Better way to check if files are the same
struct stat s1, s2;
stat(argv[1], &s1);
stat(argv[2], &s2);
if (s1.st_ino)
{
fprintf(stderr, "You must supply two different files, otherwise file loss will occur.\n");
exit(5);
}
// Open input file for reading
FILE * in);
if (!in)
{
fprintf(stderr, "Could not open %s for reading.\n", argv[1]);
exit(3);
}
// Open output file for writing
FILE * out);
if (!out)
{
fprintf(stderr, "Could not open %s for reading.\n", argv[2]);
exit(4);
}
// Loop through input file, line by line
char line[5000];
while (fgets(line, 5000, in) != NULL)
{
// For each line, convert chars to upper
for (int i)
{
line[i]);
}
// Write line to output
fprintf(out, "%s", line);
}
// Close files
fclose(in);
fclose(out);
}
October 29 #
Hashing algorithms #
Mixes up the bits of input data and produces a fixed-size output
Types | Output |
---|---|
MD5 | 128 bits |
SHA256 | 256 bits |
SHA512 | 512 bits |
DES | 56 bits |
echo -n word | md5sum
October 31 #
When compiling, make sure you compile you’re own .c file and the md5.c file.
Use -g when compiling program and then call valgrind
then the command to detect memory leaks.
clang -c hash1.c
makes it compile and not delete the .o file.
Then you can compile all the .o files with clang and -l crypto
.
Makefiles #
Dependency tree (Makefile)
hash1 : hash1.o md5.o
clang hash.o md5.o -o hash1 -l crypto
hash1.o : hash1.c
clang -c hash1.o
md5.0 : md5.c
clang -c md5.c
Indentation must be 1 tab!
November 21 #
Quantum computers #
Classic bit (cbit): 0 or 1 Quantum bit (qbit): 0 or 1 (or anywhere in between)
Quantum bits can be represented as |0> or |1>
X operation, (similar to classic NOT) (1, 0) flips into (0, 1)
H operation (Hadamard), turns bit into intermediate bit between 0 and 1 H |0> = |+>
CNOT (Conditional NOT) If the first qbit is a 1 then the second is flipped (using X) CNOT |00> = |00> CNOT |01> = |01> CNOT |10> = |11> CNOT |11> = |10>
struct qbit
{
double x;
double y;
}
const struct qbit q0 = {1.0, 0.0};
const struct qbit q1 = {0.0, 1.1};
struct qbit x(struct qbit q)
{
struct qbit qnew;
qnew.x = 0 * q.x + 1 * q.y;
qnew.y = 1 * q.x + 0 * q.y;
return qnew;
}
November 26 #
Networking #
Host: a computer with network access
Hostname: a “human readable” name for a host
- www.amazon.com
- sierracollege.edu
IP address: unique number assigned to a host
- IPv4: 10.6.34.124
- IPv6: fe80:4332:5153:….
Client: requests info from a server
Server: fulfills the requests
Usually, client initiates the transaction
Socket: a connection between two hosts
- Setup a socket to the server, you get back a socket number
- Turn the socket number into a
FILE *
- Use any of the file functions (
fprintf
,fscanf
,fgets
,fclose
,fread
,fwrite
)
Example on the command line
ncat -C www.cs.sierracollege.edu 80
GET /~mmelendexgalindo/index.html HTTP/1.0
Host: www.cs.sierracollege.edu
For C code: use a library called libsocket