Skip to main content

C - Ritchie & Kernighan


In respectful memory of Dennis Ritchie, the true giant whose shoulders we have been standing on, for decades. 


Summarizing chapters as bullet points from the epic "C Programming Language" book. Good for anyone who wants to do a refresher on the C language, they dearly knew very well. Or to do a quick interview prep. 


Chapter 1-Introduction


  1. %[n]d – prints the integer in a space of 'n' characters wide,; if 'n' is not given, just prints the integer in as much space as needed
  2. %[[a][.b]]f-prints the floating point in space of width 'a' and with 'b' digits after decimal point
  3. %.0f suppresses the printing of the decimal point and the fraction part, which is zero.
  4. In C,a text stream is a sequence of characters divided into lines; each line consists of zero or more characters followed by a newline character.
  5. printf("End:%d",EOF); will print “End:-1”
  6. '\n' stands for the value of the newline character, which is 10 in ASCII
  7. white space characters are blank, tab, newline
  8. When the name of an array is used as an argument, the value passed to the function is the location or address of the beginning of the array - there is no copying of array elements
  9. Each local variable in a function comes into existence only when the function is called, and disappears when the function is exited. such variables are usually known as automatic variables
  10. An external variable must be defined, exactly once, outside of any function; this sets aside storage for it. The variable must also be declared in each function that wants to access it; this states the type of the variable. (the term external variable refers to a global variable)
  11. The declaration may be an explicit extern statement or may be implicit from context.If the definition of the external variable occurs in the source file before its use in a particular function, then there is no need for an extern declaration in the function.Otherwise it is needed.
  12. If the program is in several source files, and a variable is defined in file1 and used in file2 and file3, then extern declarations are needed in file2 and file3 to connect the occurrences of the variable. The usual practice is to collect extern declarations of variables and functions in a separate file, historically called a header
  13. For function names and external variables, the number of characters in the name may be less than 31, because external names may be used by assemblers and loaders over which the language has no control
     

Chapter2:Types,Operators and expressions

 


  1. Each compiler is free to choose appropriate sizes for its own hardware, subject only to
int>=16bits
long>=32bits
short<=int
int<=long
  1. Whether plain chars are signed or unsigned is machine-dependent, but printable characters are always positive.
  2. A long constant is written with a terminal l (ell) or L.Unsigned constants are written with a terminal u or U, and the suffix ul or UL indicates unsigned long.
  3. Octal and hexadecimal constants may also be followed by L to make them long and U to make them unsigned: 0XFUL is an unsigned long constant with value 15 decimal.
  4. an arbitrary byte-sized bit pattern can be specified by '\ooo' where ooo is one to three octal digits (0...7) or by '\xhh' where hh is one or more hexadecimal digits (0...9, a...f, A...F).
  5. The complete set of escape sequences 
a-alert (bell) character
\\-backslash
\b-backspace
\?-question mark
\f-formfeed
\'-single quote
\n-newline
\"-double quote
\r-carriage return
\ooo-octal number
\t-horizontal tab
\xhh-hexadecimal number
\v-vertical tab
  1. String constants can be concatenated at compile time:
"hello, " "world" is equivalent to "hello, world"
  1. The standard library function strlen(s) returns the length of its character string argument s, excluding the terminal '\0'
  2. Even character constants can be assigned to the names in a enum declaration because char constants are internally only numeric values
  3. Enumerations provide a convenient way to associate constant values with names, an alternative to #define with the advantage that the values can be generated for you
  4. If the variable in question is not automatic, the initialization is done once only, conceptionally before the program starts executing, and the initializer must be a constant expression.
  5. External and static variables are initialized to zero by default. Automatic variables for which is no explicit initializer have undefined (i.e., garbage) values.
  6. The % operator cannot be applied to a float or double.
  7. , the only automatic conversions are those that convert a ``narrower'' operand into a ``wider'' one without losing information, such as converting an integer into floating point
  8. atoi() , when provided with a string containing non-digit characters, returns the number represented by the input until the first non-digit character was encountered. Eg:atoi(12d3r) -> 12
  9. floats in an expression are not automatically converted to double;
  10. -1L > 1UL because -1L is promoted to unsigned long and thus appears to be a large positive number.
  11. -1L < 1U, because 1U, which is an unsigned int, is promoted to a signed long.
  12. Longer integers are converted to shorter ones or to chars by dropping the excess high-order bits. Eg 512 converted to char becomes 0 since the lower byte in 512 is 0
  13. the cast produces the value of variable in the proper type; variable itself is not altered
  14. If arguments are declared by a function prototype, as the normally should be, the declaration causes automatic coercion of any arguments when the function is called. Otherwise explicit casting is needed
  15. the expression ++n increments n before its value is used, while n++ increments n after its value has been used
  16. The increment and decrement operators can only be applied to variables; applying to an expression is illegal.
  17. Right shifting an unsigned quantity always fits the vacated bits with zero. Right shifting a signed quantity will fill with bit signs (``arithmetic shift'') on some machines and with 0-bits (``logical shift'') on others.
  18. Declaring a variable as unsigned makes it work with integers as well as chars , when performing bit wise operations
  19. For a number c, c&c-1 deletes the rightmost 1 bit. Hence the number of bits set in c can be calculated using (c=c&c-1) != 0
  20. & is used to mask or set some bits to 0; | is used to set some bits to 1
  21. | using 0's and & using 1's will yield the same number . Eg: c | 0 = c&1=c; c may be a sequence of 'n' bits
  22. To extract a 'n' bit field starting from 'pos' from 'c'. Right shift 'c' by 'pos' and & with a mask having n rightmost bits as 1 and rest of the bits 0
  23. Right Rotation of 'c' (represented using 'b' bits) by 'n' places can be done as follows
            1. x=c>>n
            2. y= Number having n rightmost digits of 'c' as its 'n' leftmost digits in the same order
            3. New c=x|y
  1. A terniary expression can return any type value as one of its results. The returned result values may also be of different types
    Operator
    Associativity
    () [] -> .
    left to right
    ! ~ ++ -- + - * (type) sizeof
    right to left
    * / %
    left to right
    + -
    left to right
    << >>
    left to right
    < <= > >=
    left to right
    == !=
    left to right
    &
    left to right
    ^
    left to right
    |
    left to right
    &&
    left to right
    ||
    left to right
    ?:
    right to left
    = += -= *= /= %= &= ^= |= <<= >>=
    right to left
    ,
    left to right

    1. Function calls, nested assignment statements, and increment and decrement operators cause ``side effects'' - some variable is changed as a by-product of the evaluation of an expression
    2. the order in which function arguments and the operands of operators are evaluated is not specified. So varyng results under various compilers
    3. In unix, while evaluating 'f() <op> g()' , f() is evaluated before g(). arguments are evaluated from right to left.Eg: g(++i,i++) call is resolved into g(i+2,i)



      To be continued ....

Comments

Popular posts from this blog

Thoughts On Adding Spatial Indexing to Voldemort

This weekend, I set out to explore something that has always been a daemon running at the back of my head. What would it mean to add Spatial Indexing support to Voldemort, given that Voldemort supports a pluggable storage layer.. Would it fit well with the existing Voldemort server architecture? Or would it create a frankenstein freak show where two systems essentially exist side by side under one codebase... Let's explore..

Basic Idea The 50000 ft blueprint goes like this.

Implement a new Storage Engine on top Postgres sql (Sorry innoDB, you don't have true spatial indexes yet and Postgres is kick ass)Implement a new smart partitioning layer that maps a given geolocation to a subset of servers in the cluster (There are a few ways to do this. But this needs to be done to get an efficient solution. I don't believe in naive spraying of results to all servers)Support "geolocation" as a new standard key serializer type in Voldemort. The values will still be  opaque b…

Learning Spark Streaming #1

I have been doing a lot of Spark in the past few months, and of late, have taken a keen interest in Spark Streaming. In a series of posts, I intend to cover a lot of details about Spark streaming and even other stream processing systems in general, either presenting technical arguments/critiques, with any micro benchmarks as needed.

Some high level description of Spark Streaming (as of 1.4),  most of which you can find in the programming guide.  At a high level, Spark streaming is simply a spark job run on very small increments of input data (i.e micro batch), every 't' seconds, where t can be as low as 1 second.

As with any stream processing system, there are three big aspects to the framework itself.


Ingesting the data streams : This is accomplished via DStreams, which you can think of effectively as a thin wrapper around an input source such as Kafka/HDFS which knows how to read the next N entries from the input.The receiver based approach is a little complicated IMHO, and …

Setting up Hadoop/YARN/Spark/Hive on Mac OSX El Capitan

If you are like me, who loves to have everything you are developing against working locally in a mini-integration environment, read on

Here, we attempt to get some pretty heavy-weight stuff working locally on your mac, namely

Hadoop (Hadoop2/HDFS)YARN (So you can submit MR jobs)Spark (We will illustrate with Spark Shell, but should work on YARN mode as well)Hive (So we can create some tables and play with it) We will use the latest stable Cloudera distribution, and work off the jars. Most of the methodology is borrowed from here, we just link the four pieces together nicely in this blog. 
Download StuffFirst off all, make sure you have Java 7/8 installed, with JAVA_HOME variable setup to point to the correct location. You have to download the CDH tarballs for Hadoop, Zookeeper, Hive from the tarball page (CDH 5.4.x page) and untar them under a folder (refered to as CDH_HOME going forward) as hadoop, zookeeper


$ ls $HOME/bin/cdh/5.4.7 hadoop hadoop-2.6.0-cdh5.4.7.…