TimeLinux1

Tuesday, November 20, 2012

Linux Programming - 1


Linux Systems Programming by RL

20 -System Programming is the art of writing system software.
-System software lives at a low level, interfacing directly with the kernel and core system libraries.
-examples of system software: shell, text editor, compiler etc.
-system software is the heart of all software.
21 -system software has a strong awareness of the hardware and OS.
-Much of system software is written in C and its libraries.
-As opposed to system software, there is application software written in languages like PHP, JavaScript, Java etc.

-Linux is Unix like, not Unix.
-Linux follows its own course, diverging where desired and converging only where practical.

22 -Three cornerstones to Linux system programming:
. system calls or syscalls
. C library
. C compiler

-system calls or syscalls:
are function invocations made from the userspace to kernel to request
some service from the OS.
-eg your text editor uses read() syscall to read a file.

-Linux has far fewer syscalls (in hundreds) than windows (that has thousands).
-some linux syscalls are architecture specific (eg only for alpha or intel)
but most (90% +) are common.
-system calls are denoted by a number, starting with 0.

-for reasons of security and reliability, userspace programs are not allowed to directly call kernel. They issue interrupts to to 'request' kernel attention.

23 -The C library:
aka glibc (or libc), is a set of core services and functions that
facilitate system call invocation.

-The C compiler:
aka gcc is a set of programs allowing to compile system and userspace
programs.

-APIs and ABIs:
.Application Program Interface & Application Binary Interface.
These are programming routines that allow communication between software on
the source code or binary levels.
-APIs and ABIs are important from programs portability across platforms.
25
-Linux is not officially Posix compliant.
-The term 'Posix' was suggested by Richard Stallman of FSF.

-Commands to see the versions of:
. linux - uname -r -ours is 3.6
. gcc - gcc --version -ours is 4.7
. glibc - ldd --version -ours is 2.15

28 -Everything in linux is a file. And all files are streams of bytes.
-in order to deal with files they must be opened for read &/or write.
-files are referenced by a descriptor (a pointer?)
-file descriptors are shared between kernel and userspace.
29 -The file operations start at a certain position in the file.
-usually this position is zero. And it cannot be negative.
-a single file can be opened multiple times, even by the same process.
-although files are accessed by names, they are not actually related.
-rather files are directly related to the inode.
-The inode of a file has its accounting info (who, what, when, etc)
-the inode does not have a file's name.
-directories are used to provide the names associated to files.
-userspace programs access files by names.
-so a directory can be thought of a file with mapping of filenames to inodes.
-eg: when a userspace program requests a file (from the kernel),
the kernel opens the directory and searches the name to get its inode.
-when two filenames point to the same inode, they are hard links.
-inodes are meaningless outside the filesystem, so hardlinks cant span fs.
-when two filenames point to diff inodes but one contains the path of other,
they are called symbolic links.
-in other words, symbolic links have diff inodes and can span fs.

-Filesystems:
-a hierarchical arrangement of files (on linux, everything is a file)
-The smallest addressable unit on a block device is the sector. The sector is a physical quality of the device.
-Likewise, the smallest logically addressable unit on a filesystem is the block. The block is an abstraction of the filesystem, not of the physical media on which the file-system resides. A block is usually a power-of-two multiple of the sector size.
-Blocks are generally larger than the sector, but they must be smaller than the page size* (the smallest unit addressable by the memory management unit, a hardware component).
-in nutshell, memory pages > fs blocks > device sectors.

-Processes:
-If files are the most fundamental abstraction in a Unix system, processes are the second most fundamental.
-processes are object code in execution; plus they also have data.
-Processes exist in a virtual system. From their perspective they are the only
process on the system. They never know the difference because the kernel
seamlessly preempts and schedules processes.
-each process has its own independent address space in memory.

-Threads:
-threads are the unit of activity within a process, an abstraction responsible
for executing code and maintaining a processes' running state.
-while threads of a process share some components of the process (like global variables) they have some independent components like the stack that stores   local variables.

-note about directory permissions:
 For directories, read permission allows the contents of the directory to be listed, write permission allows new links to be added inside the directory, and execute permission allows the directory to be entered and used in a  pathname.
-note about signals:
 Signals are a mechanism for one-way asynchronous notifications. A signal may be sent from the kernel to a process, from a process to another process, or from a process to itself. Signals typically alert a process to some event,
eg ctrl+z. Linux has about 30 signals.
-note about errors:
 exit status 0 is generally treated as success and a non zero value like -1
is treated as failure.

-In Linux, the kernel maintains a per-process list of open files called the
file table. Its indexed by a file descriptor that is a positive int.
-The fd serves as a pointer to the file.
-both userspace and kernel space use the file descriptors or fd.
-by default a child process receives a copy of its parents file table.
-Each linux process has a max number of files that it can open usually 1024.
-fd 0=stdin, fd 1=stdout, fd 2=stderr. Each process has these 3.

-file open() system call:
-syntax:  int open (const char *name, int flags, mode_t mode);
-eg:  fd = open ("/home/kidd/madagascar", O_RDONLY);  //fd = file desc.

-file ownership:
-the uid of a file's owner is the effective uid of the process creating the file. gid is usually the effective gid of the process creating the file.
-umask: the umask exists to allow the user to limit the permissions that his programs set on new files.

-file creat() system call: //yes no 'e' in creat()
-syntax:  int creat (const char *name, mode_t mode);
-eg:  fd = creat (file, 644);

-file read() system call:
-syntax:  ssize_t read (int fd, void *buf, size_t len);
-eg:  ssize_t nr;
 nr = read (fd, &word, sizeof(unsigned long));
-note: size of a datatype depends on the processor.
-eg: unsigned long type is 4 bytes on 32-bit systems, 8 bytes on 64-bit sys.

-file write() system call:
-syntax:  ssize_t write (int fd, const void *buf, size_t count);
-eg:  ssize_t nr;
 nr = write (fd, buf, strlen (buf));
-writes are usually delayed writes, whereby kernel accumulates data blocks in
before writing them to disk.
-there are however, times when applications want to control when kernel writes
data to disks.
-And for those situations, Linux provides fsync() and fdatasync() syscalls.
-syntax:  int fsync(int fd);
 int fdatasync(int fd);

-direct IO:
-if an application wishes to perform its own IO bypassing the os provided
mechanisms, then they need to request the kernel to call the file open()
function with O_DIRECT flag. With this, I/O will initiate directly from user-
space buffers to the device, bypassing the page cache. All I/O will be synchronous; operations will not return until completed.

-file close() system call:
-after a program has finished working with a file descriptor, it needs to
unmap the file descriptor from the file using close().
-syntax:  int close (int fd);
-return value -1 is error, 0 is success.

-lseek() system call:
-while normally IO in a file occurs linearly, some applications need to go to
a random location in the file. This is possible with the lseek() syscall.
-lseek() does not initiate IO, it just updates the file pointer position.
-syntax:  off_t lseek(int fd, off_t pos, int origin);
-eg:  off_t ret;
 ret = lskee(fd, (off_t) 109, SEEK_SET); //set the fd pos 109.
-Now it is possible to seek beyond the end of file (EOF). Why? well sometimes
apps will do so. In such a case, it depends if the request is read or write.
If it is read, then fd will return EOF.
If it is write, then fd will advance to the new position and the EOF to new
position will be padded with zeroes. This zero padding is called hole. This
can mean that the total filesystem space > diskspace. Manipulating holes does
not initiate any physical IO and they can actually improve performance.
-In addition to this in Linux, you can have variants of read() and write() that each take a parameter the file position from where to start read/write.
-these two are pread() and pwrite().
-eg: ssize_t pread (int fd, void *buf, size_t count, off_t pos);

-Multiplexed IO.
-With complex applications like GUI, often require multiple file descriptors
to handle multiple IO like from keyboard, mouse and processes internally.
This is where multiplexed IO comes into play.
-Multiplexe IO allows applications to concurrently block on multiple file descriptors, receive notifications from any of them and read/write without
blocking each other.
-Linux provides three multiplexed IO solutions:
.select()
.poll()
.epoll() //event poll
-select()
-eg: int select (int n, fd_set *readfs,fd_set *writefs,fd_set *exceptfs,
struct timeval *timeout)
-as can be seen, select IO watches for read, write, exceptions & timeouts all
at the same time.
-poll()
-the difference between select() and poll() is that poll() uses an array of
fds (instead of 3 separate ones for read, write, exception)
-eg: struct pollfd{
int fd; //file descriptor
short events; //events to watch
short revents; //returned events
};
-epoll()
-while both select() and poll() do the same job of multiplexed IO, they still
require a host of file desctiptors to list and watch events.
-epoll() is different in that it separates monitoring events from actual  monitoring. What that means, is while one syscall intializes epoll, it does
not stay back to monitor fds, another syscall does so, and a third actually
performs it.
-eg: int epoll_create(int size)
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents,
int timeout);

-Buffered IO
-all disk operations can be measured in terms of blocks.
-An optimal situation for IO emerges if syscalls request integer multiples of
data blocks in the minimum number of iterations. This is because in that case, the kernel doesnt have to spin cycles doing unneeded calculations.
-If programs dont have the ability to do so, the system tries the second
approach of buffered IO, in which data is cached in buffer until they reach
the optimal size of multiples of block size.

Sunday, November 18, 2012

C Programming Basics - 2


-structures are user defined datatypes that can store multiple types of fixed data.
-eg: struct book
{
char name ;
float price ;
int pages ;
};
struct booka, bookb, bookc.
-here we are storing char, float and int in one combined struct called 'book'.
-then we instantiated the structure into three variables booka, bookb, bookc.
-struct type declaration does not tell the compiler to reserve any space in memory.
-all it does is define the 'form'.
-also structure type declaration is usually defined at the top of a source code file
before any other variable or function.
-when structure elements are stored, they are stored contiguosly in memory.
-structures can also be made into arrays.
-in the above example, we simply say:
struct book b[10] to store 10 elements in one go (b0 to b9).
389 -structures allow copying of elements in one go.
-eg: b2=b1 -copies name, price, pages of b1 into that of b2.
390 -structures can be nested.
-eg: struct book
{
char name;
float price;
}
struct author
{
char authorname;
struct book b; <<--structure book b in author.
}
-to get values: author a.b.name  or author a.b.price;
-structures can also have pointers.
-eg: struct book *ptr;
ptr=&b1; initialized with addr of b1.
printf("\n %s %d, ptr->name, ptr->price);
397 -some uses of structures:
. in databases
. in changing size of cursor
. in sending output to a printer
. in finding memory size of a comp
. in drawing graphics on a screent and so on..

Nov 17
=====
409 -Input and output is not part of C language. By C here we mean the C compiler.
-instead they are part of library functions that are add-ons & called by C compiler.
-IO facilities for different OS are different.
-thus printf on Linux is different from printf on solaris/windows.
-IO functions can be of two types:
. console IO -io bet stdin(keybd), stdout(monitor, stderr(console)
. file IO -io to and from files.
409 -console = keyboard + monitor together (directly connected to a host)
-console io can be subdivided into:
. formatted io - user in control of format of output/input
. unformatted io - user not in control
-eg: formatted console io - printf(), scanf()
410 -eg: unformatt console io - getch(),getche(),getchar(),gets(), putch(), putchar(), puts()
-note: there is no unformatted console io functions for ints and floats (only char/strings)
419 -printf vs sprintf - printf prints on screen, sprintf stores to string
-eg: printf("\n %d", i) vs sprintf(astr, "%d" i), printf("\n%s",astr)
-scanf  vs sscanf - read from stdin vs read from string
-eg: scanf("%s")  vs  sscanf("%s",a) where a="abcd"

419 -note: in formatted console io, 'enter' key has to be hit before the io takes place. If io is desired the moment something is entered/read, instead
of waiting for 'enter key', we use unformatted io functions.
-unformatted io functions examples:
.getch()  - reads input without echoing on screen
.getche() - reads input and echoes on screen
.getchar()- reads input and echoes after you hit enter key
.fgetchar() like getchar. getchar is a macro, fgetchar is a func.
-more:
.putch()  - output on screen //dos only?
.putchar()- output on screen //works on linux

-more:
.gets()  - receives a string that has spaces (scanf cant do that)
.puts()  - outputs  a string to the screen.

430 -all data stored on disk is in binary form.
-the manner in which this binary data is stored on disk varies from OS to OS.
-but this doesnt matter to C programs as they simply have to call the
IO functions for that OS via the compiler designed for that OS.

432 -in io, strings are quoted in double quotes " " whereas chars in single ' '.
-once a file is opened using fopen, and directed to a pointer, we no longer need to address it by name, pointer is enough.
-eg: fp=fopen("afile.txt");
then fgetc(fp), fclose(fp) etc are used instead of fgetc("afile.txt") etc.

482 -commandline params can be passed to main as two params known as:
.argv - an array of pointers to strings
.argc - an int = the # of strings argv points
-eg: in this command:
filecopy filea fileb
-the program interprets it internally as:
main(int argc, char *argv[])
-argc=3
-argv[0]=base addr of the string "filecopy"
-argv[1]=base addr of the string "filea"
-argv[2]=base addr of the string "fileb"

520 -enum data type allows user defined data types to be created.
-eg: enum mar_status
{
single, married, divorced,widowed
};
enum mar_status person1, person2
-internally the compiler treats enumerators as integers.
-eg: in the above, single is stored as 0, married as 1 and so on.
-once declared, enums can be included in structs, like this:
-eg: struct person
{
char name[30];
int age;
enum mar_status status;
};
  struct person pers;
strcpy( pers.name,"Superman");
pers.age=30;
pers.status=single;
-enum scope can be global or local. global if declared outside all functions,
local if declared inside a function.
-typedef: a shorthand for a variable type, usually in CAPS.
-eg: typdef unsigned long int UNLONGIN; //UNLONGIN=unsigned long int
-then UNLONGIN var1, var2;
-typedef is useful when dealing with structs or enums.
-eg: in the enum mar_status above, we could say this to define person1,2
typedef enum mar_status MSTAT;
-then MSTAT p1, p2;
-in short, typedef improves program readability.

-typecasting: defining the type of variable return;
-defined in brackets (,) before an operation.
-eg: int i=4, j=6;
div = (float) 4/6; //(float) is typecast, else int would be retrn

-pointers can even point to functions because functions have addresses in C.
-to do so, all we have to do is to mention the name of the function
-eg: i=display //i gets the value of function display.

-unions: unions are derived data types like structures.
-ie both unions and structs group a number of different variables together.
-the difference is in structure, the constituent variables are not necessarily
contiguous in memory.
-in unions the constituent variables are contiguous.
-eg: union a
{
int i;
char ch[2];
};
union a key;
-if we had done this using struct, it would take 6 bytes in mem.
-but with unions it takes only 4 bec int i and ch[] are made to occupy same
spot in memory.
-unions are useful in dealing with hardware.
620 -interaction with hardware means, interaction with the chip for that h/w.
621 -For different events there are different interrupts. As a reaction to the occurrence of an interrupt a table called Interrupt Vector Table (IVT) is looked up. IVT is present in memory. It is populated with addresses of different kernel routines during booting. Depending upon which interrupt has occurred the Microprocessor picks the address of the appropriate routine from IVT and transfers execution control to it. Once the control reaches the routine, the code in the routine interacts with the hardware. These routines are called
interrupt service routines (ISRs) and are part of the device drivers.
627 -as to why application programs cannot directly talk to hardware:
in a multiuser, multiprogramming OS, every device is shared amongst multiple applications running in memory. To avoid conflict between
different programs accessing the same device simultaneously the OS
does not permit an application program to directly access any of the devices. Instead it provides several API functions or system calls to carry out the interaction.
-Note: that the system calls dont change when a new device is added to the system.

-Linux Programing Discussion.
-C program -> system call -> device driver -> hardware.
652 -The programming architecture (better known as programming model) for each OS is different. Hence naturally the program that achieves the same task under different OS would have to be different.
-Gnome and KDE are just GUI shells.
-In multitasking os like linux, the microprocessor divides its execution time
equally among running processes in a round robin manner. Thus if we take a snapshot of the memory only one process would be found executing on the microprocessor.
-The scheduling of process on the cpu is done by scheduler.
-The scheduler stores the info a process (like cpu registers, contents of stack etc) into scheduler table and switches to next program.
This switching is called context switch.
-Preemptive scheduling: context switch happens as soon as the time slot allocated is over, whether the process is complete or not.
-1st linux program:
#include <stdio.h>
int main( )
{
printf ( "\n Parent Process ID = %d", getppid( ) ) ;
printf ( "\n Process ID = %d\n", getpid( ) ) ;
}
-In linux a process can spawn another process by calling fork() system call.
-system calls are also known as library functions.
-the parent and child process share the code.
661 -if some code needs to be run in the child, it is run using the exec() func.
662 -The ps command gets its info from the "process-table".
-Apart from other information the process table contains an entry of ‘exit code’ of the process. This integer value indicates the reason why the process was terminated. Even though the process comes to an end its entry would remain in the process table until such time that the parent of the terminated process queries the exit code. This act of
querying deletes the entry of the terminated process from the table
and returns the exit code to the parent that raised the query.
-If the child exits first (which is normal), its exit code would persist in the process table until the parent queries it. This is zombie process.
-If the parent exits first(not normal), the exit code is not queried and
persists. The child is called orphan and is adopted by init.
init queries the exit code and the child entry is removed from table.
-Knowing the exit code is important because that determines if the processes
terminated successfully or not.

670 -while the communication between programs and OS happens via system calls (aka
library functions like fork(), exec() ) etc, the reverse ie OS to
programs happens via signals.
-eg: when we hit ctrl+c, the kernel sends a terminate signal to the program.
684 -Signal Processing is the heart of programming under Linux.


Next we will look at Linux Programming...

C Programming Basics - 1


-Major parts of popular operating systems like Windows,
UNIX, Linux are still written in C. This is because even today
when it comes to performance (speed of execution) nothing
beats C. Moreover, if one is to extend the operating system to
work with new devices one needs to write device driver
programs. These programs are exclusively written in C.
19 -Embedded systems in Mobiles and Gadgets are written in C because these programs not only have to run fast but also have to work in limited
amount of memory. Only C fits the bill.
-This is also true for Computer games that must be fast.
-C makes lowlevel hardware interaction possible without loss of performance.

23 -Constants in C are of two types:
.primary integers, real (aka float), characters
.secondary array, pointer, structure, union, enum etc

36 -printf() and scanf() are counterpart functions.
-printf() prints output, scanf() reads input.
-scanf() takes pointers as parameters (pointer=memory address of a variable).
-eg:
printf ( "Enter values of p, n, r" ) ;
scanf  ( "%d %d %f", &p, &n, &r ) ;

Nov 08
=====
174 -when a function is called, the caller is temporarily suspended while the
called function goes to work. Once the called function is done it
returns the execution control back to the caller
183 -To send back control, its enough to have a closing bracket }. No return reqd.
-any function can be called, even main().
179 -a function can call itself (recursion).
-to be called by a function, the called function must be defined outside the
caller.
-Two types of functions exist:
.library functions -a group of functions labeled as a library
.user defined functions
180 -if there are some logically isolated tasks, put them in a function.
-Such programs are easy to read and maintain.


Nov 10
=====
197 -Pointers:
Pointers are unsigned integers that hold an address in memory.
The address they hold is the address of a variable.
-Pointers are created with * operator.
-& - address of a variable
-* - value at the pointer, indicates the creation of a pointer.
- [ampao starvat]
-eg: float i=29.7; --variable created and given an address
int *j; --variable to store some address of some int
j=&i; --that some address is now address of i
-so *j is value at the address of i = value of i = 29.7
-also since j=&i,
*j=*(&i)=value at(address of i)=29.7
-also &j=&(&i)=address of(address of i)=address of i [verified]
-so *(&j)=value at(address of(address of i)=value at(addr of i)=29.7

198 -float *f does not mean address is float.
-float *f means value at f points to a float variable
-similarly, char *ch means value at ch points to a character variable

Nov 11
=====
201 -Pointers and functions.
-functions can receive arguments by one of two methods:
. by values  of arguments -eg afunc(i, j)   - call by value
. by address of arguments -eg afunc(&i, &j)  - call by reference
-difference between the two methods:
. arg by val - operations in called func dont affect caller func
. arg by addr - operations in called func affect caller func
-Note: call or arg by value is more common than call or arg by addr (or ref)
call by reference allows function to return more than one value
-eg:
main( )
{
int radius ;
float area, perimeter ;
printf ( "\nEnter radius of a circle " ) ;
scanf ( "%d", &radius ) ;
areaperi ( radius, &area, &perimeter ) ;
printf ( "Area = %f", area ) ;
printf ( "\nPerimeter = %f", perimeter ) ;
}
areaperi ( int r, float *a, float *p )
{
*a = 3.14 * r * r ;
*p = 2 * 3.14 * r ;
}

And here is the output...
Enter radius of a circle 5
Area = 78.500000
Perimeter = 31.400000
-conclusion: we sent val of radius and addr of area, perim and got two values of area and permiter in return.

204 -recursion:
when a function calls itself
-Thus during every recursive function call we are working with a fresh set of parameters.

212 -It is possible to add user defined functions to existing system libraries.
-It is possible to add user defined functions to user defined libraries.

Nov 13
=====

230 -int data type can be of two types:
.short int - 2 bytes in memory
.long  int - 4 bytes in memory
291 -For linux/windows these days, ints are 4 bytes
-further they can be signed and unsigned.
-unsigned means +ve values so while signed short int range from -32k to +32k,
unsigned int range from 0 to 65k, almost doubling the range, in a way.
-even chars have signs (since they are an ascii number internally).
-chars are 1 byte long. signed chars are -128 to +128. unsigned 0 to 256.
-floats occupy 4 bytes.
-double occupy 8 bytes in memory. long double is 10 bytes in memory.
-Note: for older 16 bit processors, which dont have the ability to hold huge
numbers outside their range (>2to16), an emulator software is used
that mimics larger address area. Downside, the emulator approximates
the numbers to fit in, so the answers may be a little ways off esp
for very large nums.
-Every variable has a default storage class.
-storage class of a variable, tells:
. where the variable will be stored
. what will be the initial value (unless explicitly specified)
. what will be the scope of the variable
. life duration of the variable (how long it exists?)
-there are four storage classes:
. automatic -stored in mem, no fixed defaults, scope local
. register -stored in cpu registers, no defs, scope local
. static -stored in mem, default 0, persist bet functions
. extern -srored in mem, default 0, scope global, life of prog
-if variables are not definded explicitly, they are assumed to be auto.

Nov 14
=====

257 -The C preprocessor is exactly what its name implies. It is a program that processes our source program before it is passed to the compiler. -Preprocessor commands (often known as directives) form what can almost be considered a language within C language.
-The directives can be placed anywhere in a program but are most often placed at the beginning of a program, before the first function definition.
-The directives could be in the form of:
. macro expansion #define ABC
. file inclusion #include abc.h
. conditional compilation --not common  #if elif
. miscellaneous --not common  #undef or pragma
-The benefit of preprocessor commands is that it improves compiler performnc.
-They also improve readability of a program.
-prerprocessor directives are defined with
. the '#define keyword'
. in CAPS
. no semicolons
. in the very beginning of the program
-eg: #define PI 3.14
main()
...
-Macros can also have arguments but everything should be in parentheses
-eg: #define AREA(x) (3.14*x*x)

257 -source code to executable in two steps:
. source code + preproc -> object code - by compile step
. object code + system libs -> exe code - by link step
267 -macros behave like functions but
-in macro calls, the compiler simply dumps macro code when called
-in func  calls, the control is actually passed to the func
-macros are faster than functions but good when code is small.
-macros increase code size, whereas functions decrease them.

269 -#include "file" - looks for file in the whole search path
-#include <file> - looks for file only in the pwd or compiler dirs

285 -array - a set of similar data types
-arrays allow multiple values to be stored in a single variable
-arrays are also called subscripted variable
-pointers and arrays are closely related.
-all arrays make use of pointers internally
289 -no matter how big an array, its elements are always stored in contiguous memory locations.
286 -a string is an array of characters.
290 -array initialization:
int num[6] = {1,2,3,5,5,6}
or int num[]  = {1,2,3,4,5,6}
292 -The compiler does not check if an array size is too small for the values being input.
296 -Numbers can be added and subtracted to pointers
-eg: if i=4 and j=&i=lets say 10000
-then i-2 and j-4
=> i=2 and j = j-4 = 10000 - 4x4 = 9986 (size of 4 ints subtracted)
297 -while a number can be added or subtracted to pointers, pointers themselves cannot be added, multiplied or divided by another pointer.

286 -Accessing array elements by pointers is always faster than accessing them by subscripts.
302 -Whole arrays can be passed to functions via pointers.
-Passing the zeroth element of an array is the same as passing the whole arr.
-eg: displ (&num[0],5) = displ (&num,5) = pass a 5 elemt arr num to displ()
-also if int num[ ] = { 24, 34, 12, 44, 56, 17 } ;
-then *num = the zeroth element of the array, that is, 24.
-also, *num and *( num + 0 ) both refer to 24.
-similarly, *(num+i)=*(i+num)=num[i]=i[num] == the ith element of arr num.
Nov 15
=====
304 -2D arrays aka matrix can be thought of as a stack of 1D arrays on top of each other.
-arr[5][2] means 5 1D arrays of 2 elements each on top of each other.
-the first element is [0][0], last [n][m] which means
n rows, m columns
and [n+1][m+1] element is row col ender.
-each row has a two values.
-eg ID, age for a group of persons.
-you can omit row nums but not column nums.
-eg: arr[][3] is ok, arr[3][] is not.
307 -While a 2D array can be thought of as a matrix, the arrangement is imaginary.
-This is because memory doesn’t contain rows and columns.
-In memory whether it is a one-dimensional or a two-dimensional array the array elements are stored in one continuous chain.

Nov 16
======
-strings are arrays of characters.
-string arrays are terminated by a null character ('\0').
-to output strings, we can use %s placeholder and call string in printf.
-eg: printf("%s", str); --prints string called str.
-scanf() function cannot receive multiword strings.
-To receive and print multiword strings, we have gets() and puts() functions.
-puts automatically puts a new line character at the end of its output.

-The malloc function:
is a standard library function that requires the number of bytes to be allocated and returns the base address of the chunk of memory that it allocates.
-it allocates memory at runtime ie is dynamic.
-The address returned by malloc() is always of the type void *.
-to use it, we need to #include "alloc.h" as preprocessor.
-eg: ptr = malloc(6)  allocates 6 bytes of mem and sets the base addr to ptr.

Tuesday, November 13, 2012

C Programing Examples - Power of a number.


The following program will calculate the power of a non negative integer to non negative power. Can be extended easily for negative powers by replacing multiplication by division in power function.

[root@MS-vaio C_Progs]# cat power.c
=====
#include <stdio.h>
main()
{
int a,b,c;
int powr (int x, int y);
printf("\n Please enter a positive integer and its power, separated by comma:");
scanf ("%d, %d",&a,&b);
c=powr(a,b);
printf("\n %d to the power %d is: %d \n",a,b,c);
}

///powr function starts here...
powr (int x, int y)
{
int i,j;
if (y==0)
    {
     return (1);
    }
if (y==1)
   {
return (x);
   }
else
   {
    j=x;
    for(i=2;i<=y;i++)
x=x*j;
        return (x);
    }
}
==========Sample Run======
[root@MS-vaio C_Progs]# gcc -o answ power.c
[root@MS-vaio C_Progs]# ./answ

 Please enter a positive integer and its power, separated by comma: 5, 5

 5 to the power 5 is: 3125