COP 3223H meeting -*- Outline -*- * C vs. Python Idea is to use what we already know about Python to help us learn C quickly I will resist using this to tell you more about Python, so we will keep to the subset of Python we learned in class (which is limited) I use the C99 ISO Standard as a reference (see the course resources page) ** lexical syntax Both languages are case sensitive (case of identifiers matters) ------------------------------------------ LEXICAL SYNTAX tokens Python C ========================================== comments # to eol... continuing STUFF \ STUFF \ a line + MORE + MORE names bool False, True literals int 0, 1, -1, ... 0, 1, -1, ... literals float 0.0, 0.271e1, 0.0, literals 5e-6 string "a str", literals 'another one' char "c", 'c', '\n' literals "\t" ------------------------------------------ ... ISO C99 and most C compilers recognize comments of the form // to eol ... One can also use comments of the form /* ... */ which can be used in all C compilers (even old ones). Such /* ... */ style comments do not nest. ... line continuations are less often needed in C since C doesn't rely on indentation. ... In Python, names can use unicode characters, but identifier naming is similar in C otherwise, even though ISO C99 only guarantees support of ISO 646 characters (essentially ASCII) for source code ... false, true The type _Bool in C is optional in ISO C99, but stdbool.h should be available always, and defines false as 0 and true as 1 Really 0 is false and all non-zero values are true. ints in Python are arbitary precision, whereas in C they are limited in size. C has seveal types of ints: _Bool (1 bit), signed char (8 bits), signed short (16 bits), int (32 bits), and long int (or long, 64 bits), and long long int (128 bits) and signed (the default) and unsigned versions of these in C there are three types of floating point numbers: float (32 bits) double (64 bits), and long double (128 bits). By default literals in C are doubles. You can make a float literal like: 3.2f ... In Python you can use either "...", '...', or """...""" or '''...''' for string literals In C only "..." gives you a string literal C chars always use single quotes, escape sequences are similar (\n for newline, \t for tab, etc.) ** context-free syntax *** expressions ------------------------------------------ DIFFERENCES IN EXPRESSIONS expression Python C ========================================== parenthesis (E) (E) arithmetic A + B A + B A * B A * B A - B A - B A / B A // B A % B A % B A ** B comparisons A < B A < B A <= B A <= B A >= B A >= B A > B A > B A == B A != B A != B Boolean A and B operators A or B not B Ternary E1 if B else E2 operator function f(A1,A2) f(A1,A2) calls field R.G access string S[I] access string S1 = S1 + S2 ops len(S) S1 == S2 anon. (lambda X : E) funcion ------------------------------------------ ... (double)3 / 2 / when both operands are ints, returns an int ... pow(A,B) from , returns a double ... A && B A || B !b ... B ? E1 : E2 I usually put parentheses around this ... A == B, but note that there is no way to overload so == can't be user defined in C ... R.G but C don't have objects that exactly mimic Python's record-like structs in C are simpler ... S[I] Both C and Python index from 0, or *S+I but C doesn't have sequences like C's it just has arrays, so this correspondence only holds for strings. In C S[I] and *S+I mean the same thing. ... strncat(S1,S2,N) where N is the amount of space left in S1 strlen(S) strcmp(S1,S2) == 0 so as one can see, in general to do things with strings, one needs to use the library functions in ... (nothing) no anonymous function closures in C *** statements C is technically an expression language, as assignments in C are expressions with a value (beware!) ------------------------------------------ DIFFERENCES IN STATEMENTS statement Python C ========================================== assignment X = E skip pass return return E return E; sequence S1 S1 S2 S2 if if E: S1 else: S2 loops while E: S for X in R: S loop ctrl break break; stmts continue continue; ------------------------------------------ ... X = E; note that all statements in C end in a semicolon ... ; a semicolon by itself ... if (E) { the curly brackets can be omitted if the statment S1 (S1 or S2) is just one statement, but okay } else { to always have them, and recommended! S2 } ... while(E) { again could omit the curly braces in special cases S } ... for (X = R[0]; X < len(R); X++) { not really the same! S } Q: What do you notice about the syntactic differences between Python and C compound statements? In C the conditions are always in parentheses In C there are semicolons (or }) at the end of every statement In C indentation is optional, the compiler relies on nesting of { and }, but it's still good practice to indent as you have done. *** declarations **** variable and function declarations C is statically typed, and (thus) has many more declarations ------------------------------------------ DIFFERENCES IN DECLARATIONS statement Python C ========================================== variable V = E function def F(arg): S ------------------------------------------ ... T V = E; where T is the type of E (and thus V), or note the semicolon, this is actually a statement T V; as in Python V = E; ... T F(T1 arg) { where T is the result type of F, S and T1 is the type of arg } **** modules ------------------------------------------ DIFFERENCES IN MODULES AND USES In Python, files are modules, used via import M In C, Python C ======================================== import math import LispList ------------------------------------------ ... a file, M.c, and header file, M.h, form something similar to a module used via #include if M is built-in to the language or #include "M.h" if M is user-defined (locally defined) ... import ... import "LispList.h" ** static semantics Many differences stem from the more dynamic nature of Python Python can be interpreted, and may errors are only detected at the last second. C wants to distinguish runtime representations of data to issue the most efficient instruction Q: What does Python do to compute A+B ? it *** types and type checking ------------------------------------------ DIFFERENCES IN TYPE CHECKING Python C ======================================== type dynamically checks Examples: def implies(b1,b2): return not b1 or b2 def trianglearea(b,h): return 1/2 * b * h ------------------------------------------ ... statically ... #include bool implies(bool b1, bool b2) { return !b1 || b2; } ... double trianglearea(double b, double h) { return 0.5 * b * h; // note that 1/2 == 0 in C! } *** naming and declaration scope ------------------------------------------ SCOPE OF DECLARAIONS def: the *scope* of a declaration (or definition) is In Python, the scopes are: global (to a program) local: - to an object - to a function In C the scopes are: global (to a program) ------------------------------------------ ... the area of a program in which that declaration (or definition) has effect. ... note global is the default at top level of files local: - to a file == (declared static) - to a function == auto - to a block (within { and }) ------------------------------------------ EXAMPLE OF LOCAL SCOPES IN C #include void printit(int i) { printf("i is %d\n", i); } int main() { int i = 0; printit(i); { int i = 2; printit(i); i += 1; printit(i); } printit(i); if (i == 0) { int i = 4; printit(i); } else { int i = 5; printit(i); } printit(i); } ------------------------------------------ Q: What does this print? work through which declaration each i refers to, it's the closest surrounding declaration in each case. *** modules ------------------------------------------ DIFFERENCES IN MODULES In Python, imports affect the global dictionary, dynamically In C #includes are ------------------------------------------ ... textual inclusions, and thus put their declarations into a scope statically (however, macros only have global scope in C) *** documentation conventions ------------------------------------------ DOCUMENTATION CONVENTIONS In Python: - your name goes in a comment at the top of a file - a triple-quoted documentation string follows the function header In C - your name goes in a comment at the top of the file - put ------------------------------------------ ... a comment before each function that briefly describes it. from https://www.doc.ic.ac.uk/lab/cplus/cstyle.html#N10126: "Each function should be preceded by a block comment prologue that gives a short description of what the function does and (if not clear) how to use it. Discussion of non-trivial design decisions and side-effects is also appropriate. Avoid duplicating information clear from the code." *** programs ------------------------------------------ DIFFERENCES IN PROGRAMS In Python, a program runs the statement in the __main__ module In C, a program runs the function int main(int argc, char *argv[]) ------------------------------------------ We didn't talk much about programs in Python, actually but pytest is an example of a Python program and we probably won't talk much about them in C either... *** working with programs (editing, compiling) ------------------------------------------ WORKING ON C PROGRAMS In C, a program is a collection of files, with a main function Steps in writing and running a program ------------------------------------------ 0. Using a text editor, write the files source code in .c files, headers in .h files (usually headers aren't important unless you are making a reusable abstraction, such as a library function or data type) 1. Compile each source file using gcc gcc -Wpedantic -c *.c this produces .o files for each c file 2. link the .o files together gcc *.o -o program 3. Run the program ./program # on Unix > program.exe # in a Windows command shell Steps 1 and 2 can be combined: gcc *.c -o program