Hyperpolyglot.org
a side-by-side reference sheet
grammar and invocation | variables and expressions | arithmetic and logic | strings | regexes | dates and time
arrays | dictionaries | user-defined types | functions | execution control | file handles | files | directories
processes and environment | libraries and namespaces | objects | generic types | reflection | net and web
unit tests | debugging and profiling | contact
c++ | objective c | java | c# | |
---|---|---|---|---|
version used | g++ 4.6 with -std=c++0x flag | gcc 4.2 | java 1.6 | mono 2.10 (C# 4.0) |
show version | $ g++ --version | $ gcc --version | $ javac -version | $ mcs --version |
implicit prologue | #include <iostream> #include <string> using namespace std; | |||
grammar and invocation | ||||
c++ | objective c | java | c# | |
hello world | $ cat hello.cpp #include <iostream> using namespace std; int main(int argc, char**arg) { $ g++ -std=c++0x hello.cpp $ ./a.out | $ cat hello.m #include <stdio.h> int main(int argc, char **argv) { $ gcc hello.m $ ./a.out | $ cat Hello.java public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); } } $ javac Hello.java $ java Hello | $ cat hello.cs using System; public class Hello { $ mcs hello.cs $ mono hello.exe |
file suffixes source, header, object file | foo.cpp foo.h foo.o | Foo.m Foo.h Foo.o | Foo.java none Foo.class Foo.java must define a single top level class Foo | Foo.cs none Foo.exe or Foo.dll although files are often named after a class they contain, this is not required |
block delimiters | { } | { } | { } | { } |
statement terminator | ; | ; | ; | ; |
top level statements | A source file will normally have #include directives at the top, followed by declarations, definitions, and namespaces containing declarations and definitions. After the preprocessor has finished processing a source file, the | each file contains the following elements in order: (1) optional package directive | ||
end-of-line comment | // comment | // comment | // comment | // comment |
multiple line comment | /* comment another comment */ | /* comment another comment */ | /* comment another comment */ | /* comment another comment */ |
variables and expressions | ||||
c++ | objective c | java | c# | |
local variable | int i; int j = 3; int k(7); | int i; int j = 3; | int i; int j = 3; | int i; int j = 3; |
uninitialized local variable | The behavior is undefined. Most implementations do not zero-initialize stack variables, so the value will be whatever happened to be in memory. | behavior is undefined. Most implementations do not zero-initialize stack variables, so the value will be whatever happened to be in memory. | zero initialized | compiler prevents use of uninitialized local variable |
global variable | // in foo.cpp and outside of any function // or class definition: int foo = 7; // in bar.cpp and outside of any function | in foo.cpp outside of any function or class definition: int foo = 7; in bar.cpp outside of any function or class definition: | ||
constant | const int i = 7; | const int i = 7; | final int i = 7; | const int i = 7; |
allocate heap | int* ip = new int; | #include <stdlib.h> int *ip = malloc(sizeof(int)); | primitive types are always stack allocated. Use a wrapper class to store on the heap: Integer i = new Integer(0); | object i = 0; |
free heap | delete i; | #include <stdlib.h> free(ip); | garbage collected | garbage collected |
null | NULL | NULL | null | null |
coalesce | string s1 = s2 || "was null"; | NSString *s1 = s2 || @"was null"; | String s1 = s2 == null ? "was null" : s2; | string s1 = s2 ?? "was null"; |
arithmetic and logic | ||||
c++ | objective c | java | c# | |
boolean type | bool | BOOL | boolean | bool |
true and false | true false | YES NO | true false | true false |
falsehoods | false 0 0.0 NULL | 0 0.0 NULL | false | false |
logical operators | && || ! and or not | && || ! | && || ! | && || ! |
relational operators | == != < > <= >= | == != < > <= >= | == != < > <= >= | == != < > <= >= |
integer type | signed char n1; // 1+ bytes short int n2; // 2+ bytes int n3; // 2+ bytes long int n4; // 4+ bytes long long int n5; // 4+ bytes | signed char 1+ byte short int 2+ bytes int 2+ bytes long int 4+ bytes long long int 4+ bytes | byte 1 byte short 2 bytes int 4 bytes long 8 bytes | sbyte 1 byte short 2 bytes int 4 bytes long 8 bytes |
unsigned type | unsigned char n1; // 1+ bytes unsigned short int n2; // 2+ bytes unsigned int n3; // 2+ bytes unsigned long int n4; // 4+ bytes unsigned long long int n5; // 4+ bytes | unsigned char: 8+ unsigned short int 2 bytes+ unsigned int 2 bytes+ unsigned long int 4+ bytes unsigned long long int 4+ bytes | char 2 bytes | byte 1 byte ushort 2 bytes uint 4 bytes ulong 8 bytes |
float type | float x1; // 4 bytes double x2; // 8 bytes long double x3; // 16 bytes | float double long double | float 4 bytes double 8 bytes | float 4 bytes double 8 bytes |
fixed type | none | none | none | decimal 12 bytes |
arithmetic operators | + - * / % | + - * / % | + - * / % | + - * / % |
integer division | // evaluates to 2: 7 / 3 | evaluates to 2: 7 / 3 | evaluates to 2: 7 / 3 | evaluates to 2: 7 / 3 |
integer division by zero | process sent a SIGFPE signal | process sent a SIGFPE signal | throws java.lang.ArithmeticException | Syntax error if divisor is a constant. Otherwise throws System.DivideByZeroException |
float division | 7 / static_cast<float>(3) | 7 / (float)3 | 7 / (float)3 | 7 / (float)3 |
float division by zero dividend is positive, zero, negative | inf nan -inf There are no portably defined literals or constants for the above values. | inf nan -inf there are no portably defined literals or constants for the above values. | Float.POSITIVE_INFINITY Float.NaN Float.NEGATIVE_INFINITY constants with same names defined in Double | float.PositiveInfinity float.NaN float.NegativeInfinity constants with same names defined in double |
power | #include <math.h> double x = pow(2.0, 32.0); | #include <math.h> pow(2.0, 32.0); | Math.pow(2.0, 32.0); | System.Math.Pow(2.0, 32.0); |
sqrt | #include <math.h> double x = sqrt(2); | #include <math.h> sqrt(2) | Math.sqrt(2) | Math.Sqrt(2) |
sqrt -1 | nan | nan | Double.NaN | double.NaN |
transcendental functions | #include <math.h> exp log log2 log10 | #include <math.h> exp log log2 log10 | Math.exp Math.log none Math.log10 Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 | using System; Math.Exp Math.Log none Math.Log10 Math.Sin Math.Cos Math.Tan Math.Asin Math.Acos Math.Atan Math.Atan2 |
transcendental constants | #include <math.h> double e = M_E; | #include <math.h> M_E | Math.E Math.PI | System.Math.E System.Math.PI |
float truncation towards zero, to nearest integer, towards -∞, towards ∞ | #include <math.h> double x = 3.7; long trnc = static_cast<long>(x); long rnd = round(x); long flr = floorl(x); long cl = ceill(x); | #include <math.h> double d = 3.77; long trnc = (long)d; long rnd = round(d); long flr = floorl(d); long cl = ceill(d); | (long)3.77 Math.round(3.77) (long)Math.floor(3.77) (long)Math.ceil(3.77) | using System; (long)3.77 Math.Round(3.77) Math.Floor(3.77) Math.Ceiling(3.77) |
absolute value | #include <stdlib.h> // abs() #include <math.h> // fabs() int n = -7; double x = -7.77; | #include <stdlib.h> // abs() #include <math.h> // fabs() int i = -7; float x = -7.77; | Math.abs(-7) Math.abs(-7.77) | System.Math.Abs(-7) System.Math.Abs(-7.77) |
integer overflow | modular arithmetic The C standard does not define behavior for signed integers, however. | modular arithmetic The C standard does not define behavior for signed integers, however. | modular arithmetic | modular arithmetic |
float overflow | no behavior defined by standard; many implementations return inf | no behavior defined by standard; many implementations return inf | Float.POSITIVE_INFINITY | float.PositiveInfinity |
float limits largest finite float, smallest positive float | #include <float.h> FLT_MAX | Float.MAX_VALUE Float.MIN_VALUE Double.MAX_VALUE Double.MIN_VALUE | float.MaxValue float.Epsilon double.MaxValue double.Epsilon | |
complex construction | #include <complex> complex<double> z(1.0, 2.0); | |||
complex decomposition real and imaginary component, argument, absolute value, conjugate | z.real() z.imag() arg(z) abs(z) conj(z) | |||
random number uniform integer, uniform float, normal float | #include <random> default_random_engine dre; uniform_int_distribution<int> uid(0, 99); int i = uid(dre); | #include <stdlib.h> // assuming 100 much smaller than RAND_MAX: | import java.util.Random; Random rnd = new Random(); int i = rnd.nextInt(100); | using System; Random rnd = new Random(); int i = rnd.Next(); |
random seed | #include <random> // set seed in constructor: // set seed of existing engine: | import java.util.Random; Random rnd = new Random(); rnd.setSeed(17); seed can be passed to constructor | using System; Random rnd = new Random(17); | |
bit operators | << >> & | ^ ~ bitand bitor compl | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ |
binary, octal, and hex literals | 0b0101010 052 0x2a | none in Java 1.6 052 0x2a | none 052 0x2a | |
radix convert integer to and from string with radix | Integer.toString(42, 7) Integer.parseInt("60", 7) | |||
strings | ||||
c++ | objective c | java | c# | |
string type | string s("lorem ipsum"); // convert to C string: | NSString* s = @"lorem ipsum"; // convert to C string: | java.lang.String | string |
string literal | // const char*: "don't say \"no\"" | @"don't say \"no"" | "don't say\"no\"" | "don't say \"no\"" |
newline in literal | Newlines in string literals are ignored. | string literals can extend over multiple lines, but the newlines do not appear in the resulting string | no | string literals can extend over multiple lines, but the newlines do not appear in the resulting string |
literal escapes | \a \b \f \n \r \t \v \\ \" \' \xhh \o \oo \ooo | \a \b \f \n \r \t \v \\ \" \' \xhh \o \oo \ooo | \b \f \n \r \t \\ \" \' \uhhhh \o \oo \ooo | \a \b \f \n \r \t \v \\ \" \' \xhh \xhhhh \o \oo \ooo |
allocate string | string* s = new string("hello"); | NSString *s = @"hello"; | String s = "hello"; String t = new String(s); | string s = "hello"; string t = string.Copy(s); |
are strings mutable? | string s("bar"); s[2] = 'z'; | |||
copy string | string s("bar"); // use assignment or copy constructor: // s contains "baz"; | |||
format string | #include <sstream> ostringstream oss; | [NSString stringWithFormat:@"%@: %d", @"Spain", 7] | String.format("%s: %d", "Spain", 7) | string.Format("{0}: {1}", "Spain", 7) |
compare strings | string s1("hello"); string s2("world"); // negative if s1 lexically before s2; bool result2 = s1 == s2; | [@"hello" compare:@"hello"] | "hello".compareTo("world") | "hello".CompareTo("world") |
concatenate and append | string s("hello"); string s2 = s + " world"; s += " world"; | NSString *s1 = @"hello"; NSString *s2 = @" world"; NSString *s3 = [s1 stringByAppendingString:s2]; | "hello" + " world" | "hello" + " world" |
replicate | string hbar(80, '-'); | |||
translate case | #include <algorithm> string s("foo"); // in place: // non-destructive: | [@"HELLO" lowercaseString] | "hello".toUpperCase() "HELLO".toLowerCase() | "hello".ToUpper() HELLO".ToLower() |
trim | #include <algorithm> string s(" hello "); // trim in place on right: | [@" hello " stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]] | " hello ".trim() | " hello ".Trim() |
pad on right, on left | #include <sstream> #include <iomanip> string s("hello"); ostringstream oss; | [@"hello" stringByPaddingToLength:10 withString:@" " startingAtIndex:0] | ||
number to string | Integer.toString(14) Long.toString(14) Double.toString(14.7) | 14.ToString() 14.7.ToString() | ||
string to number | #include <sstream> stringstream ss("7 14.3 12"); ss >> n1 >> x >> n2; | [@"14" integerValue] [@"14" longLongvalue] [@"14.7" floatValue] [@"14.7" doubleValue] | Byte.parseByte("14") Short.parseShort("14") Integer.parseInt("14") Long.parseLong("14") Float.parseFloat("14.7") Double.parseDouble("14.7") | byte.Parse("14") short.Parse("14") int.Parse("14") long.Parse("14") float.Parse("14") double.Parse("14") decimal.Parse("14") |
join | System.String.Join(", ", names) | |||
split | #include <boost/algorithm/string.hpp> #include <vector> string s("Bob Amy Ned"); vector<string> vec; boost::split(vec, s, boost::is_any_of(" ")); | [@"Bob Ned Amy" componentsSeparatedByString:@" "] | "Bob Ned Amy".split(" ") | string[] names = "Bob Ned Amy".Split(' '); |
serialize | ||||
string length | string s("hello"); size_t len = s.length(); | [s length] | s.length() | s.Length |
index of substring | string("hello").find("ll") | [@"hello" rangeOfString:@"ll"].location | "hello".indexOf("ll") | "hello".IndexOf("ll") |
extract substring | string("hello").substr(2, 2) | [@"hello" substringWithRange:NSMakeRange(2, 2)] | "hello".substring(2,4) | "hello".Substring(2, 2) |
character type | char wchar_t | |||
character literal | char n = 'X'; | |||
test character letter, digit, whitespace, uppercase letter, lowercase letter | // functions have this signature: // // int (*)(int): // isalpha isdigit isspace isupper islower | |||
regular expressions | ||||
c++ | objective c | java | c# | |
regex type | regex wregex | |||
character class abbreviations | . \d \D \s \S \w \W | |||
anchors | ^ $ \b \B | |||
lookahead positive, negative | (?=subpattern) (?!subpattern) | |||
match test | #include <regex> regex rx(".*ll.*"); | NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @".*ll.*"]; BOOL is_match = [pred evaluateWithObject:@"hello"]; | boolean isMatch = "hello".matches(".*ll.*"); | using System.Text.RegularExpressions; Regex regex = new Regex("ll"); bool isMatch = regex.IsMatch("hello"); |
case insensitive match test | #include <regex> regex rx("lorem", icase); | |||
modifiers | ||||
substitution | String s1 = "hello".replace("ll","LL"); String s2 = "hello".replaceAll("l","L"); | using System.Text.RegularExpressions; Regex r1 = new Regex("ll"); String s1 = r1.Replace("hello", "LL", 1); Regex r2 = new Regex("l"); String s2 = r2.Replace("hello", "L"); | ||
match, prematch, postmatch | ||||
group capture | ||||
dates and time | ||||
c++ | objective c | java | c# | |
date and time type | java.util.Date | System.DateTime | ||
current date and time | import java.util.Date; long millis = System.currentTimeMillis(); | DateTime dt = DateTime.Now(); | ||
to unix epoch, from unix epoch | long epoch = dt.getTime() / 1000; Date dt2 = new Date(epoch * 1000); | long hundredM = 100 * 1000 * 1000; long sec = dt.ToFileTimeUtc() / hundredM; long epoch = sec - 1164444480; long ft = (epoch + 1164444480) * hundredM; | ||
date and time to string | dt.toString() | |||
format date | String s = "yyyy-MM-dd HH:mm:ss"; DateFormat fmt = new SimpleDateFormat(s); String s2 = fmt.format(dt); | String s = "yyyy-MM-dd HH:mm:ss"); String s2 = dt.ToString(s); | ||
parse date | String s = "2011-05-03 17:00:00"; Date dt2 = fmt.parse(s); | CultureInfo enUS = new CultureInfo("en-US"); DateTime dt2 = DateTime.ParseExact( | ||
date subtraction | difference in milliseconds as a long: dt2.getTime() - dt.getTime() | |||
add duration | long day_ms = 24 * 3600 * 1000; Date dt = new Date(dt.getTime() + day_ms)); | |||
date parts | ||||
time parts | ||||
arrays | ||||
c++ | objective c | java | c# | |
allocate array on stack | int a[10]; | int a[10]; | arrays must be allocated on heap | arrays must be allocated on heap |
allocate array on heap | int *a = new int[10]; | #include <stdlib.h> int *a = calloc(10, sizeof(int)); | int[] a = new int[10]; | int[] a = new int[10]; |
free array on heap | delete[] a; | #include <stdlib.h> free(a); | garbage collected | garbage collected |
array literal | int a[] = {1,2,3}; | NSArray *a = [NSArray arrayWithObjects:@"hello", @"goodbye", nil]; | int[] a = {1,2,3}; | int[] a = {1,2,3}; |
array access | a[0] | [a objectAtIndex:0] | a[0] | a[0] |
length | none | [a count] | a.length | a.Length |
array out-of-bounds result | undefined, possible SIGSEGV | raises NSRangeException exception | ArrayIndexOutOfBoundsException | IndexOutOfRangeException |
array iteration | int a[10]; for (i=0; i<10; i++ ) { do something with a[i] } | NSEnumerator *i = [a objectEnumerator]; id o; while (o = [i nextObject]) { do something with o } | for (String name : names) { | foreach (string name in names) { |
vector declaration | #include <vector> vector <int> vec; | NSMutableArray *a = [NSMutableArray arrayWithCapacity:10]; | java.util.Vector<String> vec = new java.util.Vector<String>(); | using System.Collections.Generic; List<string> l = new List<string>(); |
vector push | vec.push_back(7); | [a addObject:@"hello"]; | vec.add("hello"); or vec.add(vec.size(), "hello") | l.Add("hello"); |
vector pop | vec.pop_back(); | [a removeLastObject]; | vec.removeElementAt(vec.size()-1); | l.RemoveAt(l.Count - 1); |
vector size | vec.size() | [a count] | vec.size() | l.Count |
vector access | vec[0] vec.at(0) | [a objectAtIndex:0] | vec.elementAt(0) | l[0] |
vector out of bounds result | vec[] has undefined behavior vec.at() raises out_of_range | raises NSRangeException | throws ArrayIndexOutOfBoundsException | throws System.ArgumentOutOfRangeException |
vector iteration | int sum = 0; vector<int>::iterator vi; for (vi = vec.begin(); vi != vec.end(); vi++ ) { sum += *vi; } | NSEnumerator *i = [a objectEnumerator]; id o; while (o = [i nextObject]) { do something with o } | for ( String s : vec ) { do something with s } | foreach ( string s in l ) { do something with s } |
dictionaries | ||||
c++ | objective c | java | c# | |
pair | pair<int, float> p(7, 3.14); cout << p.first << ", " << p.second << endl; | using System.Collections.Generic; KeyValuePair<string,int> pr = new KeyValuePair<string,int>("hello",5); System.Console.WriteLine("{0} {1}", pr.Key, pr.Value); | ||
map declaration | #include <map> map<string, int> m; | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:10]; | java.util.TreeMap<String, Integer> m = new java.util.TreeMap<String, Integer>(); | using System.Collections.Generic; Dictionary<string, int> dict = new Dictionary<string, int>(); |
map access | m["hello"] = 5; cout << m["hello"]) << endl; | [dict setObject:@"5" forKey:@"hello"]; [dict objectForKey:@"hello"] | m.put("hello", 5); m.get("hello") | dict.Add("hello", 5); dict["hello"] |
map size | m.size() | [dict count] | m.size() | dict.Count |
map remove element | m.erase(m.find("hello")); | [dict removeObjectForKey:@"hello"]; | m.remove("hello"); | dict.Remove("hello"); |
map element not found result | NULL | NULL | null | throws KeyNotFoundException in System.Collections.Generic |
map iterate | map<string,int>::iterator mi; for (mi = m.begin(); mi != m.end(); mi++) { printf("%s %d", mi->first, mi->second) } | NSEnumerator *i = [dict keyEnumerator]; id key; while ((key = [i nextObject])) { do something with key } | for ( java.util.Map.Entry<String, Integer> e : m.entrySet() ) { use e.getKey() or e.getValue() } | foreach ( KeyValuePair<string,int> e in dict) { use e.Key and e.Value } |
user-defined types | ||||
c++ | objective c | java | c# | |
typedef | typedef int customer_id; customer_id cid = 3; | typedef int customer_id; customer_id cid = 3; | none | none |
enum | enum day_of_week { mon, tue, wed, thu, fri, sat, sun }; day_of_week d = tue; | enum day_of_week { mon, tue, wed, thu, fri, sat, sun }; enum day_of_week d = tue; | public enum DayOfWeek { MON, TUE, WED, THU, FRI, SAT, SUN }; DayOfWeek d = DayOfWeek.TUE; | public enum DayOfWeek { MON, TUE, WED, THU, FRI, SAT, SUN }; DayOfWeek d = DayOfWeek.TUE; |
struct definition | class MedalCount { public: const char *country; int gold; int silver; int bronze; }; | struct medal_count { const char* country; int gold; int silver; int bronze; }; | public class MedalCount { public String country; public int gold; public int silver; public int bronze; } | public class MedalCount { public string country; public int gold; public int silver; public int bronze; } |
struct declaration | MedalCount spain; | struct medal_count spain; | MedalCount spain = new MedalCount(); | MedalCount spain = new MedalCount(); |
struct initialization | MedalCount spain = { "Spain", 3, 7, 4 }; | struct medal_count spain = { "Spain", 3, 7, 4}; struct medal_count france = { .gold = 8, .silver = 7, .bronze = 9, .country = "France" }; | no object literal syntax; define a constructor | no object literal syntax; define a constructor |
struct member assignment | spain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4; | spain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4; | spain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4; | spain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4; |
struct member access | int spain_total = spain.gold + spain.silver + spain.bronze; | int spain_total = spain.gold + spain.silver + spain.bronze; | int spain_total = spain.gold + spain.silver + spain.bronze; | int spain_total = spain.gold + spain.silver + spain.bronze; |
functions | ||||
c++ | objective c | java | c# | |
pass by value | void use_integer(int i) { // function body } int i = 7; | void use_integer(int i) { function body } int i = 7; use_integer(i); | primitive types are always passed by value | primitive types are always passed by value |
pass by address | void use_iptr(int *i) { function body } int i = 7; use_iptr(&i); | void use_iptr(int *i) { function body } int i = 7; use_iptr(&i); | none | none |
pass by reference | void use_iref(int& i) { printf("using iref: %d", i); } int i = 7; use_iref(i); | none | objects and arrays are always passed by reference | objects and arrays are always passed by reference |
default argument value | float log(float exp, float base=10.0) { | none | use method overloading | use method overloading |
named parameters | none | +(float)weight: (float) w height: (float) h { return (w * 703) / (h * h); } +(float)height: (float) h weight: (float) w { return [BMI weight: w height: h]; } [BMI weight:155 height:70]; [BMI height:70 weight:155]; | none | added in C# 4.0: static int BMI(int weight, int height) { return (weight * 703) / (height * height); } BMI(weight: 123, height: 64); BMI(height: 64, weight: 123); |
function overloading | yes | method overloading only | yes | yes |
variable number of arguments | use C; use default values or function overloading for finite number of arities | use C; use method overloading for finite arities | public static String concat(String first, String… rest) { StringBuilder sb = new StringBuilder(first); for (String arg: rest) { sb.append(arg); } return sb.toString(); } String s = Concat.concat("Hello", ", ", "World", "!"); | public static string concat(params string[] args) { return System.String.Join("",args); } string s = Concat.concat("Hello", ", ", "World", "!") |
passing functions | ||||
anonymous function | ||||
operator overloading | Rational Rational::operator+(Rational& o) { return Rational(this->num*o.denom + o.num*this->denom, this->denom * o.denom); } | none | none | public static Rational operator+(Rational a, Rational b) { return new Rational(a.num*b.denom + b.num *a.denom,a.denom*b.denom); } |
execution control | ||||
c++ | objective c | java | c# | |
if | int signum; if (n > 0) { | if (i>0) { signum = 1; } else if (i==0) { signum = 0; } else { signum = -1; } | if (i>0) { signum = 1; } else if (i==0) { signum = 0; } else { signum = -1; } | if (i>0) { signum = 1; } else if (i==0) { signum = 0; } else { signum = -1; } |
switch | const int INVALID_BINARY_DIGIT(-1); int bindigit; switch(n) { | switch(i) { case 0: 0; break; case 1: 1; break; default: -1; break; } | switch(i) { case 0: 0; break; case 1: 1; break; default: -1; break; } | switch(i) { case 0: 0; break; case 1: 1; break; default: -1; break; } |
while | int i(1), fact(1), n(10); while (i < n) { | int i = 0; while (i<10) { … i++; } | int i = 0; while (i<10) { … i++; } | int i = 0; while (i<10) { … i++; } |
for | int i, fact, n(10); for (i = 1, fact = 1; i <= n; i++) { | int i, n; for (i=1,n=1; i<=10; i++) { n *= i; } | int n = 1; for (int i=1; i<=10; i++) { n *= i; } | int i, n; for (i=1,n=1; i<=10; i++) { n *= i; } |
throw exception | throw exception(); | NSException *exc = [NSException exceptionWithName:@"error" reason:@"failed" userInfo:nil]; @throw exc; | throw new Exception("failed"); | throw new System.Exception("failed"); |
catch exception | try { throw exception(); } catch (exception& e) { cout << "failed" << endl; } | @try { [NSException raise:@"error" format:@"failed"]; } @catch (NSException *e) { printf([[e reason] UTF8String]); } | try { throw new Exception("failed"); } catch (Exception e) { System.out.println(e.getMessage()); } | try { throw new System.Exception("failed"); } catch (System.Exception e) { System.Console.WriteLine(e.Message); } |
finally clause | use local object with destructor | @try { risky code } @finally { perform cleanup } | try { risky code } finally { perform cleanup } | try { risky code } finally { perform cleanup } |
methods must declare exceptions | no | no | yes | no |
file handles | ||||
c++ | objective c | java | c# | |
standard file handles | cin cout cerr clog | System.in System.out System.err | ||
printf | cout << "count: " << 7 << endl; | printf("count: %d\n", 7); | System.out.printf("count: %d", 7); | System.Console.WriteLine("count: {0}", 7); |
read from file | #include <fstream> string line; ifstream f("/etc/passwd"); if (f.is_open()) { while (!f.eof()) { getline(f, line); process line } f.close(); if ( 0 != f.fail() ) { handle error } } else { handle error } | NSError *error = nil; NSString *s = [NSString stringWithContentsOfFile: @"/etc/passwd" encoding:NSUTF8StringEncoding error:&error]; if ( error != nil ) { handle error } NSArray *a = [s componentsSeparatedByString:@"\n"]; id line; while (line = [i nextObject]) { process line } | import java.io.BufferedReader; import java.io.FileReader; BufferedReader in = new BufferedReader(new FileReader("/etc/passwd")); | using System.IO; StreamReader sr = new StreamReader("/etc/passwd"); string line; while ((line = sr.ReadLine()) != null) { use line } |
write to file | #include <fstream> ofstream f("/tmp/test4"); int i; for (i=0; i<10; i++) { f << i << endl; } f.close(); if (0 != f.fail()) { handle error } | import java.io.BufferedWriter; import java.io.FileWriter; BufferedWriter fout = new BufferedWriter(new FileWriter("/tmp/test2")); int i; for (i=0; i<10; i++) { fout.write(String.format("%d", i)); fout.newLine(); } fout.close(); | using System.IO; StreamWriter fout = new StreamWriter("/tmp/test3"); int i; for (i=0; i<10; i++) { fout.WriteLine(i.ToString()); } fout.Close(); | |
files | ||||
c++ | objective c | java | c# | |
file exists test, file regular test | import java.io.File; File f = new File("/etc/hosts"); | System.IO.File.Exists("/etc/hosts") | ||
file size | import java.io.File; File f = new File("/etc/hosts"); | |||
is file readable, writable, executable | import java.io.File; File f = new File("/etc/hosts"); f.canRead() | |||
set file permissions | import java.io.File; File f = new File("/tmp/foo"); // sets owner perms; to turn perms off // if 2nd arg is false, perms are | |||
copy file, remove file, rename file | import java.io.File; ?? File f2 = new File("/tmp/foo"); File f3 = new File("/tmp/bar"); | |||
directories | ||||
c++ | objective c | java | c# | |
build pathname | import java.io.File; File root = File.listRoots()[0]; | |||
dirname and basename | #include <libgen.h> string s1 = dirname("/etc/hosts"); | import java.io.File; File f = new File("/etc/hosts"); | ||
absolute pathname | #include <climits> #include <cstdlib> char buf[PATH_MAX]; | import java.io.File; File f = new File("foo"); // getCanonicalPath() expands .. and .: | ||
iterate over directory by file | import java.io.File; File dir = new File("/etc"); // iterate over names: // iterate over file objects: | |||
glob paths | ||||
make directory | import java.io.File; File f = new File("/tmp/foo/bar"); | |||
recursive copy | ||||
remove empty directory | ||||
remove directory and contents | ||||
directory test | import java.io.File; File f = new File("/tmp"); | |||
generate unused directory name | ||||
system temporary file directory | ||||
processes and environment | ||||
c++ | objective c | java | c# | |
signature of main | int main(int argc, char **argv) { | int main(int argc, char **argv) { | public class Foo { public static void main(String[] args) { | public class Foo { public static void Main(string[] args) { |
first argument | pathname of executable | pathname of executable | first command line argument | first command line argument |
environment variable | #include <stdlib.h> char *home = getenv("HOME"); setenv("EDITOR", "emacs", 1); unsetenv("EDITOR"); | NSString *home = [[[NSProcessInfo processInfo] environment] objectForKey:@"HOME"]; | String home = System.getenv("HOME"); | using System.Environment; string home = GetEnvironmentVariable("HOME"); SetEnvironmentVariable("EDITOR", "emacs"); SetEnvironmentVariable("EDITOR", null); |
iterate through environment variables | NSEnumerator *i = [[[NSProcessInfo processInfo] environment] keyEnumerator]; id key; while ((key = [i nextObject])) { use NSString key } | import java.util.Map; Map<String, String> env = System.getenv(); for (String name : env.keySet()) { String value = env.get(name)); } | using System.Collections; using System.Environment; IDictionary env = GetEnvironmentVariables(); foreach (DictionaryEntry de in env) { use de.Key or de.Value } | |
libraries and namespaces | ||||
c++ | objective c | java | c# | |
standard library name | C++ Standard Library | Foundation Framework | Java API | Base Class Library |
declare namespace | namespace foo { namespace bar { class Baz { static const int ANSWER = 42; }; } } | package foo.bar; public class Baz { public static final int ANSWER = 42; } | namespace foo { namespace bar { public class Baz { public const int ANSWER = 42; }; } } | |
multiple namespaces per file | yes | no | yes | |
namespaces map to directories | no | yes | no | |
import namespace | using namespace foo::bar; cout << Baz::ANSWER << endl; | import foo.bar.*; System.out.println(Baz.ANSWER); | using foo.bar; System.Console.WriteLine(Baz.ANSWER); | |
import part of namespace | using namespace foo; cout << bar::Baz::ANSWER << endl; | none | none | |
import symbol | using foo::bar::Baz; cout << Baz::ANSWER << endl; | import foo.bar.Baz; System.out.println(Baz.ANSWER); | none | |
import static symbol | none | import static foo.bar.Baz.ANSWER; System.out.println(ANSWER); | none | |
import position | anywhere a statement is legal | after package and before type definitions | outside of class definitions | |
using a symbol that hasn't been imported | cout << foo::bar::Baz::ANSWER << endl; | System.out.println(foo.bar.Baz.ANSWER); | using System.Console; WriteLine(foo.bar.Baz.ANSWER); | |
application environment | ||||
multiple installations | set JAVA_HOME environment variable to directory containing a bin subdirectory with java, javac, and other command line tools. Put $JAVA_HOME/bin at front of search path. | |||
package manager | ||||
objects | ||||
c++ | objective c | java | c# | |
semantics of == | value comparison | object identity comparison | object identity comparison | value comparison |
define class | Rational.hpp: class Rational { public: int num, denom; Rational(int num, int denom); virtual ~Rational(); Rational operator+(Rational& addend); static Rational max(Rational& a, Rational& b); }; | Rational.h: #import <Foundation/Foundation.h> @interface Rational : NSObject { int num; int denom; } @property int num, denom; -(Rational*) initWith: (int) n: (int) d; -(Rational*) add: (Rational *) o; @end Rational.m: #include "Rational.h" @implementation Rational @synthesize num, denom; -(Rational*) add: (Rational*) o { int sum_n = self.num * o.denom + o.num * self.denom; int sum_d = self.denom * o.denom; Rational* sum = [[Rational alloc] initWith: sum_n: sum_d]; return sum; } @end | public class Rational { public int num; public int denom; public Rational add(Rational o) throws Exception { return new Rational(this.num*o.denom + o.num*this.denom,this.denom*o.denom); } public static Rational max(Rational a, Rational b) { return (a.num*b.denom > a.num*b.denom) ? a : b; } } | public class Rational { public int num; public int denom; } |
class definition location | top level, class block, or function block | top level | top level, class block, or function block for anonymous classes | |
constructor | Rational::Rational(int n, int d) : num(n), denom(d) { if (denom == 0) { throw "zero denominator"; } int div = gcd(n,d); num = num / div; denom = denom / div; } | -(Rational*) initWith: (int) n: (int) d { self = [super init]; if (self) { self.num = n; self.denom = d; } return self; } | public Rational(int n, int d) throws Exception { if (d == 0) { throw new Exception("zero denominator"); } if ( d < 0 ) { this.num = -1 * n; this.denom = -1 * d; } else { this.num = n; this.denom = d; } } | public Rational(int n, int d) { if (0 == d) { throw new System.Exception("zero denominator"); } if (d < 0) { this.num = -1 * n; this.denom = -1 * d; } else { this.num = n; this.denom = d; } } |
create object | Rational r1(7,3); Rational *r2 = new Rational(8,5); | Rational *r = [[Rational alloc] initWith: 7: 3]; | Rational r = new Rational(7,3); | Rational r = new Rational(7,3); |
destructor | Rational::~Rational() {}; | -(void) dealloc { [super dealloc]; printf("deallocated…"); } | protected void finalize() throws Throwable { super.finalize(); } | ~Rational() { perform cleanup } |
destroy object | delete r2; | [r release]; | none | none |
define method | int Rational::height() { return (abs(num) > abs(denom)) ? abs(num) : abs(denom); } | -(int) height { if ( abs(self.num) > abs(self.denom) ) { return abs(self.num); } return abs(self.denom); } | public int height() { return (Math.abs(this.num) > this.denom) ? Math.abs(this.num) : this.denom; } | public int Height() { return (System.Math.Abs(this.num) > this.denom) ? System.Math.Abs(this.num) : this.denom; } |
invoke method | r1.height(); r2->height(); | [r1 height]; | r.height(); | r.Height(); |
dynamic dispatch | declare as virtual in base class | dispatch always dynamic | dispatch dynamic by default | declare as virtual in base class and override in derived class |
static dispatch | dispatch static by default | dispatch always dynamic | declare as final, private, or static (i.e. make it a class method) | dispatch static by default; compiler error if same method defined in base and derived class and not marked virtual in base class |
define class method | declare static in class definition | precede definition with +: +(Rational*) max: (Rational*) a: (Rational*) b { if ( a.num * b.denom > b.num * a.denom ) { return a; } return b; } | declare static in class definition | declare static in class definition |
invoke class method | ||||
name of receiver | this | self | this | this |
access control | access keywords define regions: class Foo { int privateInt1; int privateInt2; public: int publicInt1; int publicInt2; protected: int protectedInt1; int protectedInt2; private: int privateInt3; int privateInt4; }; | access keywords define regions: @interface Foo : NSObject { int protectedInt1; int protectedInt2; @public int publicInt1; int publicInt2; @protected int protectedInt3; int protectedInt4; @private int privateInt1; int privateInt2; } @end | access keywords required for methods and members: public class Foo { private int privateInt; protected int protectedInt; public int publicInt; } | access keywords available for methods and members: public class Foo { private int privateInt1; int privateInt2; protected int protectedInt; public int publicInt; } |
anonymous class | possible but not useful | none | (new Object() { public void hello() { System.out.println("hello!"); } }).hello(); | |
subclass | class Integer : public Rational { public: Integer(int n); virtual ~Integer(); }; | public class RInteger extends Rational { public RInteger(int n) throws Throwable { super(n, 1); } } | ||
invoking superclass constructor | Integer::Integer(int n) : Rational(n, 1) { } | super(n, 1); | ||
mark class underivable or method unoverrideable | none | none | final | sealed |
root class | none | NSObject | java.lang.Object | System.Object |
root class methods | none | autorelease class conformsToProtocol: hash isEqual: isKindOfClass: isProxy performSelector: performSelector:withObject: performSelector:withObject:withObject: release respondsToSelector: retain retainCount self superclass | clone() equals() finalize() getClass() hashCode() toString() | Equals() Finalize() GetHashCode() GetType() MemberwiseClone() ReferenceEquals() ToString() |
generic types | ||||
c++ | objective c | java | c# | |
define generic type | template <class A> class Foo { public: A a; Foo(A a); }; template <class A> Foo<A>::Foo(A a) : a(a) { } | public class Foo<A> { public A a; public Foo(A a) { this.a = a; } } | public class Foo<A> { public A a; public Foo(A a) { this.a = a; } } | |
instantiate generic type | Foo<string> f = Foo<string>("foo"); | Foo<String> f = new Foo<String>("foo"); | Foo<string> f = new Foo<string>("foo"); | |
generic function | template <class C> C add(C a, C b) { return a + b; } | |||
generic array | template <class C> class Foo { public: C a[10]; }; | not permitted. Use Object as the element type for the array or use an ArrayList. | public class Bar<C> { public C[] a; public Bar(C c) { this.a = new C[10]; } } | |
value parameter | template <int N> int add(int i) { return N+i; } cout << add<7>(3) << endl; | |||
template parameter | ||||
template specialization | ||||
multiple type parameters | template <class A, class B> class Pair { public: A a; B b; Pair(A a, B b); }; template <class A, class B> Pair<A, B>::Pair(A a, B b) : a(a), b(b) { } Pair<int, string> p = Pair<int, string>(7, "foo"); | |||
generic type parameters | Pair<int, Foo<string> > p = Pair<int, Foo<string> >( 7, Foo<string>("foo")); | |||
template parameters | ||||
reflection | ||||
c++ | objective c | java | c# | |
get type class of object | o = new Object(); Class c = o.getClass(); | object o = new object(); System.Type t = o.GetType(); or System.type t = typeof(o); | ||
get type class from string | Class c = Class.forName("java.io.File"); | using System; Type t = Type.GetType("object"); | ||
get type class from type identifier | typeid(Foo) | System.Type t = typeof(object); | ||
class name | typeid(Foo).name() | String name = c.getName(); | t.ToString(); | |
get methods | import java.lang.reflect.*; Method[] m = c.getMethods(); | using System.Reflection; System.Type t = typeof(object); MethodInfo[] a = t.GetMethods(); | ||
has method | import java.lang.reflect.*; Class c = Class.forName("java.io.File"); Method[] a = c.getMethods(); boolean hasMethod = false; for (int i=0; i < a.length; i++) { if (a[i].getName() == "toString") { hasMethod = true; } } | null if method not found: MethodInfo m = t.GetMethod("ToString"); | ||
invoke method object | import java.lang.reflect.*; Class c = Class.forName("java.io.File"); Method m = c.getMethod("toString"); Object o = new Object(); m.invoke(o); | m.Invoke(o); | ||
net and web | ||||
c++ | objective c | java | c# | |
url encode/decode | import java.net.URLEncoder; import java.net.URLDecoder; String url = "http://www.google.com"; | |||
unit tests | ||||
c++ | objective c | java | c# | |
test class | $ cat > test_foo.cpp #include <cppunit/TestCaller.h> #include <cppunit/TestCase.h> #include <cppunit/TestSuite.h> #include "test_foo.h" using namespace CppUnit; void TestFoo::test_01() { Test * TestFoo::suite() { return suiteOfTests; $ cat > test_foo.h class TestFoo: public CppUnit::TestCase { static CppUnit::Test *suite(); | |||
run all tests | $ cat > test_runner.cpp #include <cppunit/ui/text/TestRunner.h> #include "test_foo.h" int main( int argc, char **argv) $ sudo apt-get install libcppunit-dev $ cat > Makefile check: test_runner $ make check | |||
equality assertion | #include <cppunit/TestCase.h> CPPUNIT_ASSERT_EQUAL(1, 1); | |||
approximate assertion | ||||
exception assertion | ||||
setup | ||||
teardown | ||||
debugging and profiling | ||||
c++ | objective c | java | c# | |
debugger commands help, list source, (re)load executable, next, step, set breakpoint, show breakpoints, delete breakpoint, continue, backtrace, up stack, down stack, print, run, quit | > h > l [FIRST_LINENO, LAST_LINENO] > file PATH > n > s > b [FILE:]LINENO > i > d NUM > c > bt > up > do > p EXPR > r [ARG1[, [ARG2 ...]] > q | |||
_______________________________________________ | _______________________________________________ | _______________________________________________ | _______________________________________________ |
General
version used
The compiler version used for this sheet.
show version
How to get the compiler version.
implicit prologue
Code which examples in the sheet assume to have already been executed.
Grammar and Invocation
hello world
How to write, compile, and run a "Hello, World!" program.
file suffixes
For source files, header files, and compiled object files.
c++
The gcc compiler will treat a file with any of the following suffixes as C++ source:
.cc .cp .cxx .cpp .CPP .c++ .C
GNU make has built-in rules which treat the following suffixes as C++ source:
.cc .C .cpp
block delimiters
How blocks are delimited.
A block contains a sequence of statements. Blocks for function bodies in function definitions; to define the branches of if statements and the bodies of while loops.
Class definition bodies are blocks, though the statements that appear in them are restricted to declarations and definitions.
Bare blocks can be used to limit the scope of variables which are declared inside them.
statement terminator
How statements are terminated.
top level statements
Statements that can appear at the top level of a source file.
end-of-line comment
The syntax for a comment which is terminated by the end of the line.
multiple line comment
The syntax for a comment which can span multiple lines.
The /* */ delimiters do not nest. Using them to comment out code which already contains a /* */ comment usually results in a syntax error.
Variables and Expressions
local variable
How to declare a variable which is allocated on the stack.
uninitialized local variable
The value contained by a local variable that wasn't initialized.
global variable
How to declare a global variable.
constant
How to declare a constant variable.
allocate heap
How to allocate memory for a primitive type on the heap.
c++
new and delete can be used to manage the memory of both primitive types and objects.
objective c
Object C has a different memory management schemes for primitive types and objects. Objects are allocated with alloc and freed by means of NSAutoreleasePool. For primitive types the same techniques are used as for C. However, idiomatic Objective C will declare primitive types as local variables or as part of the state of an object and avoid explicit calls to malloc.
Arrays of objects can be created with NSArray and NSMutableArray.
java
In Java, arrays are always stored on the heap and the JVM is responsible for garbage collection. The primitive types are stored (1) on the local frame, (2) as part of the state of an object, or (3) as part of the state of a class. The primitive types are never stored in the heap directly and when they are part of object state they are garbage collected with the object. Primitive types are passed by value unless they are encapsulated in an object.
Each of the primitive types has a wrapper class, and instantiating this class is the best approximation in Java to allocating the primitive type on the heap:
Integer i = new Integer(0);
The compiler may instantiate the wrapper class implicitly; this is called boxing. The compiler also permits use of a wrapper class in the place of the primitive type, or unboxing.
C#
C# behavior is like Java. Note that C# lacks specific wrapper classes for each primitive data type.
free heap
How to free the memory for a primitive type that was allocated on the heap.
null
C++
A typical definition:
const int NULL = 0;
coalesce
The equivalent of the COALESCE function from SQL.
C++, Objective C++:
The short circuit or operator || can be used as a coalesce operator. However, in C++ and Objective C, NULL is identical to zero, whereas in databases they are two distinct values.
Java:
The ternary operator provides the closest approximation to COALESCE, but it does not have the same behavior if the tested value has a side effect.
Arithmetic and Logic
boolean type
C
The following definitions are common:
typedef int BOOL;
#define TRUE 1
#define FALSE 0
Objective C
From objc.h:
typedef signed char BOOL;
#define YES (BOOL)1
#define NO (BOOL)0
C#
bool is an alias for System.Boolean
true and false
Literals for the boolean values true and false.
C
The following definitions are common:
typedef int BOOL;
#define TRUE 1
#define FALSE 0
Objective C
From objc.h:
typedef signed char BOOL;
#define YES (BOOL)1
#define NO (BOOL)0
falsehoods
Values which evaluate as false in the conditional expression of an if statement.
logical operators
The logical operators.
In all languages on this sheet the && and || operators short circuit: i.e. && will not evaluate the 2nd argument if the 1st argument is false, and || will not evaluate the 2nd argument if the 1st argument is true. If the 2nd argument is not evaluated, side-effects that it contains are not executed.
C++
C++ defines and, or, and not to be synonyms of &&, ||, and !, with the same semantics and precedence.
Java
The arguments of the logical operators must be of type boolean.
C#
The arguments of the logical operators must be of type bool.
relational operators
Binary operators which return boolean values.
integer type
Signed integer types.
C++
Whether char is a signed or unsigned type depends on the implementation.
C#
C# has the following aliases:
sbyte: System.SByte
short: System.Int16
int: System.Int32
long: System.Int64
unsigned type
Unsigned integer types.
C++
Whether char is a signed or unsigned type depends on the implementation.
C#
C# has the following aliases:
byte: System.Byte
ushort: System.UInt16
uint: System.UInt32
ulong: System.UInt64
float type
Floating point types.
C#
C# has the following aliases:
float: System.Single
double: System.Double
fixed type
Fixed-point decimal types.
C#:
C# has the following alias:
decimal: System.Decimal
arithmetic operators
The arithmetic binary operators: addition, subtraction, multiplication, division, modulus.
integer division
How to get the quotient of two integers.
integer division by zero
The results of integer division by zero.
C++, Objective C
The behavior for division by zero is system dependent; the behavior described is nearly universal on Unix.
C#
It is a compilation error to divide by a zero constant. Division by a variable set to zero results in a runtime exception.
float division
How to perform floating point division on two integers.
float division by zero
The result of floating point division by zero.
Modern hardware, if it implements floating point instructions, will
implement instructions which conform to the IEEE 754 standard. The
standard requires values for positive infinity, negative infinity, and
not-a-number (NaN).
The C and C++ standards do not assume that they are running on
hardware which provides these values; code which assumes they exist is
not strictly speaking portable.
power
How to perform exponentiation.
C++
powm1 is an abbreviation for "power minus one". Hence the need to add one to get the answer.
sqrt
The positive square root function.
sqrt -1
The result of taking the square root of a negative number.
Here is a list of the standard mathematical functions whose domains do not cover the entire real number line:
function | returns inf on | returns nan on | returns -inf on |
---|---|---|---|
sqrt | inf | [-inf, 0) | |
log | inf | [-inf, 0) | 0 |
asin | [-inf, -1) U (1, inf] | ||
acos | [-inf, -1) U (1, inf] |
transcendental functions
The exponential and logarithm functions; the trigonometric functions; the inverse trigonometric functions.
The arguments of the trigonometric functions are in radians as are the return values of the inverse trigonometric functions.
transcendental constants
The transcendental constants e and pi.
float truncation
Functions for converting a float to a nearby integer value.
C:
The math.h library also provides floor and ceil which return double values.
Java:
Math.floor and Math.ceil return double values.
absolute value
The absolute value of a numeric quantity.
integer overflow
What happens when an integer expression results in a value larger than what can be stored in the integer type.
float overflow
What happens when a float expression results in a value larger than largest representable finite float value.
float limits
The largest finite floating point number and the smallest positive floating point number.
complex construction
How to construct a complex number.
complex decomposition
How to get the components of a complex number. Both Cartesian and
polar decompositions are illustrated. Also how to get the complex
conjugate.
random number
Ways to generate random numbers. The distributions are a uniform
integer from 0 to 99; a uniform float from 0.0 to 1.0; a standard normal
float.
c++:
The standard library includes functions for generating random numbers from other distributions.
random seed
How to set the seed for the random number generator.
bit operators
The bit operators: left shift, right shift, and, or, xor, and complement.
C++
bitand, bitor, and compl are synonyms of &, |, and ~ with identical precedence and semantics.
binary, octal, and hex literals
Binary, octal, and hex integer literals.
radix
How to convert integers to strings of digits of a given base. How to convert such strings into integers.
Strings
string type
The type for strings.
string literal
The syntax for string literals.
newline in literal
Can a newline be used in a string literal? Does the newline appear in the resulting string object?
literal escapes
Escape sequences that can be used in string literals.
allocate string
How to allocate a string.
Java
The following code
String t = new String(s);
creates a copy of the string s. However, because Java strings are immutable, it would be safe to store the same string object it t as follows:
String t = s;
are strings mutable?
copy string
format string
compare strings
C++
string::compare returns a positive value, 0, or a negative value depending upon whether the receiver is lexicographically greater, equal, or less than the argument. C++ overload the comparison operators (<, >, ==, !=, <=, >=) so that they can be used for string comparison.
Objective C
compare will return -1, 0, or 1.
Java
compareTo will return a negative value, 0, or a positive value.
C#
CompareTo will return -1, 0, or 1.
concatenate
replicate
translate case
trim
pad
number to string
string to number
C++
strtoimax, strtol, strtoll, strtoumax, strtoul, and strtoull take three arguments:
intmax_t
strtoimax(const char *str, char **endp, int base);
The 2nd argument, if not NULL, will be set to first character in the string that is not part of the number. The 3rd argument can specify a base between 2 and 36.
strtof, strtod, and strtold take three arguments:
double
strtod(const char *str, char **endp);
Java
parseInt has an optional second argument for the base.
join
java:
Use StringBuilder to implement join:
public static String join(String[] a, String sep) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<a.length; i++) {
if (i > 0) {
sb.append(sep);
}
sb.append(a[i]);
}
return sb.toString();
}
split
serialize
string length
index of substring
extract substring
character type
character literal
test character
Regular Expressions
regex match
regex substitute
Date and Time
date and time type
The data type used to store a combined date and time.
current date and time
How to get the current date and time.
to unix epoch, from unix epoch
How to convert a date/time object to the Unix epoch. How to convert the Unix epoch to a date/time object.
The Unix epoch is the number of seconds since 1 January 1970 UTC.
c#:
Windows file time is the number of nanoseconds since 1 January 1601 UTC divided by 100. The concept was introduced when journaling was added to NTFS with Windows 2000.
The magic constant (1164444480) used for the conversion can be calculated with the following code:
using System;
using System.Globalization;
CultureInfo enUS = new CultureInfo("en-US");
DateTime startEpoch = DateTime.ParseExact("1970-01-01 00:00:00 -00", "yyyy-MM-dd HH:mm:ss zz", enUS);
Console.WriteLine(startEpoch.ToFileTimeUtc() / (100*1000*1000));
format date
How to use a format string to display a date/time object.
The canonical example of doing this is the strftime function from the C standard library which defines used letters prefix by percent signs as conversion specification characters, e.g. %Y-%m-%d.
parse date
How to use a format string to parse date data from a string.
date subtraction
add duration
date parts
time parts
Arrays
allocate array on stack
How to allocate an array on the stack.
allocate array on heap
How to allocate an array on the heap.
free array on heap
How to free an array that was allocated on the heap.
array literal
Objective C
NSArray can only store instances of NSObject. For primitive types, use C arrays.
Java
Java permits arrays to be declared with C-style syntax:
int a[] = {1,2,3}
array element access
C
Arrays can be manipulated with pointer syntax. The following sets x and y to the same value:
int a[] = {3,7,4,8,5,9,6,10};
int x = a[4];
int y = *(a+4);
array out-of-bounds result
array iteration
C
C arrays do not store their size, so C developers normally store this information in a separate variable. Another option is to use a special value to mark the end of the array:
char *a[] = { "Bob", "Ned", "Amy", NULL };
int i;
for (i=0; a[i]; i++) {
printf("%s\n", a[i]);
}
vector declaration
vector push
vector pop
vector size
vector access
vector out of bounds
vector iteration
Dictionaries
pair
map declaration
C:
For those interested in an industrial strength hashtable implementation for C, here is the header file and the source file for the hashtable used by Ruby.
For those interested in a "Computer Science 101" implementation of a hashtable, here is a simpler source file and header file.
map access
map size
map remove
map element not found result
map iterator
User-Defined Types
typedef
C
Because C integer types don't have well defined sizes, typedef is sometimes employed to as an aid to writing portable code. One might include the following in a header file:
typedef int int32_t;
The rest of the code would declare integers that need to be 32 bits in size using int32_t and if the code needed to be ported to a platform with a 16 bit int, only a single place in the code requires change. In practice the typedef abstraction is leaky because functions in the standard library such as atoi, strtol, or the format strings used by printf depend on the underlying type used.
Java
Java has well defined integer sizes so typedef is not needed as a portability aid. In other situations where a C programmer would use a typedef for data abstraction, a Java programmer must either define a class or retain the raw primitive type throughout the code.
enum
C
Enums were added to the C standard when the language was standardized by ANSI in 1989.
An enum defines a family of integer constants. If an integer value is not explicitly provided for a constant, it is given a value one greater than the previous constant in the list. If the first constant in the list is not given an explicit value, it is assigned a value of zero. it is possible for constants in a list to share values. For example, in the following enum, a and c are both zero and b and d are both one.
enum { a=0, b, c=0, d };
A typedef can be used to make the enum keyword unnecessary in variable declarations:
typedef enum { mon, tue, wed, thu, fri, sat, sun } day_of_week;
day_of_week d = tue;
From the point of view of the C compiler, an enum is an int. The C compiler does not prevent assigning values to an enum type that are not in the enumerated list. Thus, the following code compiles:
enum day_of_week { mon, tue, wed, thu, fri, sat, sun };
day_of_week d = 10;
typedef enum { mon, tue, wed, thu, fri, sat, sun } day_of_week2;
day_of_week2 d2 = 10;
C++
C++ enums are more strongly typed the C enums. The compiler rejects attempts to assign a value to an enum variable that is not in the enumerated list. The following code:
enum day_of_week { mon, tue, wed, thu, fri, sat, sun };
day_of_week d = 10;
produces an error like the following:
main.cpp: In function ‘int main()’:
main.cpp:21: error: invalid conversion from ‘int’ to ‘main()::day_of_week’
Java
Java added enums in 1.5.
Java enums are strongly typed like C++ enums. Unlike C++ enums, it is an error to use an enum value in an integer context. The value has a method ordinal() which returns the integer value, however.
When used in a string context, an enum will evaluate as the string corresponding to its identifier: i.e. "TUE" for DayOfWeek.TUE. This string can be accessed explicitly with DayOfWeek.TUE.toString(). Conversely, DayOfWeek.valueOf("TUE") returns DayofWeek.TUE.
Java enums are subclasses of java.lang.Enum. In particular, an enum is a class, and if the last value if the enum definition is followed by a semicolon, what follows is a class body which can contain methods and constructors. An enum class is final and cannot be subclassed, but an enum can implement an interface.
C#
Like Java enums, C# enums will return the string corresponding to their identifier. Unlike Java enums, C# enums will evaluate as integers in a numeric context.
When used as an argument in a C# style format string, an enum value returns the string corresponding to its identifier.
struct definition
A struct provides names for elements in a predefined set of data and permits the data to be accessed directly without the intermediation of getters and setters. C++, Java, and C# classes can be used to define structs by making the data members public. However, public data members violates the uniform access principle.
C++:
From The C++ Programming Language: 3rd Edition:
by definition, a struct is a class in which members are by default public; that is,
struct s { ...
is simply shorthand for
class s { public: ...
struct declaration
struct initialization
C
The literal format for a struct can only be used during initialization. If the member names are not provided, the values must occur in the order used in the definition.
struct member assignment
struct member access
C
The period operator used for member access has higher precedence than the pointer operator. Thus parens must be used
to get at the member of a struct referenced by a pointer:
struct medal_count {
char* country;
int gold;
int silver;
int bronze;
}
struct medal_count spain = { "Spain", 3, 7 4 };
struct medal_count *winner = &spain;
printf("The winner is %s with %d gold medals", (*winner).country, (*winner).gold);
ptr->mem is a shortcut for (*ptr).mem:
printf("The winner (%s) earned %d silver medals", winner->country, winner->silver);
Functions
pass by value
pass by address
pass by reference
default argument value
named parameters
objective C:
Named parameters must be invoked in the order in which they are defined in the method signature.
C#:
Named parameter do not need to be invoked in the order in which they are defined in the method signature. Additionally, their use in
invocation is optional: the arguments can be provided without names in which case the definition order must be used.
function overloading
variable number of arguments
C
The stdarg.h library supports variable length functions, but provides
no means for the callee to determine how many arguments were provided.
Two techniques for communicating the number of arguments to the caller
are (1) devote one of the non-variable arguments for the purpose as
illustrated in the table above, or (2) set the last argument to a
sentinel value as illustrated below. Both techniques permit the caller
to make a mistake that can cause the program to segfault. printf uses
the first technique, because it infers the number of arguments from the number of format specifiers in the format string.
char* concat(char* first, ...) {
int len;
va_list ap;
char *retval, *arg;
va_start(ap, first);
len = strlen(first);
while (1) {
arg = va_arg(ap, char*);
if (!arg) {
break;
}
len += strlen(arg);
}
va_end(ap);
retval = calloc(len+1,sizeof(char));
va_start(ap, first);
strcpy(retval, first);
len = strlen(first);
while (1) {
arg = va_arg(ap, char*);
if (!arg) {
break;
}
printf("copying %s\n", arg);
strcpy(retval+len, arg);
len += strlen(arg);
}
va_end(ap);
return retval;
}
An example of use:
string *s = concat("Hello", ", ", "World", "!", NULL);
passing functions
anonymous function
operator overloading
Execution Control
for
if
For all five languages, the curly braces surrounding an if or else clause are optional if the clause contains a single statement. All five languages resolve resulting dangling else ambiguity by setting the value of c to 2 in the following code:
int a = 1;
int b = -1;
int c = 0;
if (a > 0)
if (b > 0)
c=1;
else
c= 2;
while
If the body of a while loop consists of a single statement the curly braces are optional:
int i = 0;
while (i<10)
printf("%d\n", ++i);
switch
A switch statement branches based on the value of an integer or an integer expression. Each clause must be terminated by a break statement or execution will continue into the following clause.
throw exception
C++
C++ code can throw or catch any type of object or primitive data type. The C++ standard library throws subclasses of std::exception, which does not have a message member.
Objective C
Objective C can only throw an instance of NSException or one of its subclasses.
Java
Java can only throw an implementation of java.lang.Throwable.
C#
C# can only throw an instance of System.Exception of one of its subclasses.
catch exception
C++
Exceptions can be caught by value or by reference. If the exception is an object and it is caught by value, the copy constructor and the destructor will be invoked.
Objective C
Exceptions are thrown and caught by pointer value.
finally clause
C++
Class Finally {
void (*finally)();
Finally(void (*f)()) : finally(f) {
}
~Finally() {
do_cleanup();
}
};
{
Cleanup c();
risky();
}
methods must declare exceptions
Java
If a method throws a subclass of java.lang.Exception, it must declare the exception in its throws clause. This includes exceptions originating in code called by the method. On the other hand, if the method throws a subclass of java.lang.Error, no declaration in the throws clause is necessary.
File Handles
printf
How to print a formatted string to standard out.
read from file
C
If there is an error, the global variable errno will be set to a nonzero value, and strerror(errno) will return an error message for the error.
write to file
Files
Directories
Processes and Environment
signature of main
first argument
C
The first argument is the pathname to the executable. Whether the pathname is absolute or relative depends on how the executable was invoked. If the executable was invoked via a symlink, then the first argument is the pathname of the symlink, not the executable the symlink points to.
environment variable
iterate through environment variables
Library and Namespaces
standard library name
The name of the standard library.
C++
Standard Template Library (STL)
The STL might not be installed by default.
Objective C
The Foundation Framework is the core of Cocoa, a set of libraries for Objective C development on Mac OS X and the iPhone. The Foundation Framework descends from NextStep, hence the NS prefix in the class names. NextStep was made available to operating systems other than Next as OpenStep and the GNU implementation is called GNUStep.
Java
C#
.NET Framework 4 Class Library
Mono Documentation
The core of the .NET framework is called the Base Class Library. Mono implements the BCL, but not all of the .NET framework.
Objects
define class
constructor
create object
destructor
C++
The C++ compiler will normally see to it that the destructor for a
class and all its superclasses is called. The compiler may not be aware
of the true class of the object if it was upcast to one of its base
class. If the destructor was not declared virtual, then the derived
class destructor and any other base class constructors will not get
called. Thus many developers declare all destructors virtual.
Java
Java does not chain finalize() methods, so the derived class should explicitly call the parent.
destroy object
Java
finalize() is called by the Java garbage collector.
define method
invoke method
dynamic dispatch
static dispatch
Method dispatch is static if the method is determined by the variable type, and dynamic
if it is determined by the value type. These techniques of method
dispatch yield different results when both the base class and the
derived class have implementations for a method, and an instance of the
derived class is being stored in a variable with type of the base class.
When dispatch is static, the compiler can determine the code that
will be executed for the method call. When dispatch is dynamic, the code
that will be executed is a runtime decision. C++ implementations
usually achieve this by storing function pointers in the object: qv virtual method table.
The use of the keyword static in the declaration of a class
method in C++, Java, and C# is perhaps unfortunate. Class methods are
always statically dispatched, so the concepts are not unrelated.
define class method
invoke class method
name of receiver
access control
objective c:
Access control only applies to members; all methods are public. gcc
4.0 does not enforce the access restrictions; it merely gives warnings.
anonymous class
subclass
superclass constructor
mark class underivable or method overrideable
root class
Name of the root class, if there is one.
objective c:
It is possible to define a root class other than NSObject.
root class methods
A selection of methods available on the root class.
Generic Types
define generic type
instantiate generic type
Reflection
get type class of object
get type class from string
get type class from type identifier
c++:
typeid returns a value of type type_info. The assignment method and copy constructor of type_info are private.
class name
*c++:**
The string returned by type_info.name() contains more than the class name. The code below displayed the string "Z4mainE3Foo" when run on my system.
class Foo {
int i;
};
puts(typeid(Foo).name());
get methods
has method
invoke method object
Net and Web
url encode/decode
How to URL encode and URL decode a string.
URL encoding is also called percent encoding. It is used to escape special characters in GET query string parameters.
Reserved characters according to RFC 3986 are replaced by a percent sign % followed by a two hex digit representation of the ASCII code. The reserved characters are:
! * ' ( ) ; : @ & = + $ , / ? # [ ]
Spaces can optionally be represented by a plus sign +.
Unit Tests
Debugging and Profiling
C++
C++11 Standard (pdf)
Standard C++ Library Reference
The GNU C++ Library
Google C++ Style Guide
Designing Qt-Style C++ APIs
Objective-C
Programming with Objective-C Apple
GNUstep
Mac OS X Foundation Framework
Java
Java 1.6 API
JDK 7 Project
JVM Specification 2nd Ed
The Java Language Specification 3rd Ed