0% found this document useful (0 votes)
7 views

04-C Basics

Uploaded by

tronex.solar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

04-C Basics

Uploaded by

tronex.solar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

C - Basics, Bitwise Operator

Jinyang Li
Lesson plan
• Overview
• C program organization
• Bitwise operators
• Control flow
C is an old programming language

C (1972) Java (1995) Python (2.0, 2000)


C is an old programming language

C Java Python
1972 1995 2000 (2.0)
Procedure Object oriented Procedure & object oriented
Compiled to machine Compiled to bytecode, Scripting language, interpreted
code, runs directly on runs by another piece of by software
hardware software

static type static type dynamic type


Manual memory Automatic memory management with GC
management

Tiny standard Very Large library Humongous library


library
Why learn C for CSO?
• C is a systems language
– Language for writing OS and low-level code
– System software written in C:
• Linux, Windows kernel, MacOS kernel
• MySQL, Postgres
• Apache webserver, NGIX
• Java virtual machine, Python interpreter
• Why learning C for CSO?
– simple, low-level, “close to the hardware”
The simplest C program: “Hello World”

#include <stdio.h> Equivalent to “importing” a library package

int main()
{
printf("hello, world\n");
return 0;
A function “exported” by stdio.h
}
hello.c

Compile: gcc hello.c –o hello


Run ./hello If –o is not given, output executable file is a.out
:
C program with multiple files: naïve
organization

int sum(int x, int y) #include <stdio.h> #include <stdio.h>


#include <assert.h>
{
return x+y; int main()
void test_sum()
{ {
}
int r = sum(1,1); printf(“sum=%d\n”, sum(-1,1));
sum.c assert(r == 2); }
}
main.c
int main()
{ Compile: gcc sum.c test.c –o test
test_sum();
} gcc sum.c main.c
test.c
Run: ./test Sum.c compiled twice.
./a.out Wasteful
C program with multiple files: *.h vs *.c files

Equivalent to “importing” a package


int sum(int x, int y) #include <stdio.h> #include <stdio.h>
#include <assert.h> #include “sum.h”
{
#include “sum.h”
return x+y; int main()
} {
void test_sum() printf(“sum=%d\n”, sum(-1,1));
sum.c { }
int r = sum(1,1);
assert(r == 2); main.c
int sum(int x, int y);
}
sum.h
int main()
{
test_sum();
}

test.c
Common compilation sequence
called
Source (Binary)
gcc –c main.c object linking
Code
main.c file (Binary)
main.o gcc main.o sum.o Executable
a.out
Source (Binary)
gcc –c
Code object
sum.c
sum.c file
sum.o

(Binary)
Source (Binary) gcc test.o sum.o –o test Executable
gcc –c test.c
Code object test
test.c file
test.o

C project uses the make tool to automate compiling with dependencies.


all: a.out test
test: test.o sum.o
gcc $^ -o $@
a.out: main.c sum.o
gcc $^ -o $@
%.o: %.c
gcc –c $^
Makefile
Basic C

• C’s syntax is very similar to Java


– Java borrowed its syntax from C
If uninitialized,
Initial value
variable can have any value
Variable declaration: int a = 1;

Type Name
Primitive Types (64-bit machine)

Either a character or an intger


type size (bytes) example
(unsigned) char 1 char c = ‘a’
(unsigned) short 2 short s = 12
(unsigned) int 4 int i = 1
(unsigned) long 8 long l = 1
float 4 float f = 1.0
double 8 double d = 1.0
pointer 8 int *x = &i
Next lecture
Old C has no native boolean type. A non-zero integer
represents true, a zero integer represents false

C99 has “bool” type, but one needs to include


<stdbool.h>
Implicit conversion
int main()
{
int a = -1;
unsigned int b = 1;

if (a < b) {
printf("%d is smaller than %d\n", a, b);
} else if (a > b) {
printf("%d is larger than %d\n”, a, b);
}
return 0;
}

$gcc test.c No compiler warning!


$./a.out
-1 is larger than 1

Compiler converts int types to the one with the larger value (e.g.
char à unsigned char à int à unsigned int)

-1 is implicitly cast to unsigned int (4294967295)10


Explicit conversion (casting)

int main()
{
int a = -1;
unsigned int b = 1;

if (a < (int) b) {
printf("%d is smaller than %d\n", a, b);
} else if (a > (int) b) {
printf("%d is larger than %d\n”, a, b);
}

return 0;
}
Operators

Arithmetic +, -, *, /, %, ++, --
Relational ==, !=, >, <, >=, <=
Logical &&, ||, !
Bitwise &, |, ^, ~, >>, <<

Arithmetic, Relational and Logical operators are identical to java’s


Bitwise AND: &
Truth table (of boolean function AND)
x y x AND y
0 0 0
How many rows
if function has 0 1 0
n boolean (aka 1 0 0
1-bit) inputs? 1 1 1
2n
Operator & applies AND bitwise to two integers

( 0 1 1 0 1 0 0 1 )2
& ( 0 1 0 1 0 1 0 1 )2
Result of 0x69 & 0x55

( 0 1 0 0 0 0 0 1 )2
Example use of &

• & is often used to mask off bits


b & 0 = 0?
b is any bit b & 1 = b?

int clear_msb(int x) {
return x & 0x7fffffff;
}
Bitwise OR: |
x y x OR y
0 0 0
0 1 1
1 0 1
1 1 1

Operator | applies OR bitwise to two integers

( 0 1 1 0 1 0 0 1 )2
| ( 0 1 0 1 0 1 0 1 )2
Result of 0x69 | 0x55

( 0 1 1 1 1 1 0 1 )2
Example use of |

• | can be used to turn some bits on


b | 1 = 1?
b | 0 = b?

int set_msb(int x) {
return x | 0x80000000;
}
Bitwise NOT: ~
x NOT x
0 1
1 0

Operator ~ applies NOT bitwise to two integers

~ ( 0 1 1 0 1 0 0 1 )2
result of ~0x69

( 1 0 0 1 0 1 1 0 )2
Bitwise XOR: ^
x y x XOR y
0 0 0
0 1 1
1 0 1
1 1 0

Operator ^ applies XOR bitwise to two integers

( 0 1 1 0 1 0 0 1 )2
result of 0x69^0x55 ^ ( 0 1 0 1 0 1 0 1 )2

( 0 0 1 1 1 1 0 0 )2
Bitwise left-shift: <<
x << y, treat x as a bit-vector, shift x left by y positions
– Throw away bits shifted out on the left
– Fill in 0’s on the right

result of 0x69<<3 ? (0 1 1 0 1 0 0 1)2

=(0 1 0 0 1 0 0 0)2
Bitwise right-shift: >>

• x >> y, shift bit-vector x right by y positions


– Throw away bits shifted out on the right
– Logical shift: Fill with 0’s on left
– Arithmetic shift: Replicate msb on the left

Result of (logical) right-shift: 0xa9 >> 3 (1 0 1 0 1 0 0 1)2

=(0 0 0 1 0 1 0 1)2

Result of (arithmetic) right-shift: 0xa9 >> 3 =(1 1 1 1 0 1 0 1)2


Which shift is used in C ?
Arithmetic shift for signed numbers
Logical shifting on unsigned numbers

int a = 1; unsigned int b = -1;


a = a>>31; b = b >>30;

int b = -1; ??
b = 3
b = b >>31;

a=0?? b=-1
??
Example use of shift

int multiply_by_powers_of two(int x, int p)


{
return x << p;
}

int divide_by_powers_of two(int x, int p)


{
return x >> p;
}

Caveat: right-shift rounds down, different from


integer division “/” which rounds towards zero.
e.g. -1>>1=-1, but -1/2 = 0
Example use of shift

// clear bit at position pos


// rightmost bit is at 0th pos

int clear_bit_at_pos(int x, int pos)


{
unsigned int mask = 1 << pos;
return x & (~mask);
}
Lesson plan
• Overview
• C program organization
• Bitwise operators
• Control flow
C’s Control flow
• Same as Java
• conditional:
– if ... else if... else
– switch
• loops: while, for
– continue
– break
goto statements allow jump anywhere
goto label
while (cond) {
... for(...) {
} for(...) {
B: for(...) {
... goto error
Any control flow primitive can be }
expressed as a bunch of goto’s. }
}
A:
if (cond = false) goto B; error:
... code handling error
goto A
B:
...
The only acceptable scenario for using goto
Avoid goto’s whenever possible
Avoid goto’s whenever possible
C scope rules
• Local variable: defined within a procedure
– Scope: within the procedure
• Global variable: defined outside of any procedure
– Scope: within the file unless exported via *.h
int x = 0;
int y = 1;
void swap(int x, int y) {
int tmp = x;
x = y;
y= x;
}
int main() {
int x = 0;
int y = 1;
swap(x, y);
}
Summary
• C program’s basic organization
– *.c vs. *.h files
– Compilation and make
• Bitwise operators, &, |, ~, ^, >>, <<
– >> (arithmetic vs. logical)
• Control flow
– goto is general, but results in spaghetti code

You might also like