Download presentation
Presentation is loading. Please wait.
1
Basic Data Types & Memory & Representation
2
Basic data types Primitive data types are similar to JAVA:
char int short long float double Unlike in JAVA, All can be signed/unsigned Default: signed Unlike in JAVA, the types sizes are machine dependant!
3
Memory – few definitions
Bit – a binary digit - zero or one Byte – 8 bits Not C specific 0/1 0/1
4
Basic data types The types sizes must obey the following rules.
Size of char = 1 byte Size of short ≤ size of int ≤ size of long Undetermined type sizes Advantage: hardware support for arithmetic operations Disadvantage: problems with porting code from one machine to another
5
signed VS. unsigned Each type could be signed or unsigned int negNum = -3; int posNum = 3; unsinged int posNum = 3; unsinged int posNum = -3;
6
Integers binary representation
7
Integers binary representation
unsigned integers types are represented with the binary representation of the number they stand for. The representation range therefore is… Where x is the size in bits of the type The exact representation of signed integers types is machine dependant. The most popular representation is, the two- complement representation The representation range is: [-2x-1,2x-1-1] [0,2x-1]
8
Integers binary representation
short num = -1; printf("%u",num); The output on some machines is: What happened? -1 -> (signed short representation) >65535 when interpreted as unsigned short.
9
Integers binary representation
10
The sizeof() operator The operator sizeof (type) returns the size of the type: printf("%lu",sizeof(char)); //charSize == 1 lu is unsigned long
11
Primitive types & sizeof
int main() { //Basic primitive types printf("sizeof(char) = %lu\n",sizeof(char)); printf("sizeof(int) = %lu\n",sizeof(int)); printf("sizeof(float) = %lu\n",sizeof(float)); printf("sizeof(double) = %lu\n",sizeof(double)); //Other types: printf("sizeof(void*) = %lu\n",sizeof(void*)); printf("sizeof(long double)= %lu\n",sizeof(long double)); return 0; }
12
Integral types - characters
chars can represent small integers or a character code. Examples: char c = ‘A’; char c = 65;
14
Arithmetic with character variables
char ch = 'A'; printf("The character %c has the ASCII code %u.\n", ch, ch);
15
Arithmetic with character variables
for (char ch= 'A'; ch <= 'Z'; ++ch) { printf("%c", ch); }
16
& "%d %f %lf General Input/Output
#include <stdio.h> int main() { int n; float q; double w; printf("Please enter an int, a float and a double\n"); scanf("%d %f %lf",&n,&q,&w); printf("ok, I got: n=%d, q=%f, w=%lf",n,q,w); return 0; } & "%d %f %lf
17
Characters input and output
#include <stdio.h> int main () { char c; printf("Enter character:"); c=getchar(); printf("You entered:"); putchar(c); return 0; }
18
Printing MAX_LINES #include <stdio.h> #define MAX_LINES 10 int main() { int n = 0; int c; while(((c=getchar())!=EOF) && (n<MAX_LINES) ) { putchar(c); if( c == '\n' ) n++; } return 0; } 18
19
Boolean types Boolean type doesn’t exist in C! Use char/int instead (there is also a possibility to work on bits) zero = false non-zero = true Examples: while (1) { } infinite loop if (-1974) { } true statement i = (3==4); i equals zero
20
Boolean types Boolean type doesn’t exist in C! Use char/int instead (there is also a possibility to work on bits) zero = false non-zero = true Examples: #define TRUE 1 while (TRUE) { } infinite loop while (1) { } infinite loop if (-1974) { } true statement i = (3==4); i equals zero
21
Casting and Type Conversion
Operands with different types get converted when you do arithmetic. Everything is converted to the type of the floatiest, longest operand, signed if possible without losing bits Casting possible between all primitive types. Casting up - usually automatic: float => double short => int => long etc. int i; short s; long l; i=s; // no problem l=i; // no problem s=l; // might lose info, // warning not guaranteed
22
Casting and Type Conversion
Operands with different types get converted when you do arithmetic. Everything is converted to the type of the floatiest, longest operand, signed if possible without losing bits Casting possible between all primitive types. Casting up - usually automatic: float => double short => int => long etc. Casting down – warning ! int i; short s; long l; i=s; // no problem l=i; // no problem s=l; // might lose info, // warning not guaranteed
23
Integer division Mathematical operators on only int operands
The result is int Integer numbers are treated as “int” float f=1/3; //0 float f=(float)1/3; // float f=1/3.0; //
24
Expressions as Values && - logical “and” || - logical “or”
& - bitwise “and” || - logical “or” | - bitwise “or” bitwise – end of the year Evaluation: int i=0; if (i==1 && x=isValid()) { … } Might not be evaluated
25
Functions declarations and definitions
26
Declarations and definitions
Function declaration: Specification of the function prototype. No specification of the function operations. Function definition Specification of the exact operations the function performs.
27
Declarations and definitions
“One definition rule”: many declarations, one definition. Examples: many function declarations (no body, just “signature”, one definition – with body. Legal but bad style int f(),f(int); int f(int); int f(int a); int f(int a) { return a*2; } Later on we will see the same with structs, and see cases where for a variable a declaration isn’t the same as definition (=storage allocation).
28
Function signature Syntactically you declare a function exactly the same as you do a variable: <type> <name> With the added “modifier” of “()” to the name. int g(), f, x,i, k(); The above line declares 3 int’s and two int functions.
29
Function signature In C (not c++) function signature is composed only from it’s name and return type: int f(int a,int b); Has the same type as int f(float c); Why? Once upon a time (80’) you did not write parameter names in function declarations or definitions, so all functions where like this: int f(), g(); And you would need to remember what arguments to pass…
30
Function signature Today it is still legal but it’s a very bad style and error prone. This leads to a side effect that: int f(int a,char b); int f(float a) { return a*2; } int main() { f(5,'a'); } Will compile and run, and call the second f! But, If you will try to define also the first signature – you will get an error.
31
To get these warnings with functions that has no arguments declare:
Function signature Today it is still legal but it’s a very bad style and error prone. This leads to a side effect that: int f(int a,char b); int f(float a) { return a*2; } int main() { f(5,'a'); } Will compile and run, and call the second f! But, If you will try to define also the first signature – you will get an error. No overloads. If you use high warning level, above code will give you some warning. Pay attention. To get these warnings with functions that has no arguments declare: int f(void);
32
Program style
33
Program style Principles: Readability Common Sense Clarity Right focus
Take the time for it. Very important. If not followed your code will be “write only”. Common sense Read “real” coding guidelines document – will give you insight how important it is. e.g. good one from Microsoft or one from Google. Principles: Readability Common Sense Clarity Right focus
34
What’s in a name Example #define ONE 1 #define TEN 10 #define TWENTY 20 More reasonable #define INPUT_MODE 1 #define INPUT_BUFSIZE 10 #define OUTPUT_BUFSIZE 20
35
What’s in a name Be consistent, with yourself and peers.
Use descriptive names for global variables int npending = 0; // current length of input queue Naming conventions vary (style) numPending num_pending NumberOfPendingEvents Be consistent, with yourself and peers.
36
What’s in a name Be consistent, with yourself and peers.
Consider (wording) int noOfItemsInQ; int frontOfTheQueue; int queueCapacity; … The word “queue” appears in 3 different ways Be consistent, with yourself and peers.
37
Use short names for locals
What’s in a name Compare for( theElementIndex = 0; theElementIndex < numberOfElements; theElementIndex++ ) elementArray[theElementIndex] = theElementIndex; and for( i = 0; i < nelems; i++ ) elem[i] = i; Use short names for locals
38
What’s in a name Use active name for functions Compare
now = getDate() Compare if( checkdigit(c) ) … to if( isdigit(c) ) … Accurate active names makes bugs apparent
39
Indentation Use indentation to show structure Compare To
for(size_t n=0; n <100; field[n++] = 0); c = 0; return ‘\n’; To for(size_t n=0; n <100; n++) { field[n] = 0; } c = 0; return ‘\n’;
40
Expressions Use parentheses to resolve ambiguity Compare to
leap_year = y % 4 == 0 && y %100 != || y % 400 == 0; to leap_year = ((y % 4 == 0) && (y %100 != 0)) || (y % 400 == 0);
41
Statements Use braces to resolve ambiguity Compare To
if( i < 100 ) x = i; i++; To if( i < 100 ) { x = i; } i++;
42
Idioms Do not try to make code “interesting”!
for( i = n; --i >= 0; ) { i = 0; while( i <= n-1 ) { array[i] = 1; } for( i = 0; i < n; i++ ) { array[i++] = 1; } for( i = 0; i < n; ) { } למעשה – חשוב מאד לא רק למתכנת אלא גם לקומפיילר מודרני – קוד מוכר יעבור אופטימיזציה טובה יותר בסיכוי גבוה יותר. This is the common “idiom” that any programmer will recognize
43
Idioms Use “else if” for multiway decisions if ( cond1 ) { statement1 } else if ( cond2 ) statement2 … else if ( condn ) statementn else default-statement
44
Idioms Compare: if( x > 0 ) if( y > 0 ) if( x+y < 100 ) { ... } else printf(Too large!\n" ); else printf("y too small!\n"); else printf("x too small!\n"); if( x <= 0 ) { printf("x too small!\n"); } else if( y <= 0 ) { printf("y too small!\n"); } else if( x+y >= 100 ) { printf("Sum too large!\n" ); } else { ... }
45
Does comment add something that is not evident from the code?
Comments Don’t write the obvious // return SUCCESS return SUCCESS; // Initialize total to number_received total = number_received; Test: Does comment add something that is not evident from the code? Note: “//” Comments are Not Strict ANSI C, but supported by all modern compilers, and clearer in many cases
46
Comments Don’t comment bad code – rewrite it! … Instead
// If result = 0 a match was found so return // true; otherwise return false; return !result; Instead return matchfound;
47
Code needs to tell a story
Every line or at least several lines should be self explantory about what it does, even if we don’t understand how
48
Style recap Descriptive names Clarity in expressions
Straightforward flow Readability of code & comments Consistent conventions & idioms
49
Why Bother? Good style: Sloppy style bad code Easy to understand code
Smaller & polished Makes errors apparent Sloppy style bad code Hard to read Broken flow Harder to find errors & correct them
50
In the slides we try to follow the style we dictate
In the slides we try to follow the style we dictate. But due to space restriction we sometimes bend the rules. Don’t follow everything you see in the slides. Note - style in slides:
51
Testing
52
Unit Testing in a Nutshell
Write tests Write code Code without test Automatic fail Small code change Tests run Bug found and fixed Add test for it
53
Debugging
54
Debugging 101 “Define” the bug --- reproduce it Use debugger and printouts (and other tools e.g. valgrind) Don’t panic --- think! Divide & Conquer
55
General purpose debug function
// file: my_debug.h // defines a general purpose debug printing function // usage: same as printf, // to disable the printing define the macro NDEBUG #ifdef NDEBUG #define printDEBUG(format, ...) (void (0)) #else #define printDEBUG(format, ...) \ printf(format, ##__ VA_ARGS__) #endif
56
Debugger See how the program runs, value of variables...
Breakpoints, break on expressions change... Stack Trace: very helpful for seg faults!
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.