Showing posts with label C - Cee. Show all posts
Showing posts with label C - Cee. Show all posts

Tuesday, August 31, 2010

Common errors in c

1. Introduction

This document lists the common C programming errors that the author sees time and time again. Solutions to the errors are also presented.

2. Beginner Errors

These are errors that beginning C students often make. However, the professionals still sometimes make them too!
  • Forgetting to put a break in a switch statement

Remember that C does not break out of a switch statement if a case is encountered. For example:

int x = 2;
switch(x) {
case 2:
printf("Two\n");
case 3:
printf("Three\n");
}

prints out:

Two
Three

Put a break to break out of the switch:

int x = 2;
switch(x) {
case 2:
printf("Two\n");
break;
case 3:
printf("Three\n");
break; /* not necessary, but good if additional cases are added later */
}

  • Using = instead of ==

C's = operator is used exclusively for assignment and returns the value assigned. The == operator is used exclusively for comparison and returns an integer value (0 for false, not 0 for true). Because of these return values, the C compiler often does not flag an error when = is used when one really wanted an ==. For example:

int x = 5;
if ( x = 6 )
printf("x equals 6\n");

This code prints out x equals 6! Why? The assignment inside the if sets x to 6 and returns the value 6 to the if. Since 6 is not 0, this is interpreted as true.


Avoiding this error -
One way to have the compiler find this type of error is to put any constants (or any r-value expressions) on the left side. Then if an = is used, it will be an error:
if ( 6 = x)

  • scanf() errors

There are two types of common scanf() errors:
2.3.1 Forgetting to put an ampersand (&) on arguments

scanf() must have the address of the variable to store input into. This means that often the ampersand address operator is required to compute the addresses. Here's an example:

int x;
char * st = malloc(31);

scanf("%d", &x); /* & required to pass address to scanf() */
scanf("%30s", st); /* NO & here, st itself points to variable! */

As the last line above shows, sometimes no ampersand is correct!
2.3.2 Using the wrong format for operand

C compilers do not check that the correct format is used for arguments of a scanf() call. The most common errors are using the %f format for doubles (which must use the %lf format) and mixing up %c and %s for characters and strings.

  • Size of arrays

Arrays in C always start at index 0. This means that an array of 10 integers defined as:

int a[10];

has valid indices from 0 to 9 not 10! It is very common for students go one too far in an array. This can lead to unpredictable behavior of the program.
2.5 Integer division

Unlike Pascal, C uses the / operator for both real and integer division. It is important to understand how C determines which it will do. If both operands are of an integal type, integer division is used, else real division is used. For example:

double half = 1/2;

This code sets half to 0 not 0.5! Why? Because 1 and 2 are integer constants. To fix this, change at least one of them to a real constant.

double half = 1.0/2;

If both operands are integer variables and real division is desired, cast one of the variables to double (or float).

int x = 5, y = 2;
double d = ((double) x)/y;

2.6 Loop errors

In C, a loop repeats the very next statement after the loop statement. The code:

int x = 5;
while( x > 0 );
x--;

is an infinite loop. Why? The semicolon after the while defines the statement to repeat as the null statement (which does nothing). Remove the semicolon and the loop works as expected.

Another common loop error is to iterate one too many times or one too few. Check loop conditions carefully!
2.7 Not using prototypes

Prototypes tell the compiler important features of a function: the return type and the parameters of the function. If no prototype is given, the compiler assumes that the function returns an int and can take any number of parameters of any type.

One important reason to use prototypes is to let the compiler check for errors in the argument lists of function calls. However, a prototype must be used if the function does not return an int. For example, the sqrt() function returns a double, not an int. The following code:

double x = sqrt(2);

will not work correctly if a prototype:

double sqrt(double);

does not appear above it. Why? Without a prototype, the C compiler assumes that sqrt() returns an int. Since the returned value is stored in a double variable, the compiler inserts code to convert the value to a double. This conversion is not needed and will result in the wrong value.

The solution to this problem is to include the correct C header file that contains the sqrt() prototype, math.h. For functions you write, you must either place the prototype at the top of the source file or create a header file and include it.
2.8 Not initializing pointers

Anytime you use a pointer, you should be able to answer the question: What variable does this point to? If you can not answer this question, it is likely it doesn't point to any variable. This type of error will often result in a Segmentation fault/coredump error on UNIX/Linux or a general protection fault under Windows. (Under good old DOS (ugh!), anything could happen!)

Here's an example of this type of error.

#include
int main()
{
char * st; /* defines a pointer to a char or char array */

strcpy(st, "abc"); /* what char array does st point to?? */
return 0;
}

How to do this correctly? Either use an array or dynamically allocate an array.

#include
int main()
{
char st[20]; /* defines an char array */

strcpy(st, "abc"); /* st points to char array */
return 0;
}

or

#include
#include
int main()
{
char *st = malloc(20); /* st points to allocated array*/

strcpy(st, "abc"); /* st points to char array */
free(st); /* don't forget to deallocate when done! */
return 0;
}

Actually, the first solution is much preferred for what this code does. Why? Dynamical allocation should only be used when it is required. It is slower and more error prone than just defining a normal array.
3. String Errors
3.1 Confusing character and string constants

C considers character and string constants as very different things. Character constants are enclosed in single quotes and string constants are enclosed in double quotes. String constants act as a pointer to the actually string. Consider the following code:

char ch = 'A'; /* correct */
char ch = "A"; /* error */

The second line assigns the character variable ch to the address of a string constant. This should generate a compiler error. The same should happen if a string pointer is assigned to a character constant:

const char * st = "A"; /* correct */
const char * st = 'A'; /* error */

3.2 Comparing strings with ==

Never use the == operator to compare the value of strings! Strings are char arrays. The name of a char array acts like a pointer to the string (just like other types of arrays in C). So what? Consider the following code:

char st1[] = "abc";
char st2[] = "abc";
if ( st1 == st2 )
printf("Yes");
else
printf("No");

This code prints out No. Why? Because the == operator is comparing the pointer values of st1 and st2, not the data pointed to by them. The correct way to compare string values is to use the strcmp() library function. (Be sure to include string.h) If the if statement above is replaced with the following:

if ( strcmp(st1,st2) == 0 )
printf("Yes");
else
printf("No");

the code will print out Yes. For similar reasons, don't use the other relational operators (<,>, etc.) with strings either. Use strcmp() here too.
3.3 Not null terminating strings

C assumes that a string is a character array with a terminating null character. This null character has ASCII value 0 and can be represented as just 0 or '\0'. This value is used to mark the end of meaningful data in the string. If this value is missing, many C string functions will keep processing data past the end of the meaningful data and often past the end of the character array itself until it happens to find a zero byte in memory!

Most C library string functions that create strings will always properly null terminate them. Some do not (e.g., strncpy() ). Be sure to read their descriptions carefully.
3.4 Not leaving room for the null terminator

A C string must have a null terminator at the end of the meaningful data in the string. A common mistake is to not allocate room for this extra character. For example, the string defined below

char str[30];

only has room for only 29 (not 30) actually data characters, since a null must appear after the last data character.

This can also be a problem with dynamic allocation. Below is the correct way to allocate a string to the exact size needed to hold a copy of another.

char * copy_str = malloc( strlen(orig_str) + 1);
strcpy(copy_str, orig_str);

The common mistake is to forget to add one to the return value of strlen(). The strlen() function returns a count of the data characters which does not include the null terminator.

This type of error can be very hard to detect. It might not cause any problems or only problems in extreme cases. In the case of dynamic allocation, it might corrupt the heap (the area of the program's memory used for dynamic allocation) and cause the next heap operation (malloc(), free(), etc.) to fail.
4. Input/Output Errors
4.1 Using fgetc(), etc. incorrectly

The fgetc(), getc() and getchar() functions all return back an integer value. For example, the prototype of fgetc() is:

int fgetc( FILE * );

Sometimes this integer value is really a simple character, but there is one very important case where the return value is not a character!

What is this value? EOF A common misconception of students is that files have a special EOF character at the end. There is no special character stored at the end of a file. EOF is an integer error code returned by a function. Here is the wrong way to use fgetc():

int count_line_size( FILE * fp )
{
char ch;
int cnt = 0;

while( (ch = fgetc(fp)) != EOF && ch != '\n')
cnt++;
return cnt;
}

What is wrong with this? The problem occurs in the condition of the while loop. To illustrate, here is the loop rewritten to show what C will do behind the scenes.

while( (int) ( ch = (char) fgetc(fp) ) != EOF && ch != '\n')
cnt++;

The return value of fgetc(fp) is cast to char to store the result into ch. Then the value of ch must be cast back to an int to compare it with EOF. So what? Casting an int value to a char and then back to an int may not give back the original int value. This means in the example above that if fgetc() returns back the EOF value, the casting may change the value so that the comparison later with EOF would be false.

What is the solution? Make the ch variable an int as below:

int count_line_size( FILE * fp )
{
int ch;
int cnt = 0;

while( (ch = fgetc(fp)) != EOF && ch != '\n')
cnt++;
return cnt;
}

Now the only hidden cast is in the second comparison.

while( (ch = fgetc(fp)) != EOF && ch != ((int) '\n') )
cnt++;

This cast has no harmful effects at all! So, the moral of all this is: always use an int variable to store the result of the fgetc(), getc() and getchar().
4.2 Using feof() incorrectly

There is a wide spread misunderstanding of how C's feof() function works. Many programmers use it like Pascal's eof() function. However, C's function works differently!

What's the difference? Pascal's function returns true if the next read will fail because of end of file. C's function returns true if the last function failed. Here's an example of a misuse of feof():

#include
int main()
{
FILE * fp = fopen("test.txt", "r");
char line[100];

while( ! feof(fp) ) {
fgets(line, sizeof(line), fp);
fputs(line, stdout);
}
fclose(fp);
return 0;
}

This program will print out the last line of the input file twice. Why? After the last line is read in and printed out, feof() will still return 0 (false) and the loop will continue. The next fgets() fails and so the line variable holding the contents of the last line is not changed and is printed out again. After this, feof() will return true (since fgets() failed) and the loop ends.

How should this fixed? One way is the following:

#include
int main()
{
FILE * fp = fopen("test.txt", "r");
char line[100];

while( 1 ) {
fgets(line, sizeof(line), fp);
if ( feof(fp) ) /* check for EOF right after fgets() */
break;
fputs(line, stdout);
}
fclose(fp);
return 0;
}

However, this is not the best way. There is really no reason to use feof() at all. C input functions return values that can be used to check for EOF. For example, fgets returns the NULL pointer on EOF. Here's a better version of the program:

#include
int main()
{
FILE * fp = fopen("test.txt", "r");
char line[100];

while( fgets(line, sizeof(line), fp) != NULL )
fputs(line, stdout);
fclose(fp);
return 0;
}

The author has yet to see any student use the feof() function correctly!

Incidently, this discussion also applies to C++ and Java. The eof() method of an istream works just like C's feof().
4.3 Leaving characters in the input buffer


C input (and output) functions buffer data. Buffering stores data in memory and only reads (or writes) the data from (or to) I/O devices when needed. Reading and writing data in big chunks is much more efficient than a byte (or character) at a time. Often the buffering has no effect on programming.

One place where buffering is visible is input using scanf(). The keyboard is usually line buffered. This means that each line input is stored in a buffer. Problems can arise when a program does not process all the data in a line, before it wants to process the next line of input. For example, consider the following code:

int x;
char st[31];

printf("Enter an integer: ");
scanf("%d", &x);
printf("Enter a line of text: ");
fgets(st, 31, stdin);

The fgets() will not read the line of text that is typed in. Instead, it will probably just read an empty line. In fact, the program will not even wait for an input for the fgets() call. Why? The scanf() call reads the characters needed that represent the integer number read in, but it leaves the '\n' in the input buffer. The fgets() then starts reading data from the input buffer. It finds a '\n' and stops without needing any additional keyboard input.

What's the solution? One simple method is to read and dump all the characters from the input buffer until a '\n' after the scanf() call. Since this is something that might be used in lots of places, it makes sense to make this a function. Here is a function that does just this:

/* function dump_line
* This function reads and dumps any remaining characters on the current input
* line of a file.
* Parameter:
* fp - pointer to a FILE to read characters from
* Precondition:
* fp points to a open file
* Postcondition:
* the file referenced by fp is positioned at the end of the next line
* or the end of the file.
*/
void dump_line( FILE * fp )
{
int ch;

while( (ch = fgetc(fp)) != EOF && ch != '\n' )
/* null body */;
}

Here is the code above fixed by using the above function:

int x;
char st[31];

printf("Enter an integer: ");
scanf("%d", &x);
dump_line(stdin);
printf("Enter a line of text: ");
fgets(st, 31, stdin);

One incorrect solution is to use the following:

fflush(stdin);

This will compile but its behavior is undefined by the ANSI C standard. The fflush() function is only meant to be used on streams open for output, not input. This method does seem to work with some C compilers, but is completely unportable! Thus, it should not be used.
4.4 Using the gets() function

Do not use this function! It does not know how many characters can be safely stored in the string passed to it. Thus, if too many are read, memory will be corrupted. Many security bugs that have been exploited on the Internet use this fact! Use the fgets() function instead (and read from stdin). But remember that unlike gets(), fgets() does not discard a terminating \n from the input.

The scanf() functions can also be used dangerously. The %s format can overwrite the destination string. However, it can be used safely by specifying a width. For example, the format %20s will not read more than 20 characters.
5. Acknowlegements

The author would like to thank Stefan Ledent for suggesting the section on "Not leaving room for the null terminator"

++ / -- and pointers operator *

++ is executed first comparing with *.

So we have to use ++ (*p)

Eg, consider strcpy() function.


char *strcpy(char *dest, const char *src)
{
char *save = dest;
while(*dest++ = *src++);
return save;
}
So here first thing that is happening in while loop is dest and src are incremented by 1
Than they are referenced by *
Then equated and finally loop moves on until it gets '\0'..i.e null

Sunday, August 29, 2010

Using == operator in better way in cpp

In cpp, it is possible that instead of
i==5

we can do

i=5

So we assign i = 5 and if it is like
if(cond)
cond gets true.

So better is
5==i
beause == is symmetric.
If someone writes by mistake is
5=i
As we get error = 'can't assign value to literal'.

Sunday, August 8, 2010

Self reproducing program in C

main(){char*p="main(){char*p=%c%s%c;
(void)printf(p,34,p,34,10);}%c"
(void)printf(p,34,p,34,10);}

zero sized allocation using malloc

int main()
{
int *p = 0;
printf("before addr: %pn", p);
p = (int *) malloc(0);
printf("after addr: %pn", p);
printf("sizeof: %un", sizeof(*p));
*p = 1;
printf("--- %d -- this is the last statment.n", *p);
free(p);
}

Output
before addr: (nil)
after addr: 0x80496c8
sizeof: 4
--- 1 -- this is the last statment.

Note :
Linux
  • allows a ‘read’ of the zero sized allocated memory
  • allows a ‘write’ on the zero sized allocated memory
  • sizeof shows an allocation of 4 bytes.

return and exit from main: difference

Basically the difference between following programs !
//ret.c
int main()
{
return 43;
}
//exit.c
int main()
{
exit(43);
}
well, there are three ways for the processes to exit: -
1. Voluntary exit (implicit)
2. Voluntary exit (explicit)
3. Involunatary exit
Voluntary exit can be implicit e.g. in case of return and explicit e.g.
in case of a call to exit(). Involuntary exit is like being killed by a
third process, receiving a SIGSTP signal (or other signals whose default ot set
behavior results in terminating the process).

Friday, August 6, 2010

How to create function polymorphism in C

Why should we try for polymorphism in c?
There are already many high-level, easy-to-use languages out there with full object-oriented capabilities, including polymorphism. Why insist on doing this in C?
I am working on a communications systems simulator that is used, among other things, to estimate the complexity of different communication algorithms. It is able to do so at quite a low-level, keeping count of every operation required.
At one point, I found myself needing to execute the same algorithm, but with different data types. For instance, I wanted to compare performance when using floating-point versus fixed-point numbers. I hated the idea of maintaining several, almost identical versions of the different algorithms. We're talking a few thousand lines of code here.
This is the point where, in many situations, one switches to a language that is able to run the same code on several different data types — in other words, a language that supports polymorphism.
I had one main reason to do persist in using C, though: execution speed. It is not unusual for the simulator to take a few days to complete a test case, on modern hardware. I didn't want to think about extending this time any further. In my experience, C produces the fastest code of any language (excepting, maybe, carefully optimized assembler).
Another reason was just the plain challenge of doing it. It was an opportunity to learn more about C. For example, I had never needed to use function pointers before. Also, I believe that the ultimate test of whether you understand a high-level programming concept is to implement it in C.

How to do?
OK, on to the technical details.
My main objective was to be able to tell the program which data type to use, without having to recompile. This type is selected once, when the program is invoked. I don't need to change the type once the program has started.
This simplifies the problem a bit, but more general polymorphism is easy to create with one or two simple additions to the main idea I'll describe.
I'll show how to create a polymorphic function to add two numbers. The numbers can both be either int or double. We start by creating a new data type that can hold either an integer or a double.
Example: Composite data type
typedef union
{
double floatpt;
int integer;
} number;
A union is just like a struct, except that it can hold only one element at a time. The memory required by the union is that of the largest data type it can hold.
Now we create two functions to add numbers. Both operate on variables of type number, but one uses the int part and the other the double part.
Example: Two add functions
number add_floatpt(number x, number y)
{
number result;

result.floatpt = x.floatpt + y.floatpt;
return result;
}

number add_integer(number x, number y)
{
number result;

result.integer = x.integer + y.integer;
return result;
}
As can be seen, both functions take and return arguments of type number. Internally, one of them assumes the union contains an int, and the other assumes it contains a double. In each function, we use the built-in overloading of the + operator.
Now we're ready to create our polymorphic add function. What we'll do is create a function pointer, that points to add_floatpt or to add_integer.
Example: Function pointer
/* pointer to function
* function "add" will show polymorphism */

number (* add)(number, number) = NULL;

if( sel == 1 ) {
add = &add_floatpt;
}
else {
add = &add_integer;
}
Here we use a variable named sel to decide whether add will point to add_floatpt or to add_integer. In this example, this is done once when the program starts. It can just as easily be done each time add is called, although it is a bit messier.
Now, the rest of the program can happily go about its way, calling add whenever it needs to perform an addition, completely oblivious to the underlying data types.
Below I present a full example, with comments.
Example: Full source code

/* This program shows how to create a form of function polymorphism
 * using the C language
 *
 * The technique shown is nowhere near as powerful as what C++ or other OO
 * languages provide, but is useful for some applications.
 *
 * Compilation:
 * First, save the program as poly.c; then
 * compile with: gcc -o poly poly.c
 *
 * Usage:
 * The program takes three arguments:
 * poly TYPE X Y
 *
 * TYPE: if equal to 1, then X and Y are taken as floating point numbers,
 * otherwise, X and Y are taken as integers
 *
 * X, Y : two numbers of the type specified by TYPE
 *
 * The program will output the addition of X and Y.
 *
 * Examples:
 *
 * $ ./poly 1 2.0 3.0
 * Result = 5.00000
 *
 * $ ./poly 2 2 3
 * Result = 5
 *
 * */

#include <stdlib.h>

/* all quantities used by the program will be of type "number"
 * (a union is used to save memory) */
typedef union
{
double floatpt;
int integer;
} number;

/* the next two functions are used to add numbers. Each function knows how to
 * add a different type */
number add_floatpt(number x, number y)
{
number result;

result.floatpt = x.floatpt + y.floatpt;
return result;
}

number add_integer(number x, number y)
{
number result;

result.integer = x.integer + y.integer;
return result;
}

/* the next two functions are used to print the result. Each function knows how
 * to print a different type */
void print_floatpt( number x )
{
printf( "Result = %1.5f\n", x.floatpt );
}

void print_integer( number x )
{
printf( "Result = %d\n", x.integer );
}

int main( int argc, char *argv[] )
{
int sel;
number x, y, result;

/* pointers to functions.
         * functions "add" and "print" will show polymorphism */
number (* add)(number, number) = NULL;
void (* print)(number) = NULL;

sel = atoi( argv[1] );

/* make "add" and "print" point to the function of the correct type.
         * note that the option to use integers or floating-point values
         * is set at run time; there is no need to recompile. */
if( sel == 1 ) {
add = &add_floatpt;
print = &print_floatpt;
x.floatpt = atof( argv[2] );
y.floatpt = atof( argv[3] );

}
else {
add = &add_integer;
print = &print_integer;
x.integer = atoi( argv[2] );
y.integer = atoi( argv[3] );
}

/* from this point forward, "add" and "print" can be used as
         * polymorphic functions. As long as the program does all its
         * calculations using the "number" type, it doesn't care about
         * whether the underlying types are integers or floating point
         * numbers */
result = add( x, y );
print( result );

return 0;
}

Thursday, August 5, 2010

Time Functions

In this chapter we will look at how we can access the clock time with UNIX system calls. There are many more time functions than we consider here - see man pages and standard library function listings for full details. In this chapter we concentrate on applications of timing functions in C
Uses of time functions include:
  • telling the time.
  • timing programs and functions.
  • setting number seeds.

Basic time functions

Some of thge basic time functions are prototypes as follows:
time_t time(time_t *tloc) -- returns the time since 00:00:00 GMT, Jan. 1, 1970, measured in seconds.

If tloc is not NULL, the return value is also stored in the location to which tloc points.

time() returns the value of time on success.

On failure, it returns (time_t) -1. time_t is typedefed to a long (int) in and header files.

int ftime(struct timeb *tp) -- fills in a structure pointed to by tp, as defined in :



   struct timeb
   { time_t time;
unsigned short millitm;
short timezone;
short dstflag;
};


The structure contains the time since the epoch in seconds, up to 1000 milliseconds of more precise interval, the local time zone (measured in minutes of time westward from Greenwich), and a flag that, if nonzero, indicates that Day light Saving time applies locally during the appropriate part of the year.

On success, ftime() returns no useful value. On failure, it returns -1. 

Two other functions defined etc. in
#include  

char *ctime(time_t *clock),
char *asctime(struct tm *tm)

ctime() converts a long integer, pointed to by clock, to a 26-character string of the form produced by asctime(). It first breaks down clock to a tm structure by calling localtime(), and then calls asctime() to convert that tm structure to a string.

asctime() converts a time value contained in a tm structure to a 26-character string of the form:

   Sun Sep 16 01:03:52 1973

asctime() returns a pointer to the string.

Accepting command line arguments in c/c++

In C++ it is possible to accept command line arguments. Command-line arguments are given after the name of a program in command-line operating systems like DOS or Linux, and are passed in to the program from the operating system. To use command line arguments in your program, you must first understand the full declaration of the main function, which previously has accepted no arguments. In fact, main can actually accept two arguments: one argument is number of command line arguments, and the other argument is a full list of all of the command line arguments.

The full declaration of main looks like this:
int main ( int argc, char *argv[] )
The integer, argc is the ARGument Count (hence argc). It is the number of arguments passed into the program from the command line, including the name of the program.

The array of character pointers is the listing of all the arguments. argv[0] is the name of the program, or an empty string if the name is not available. After that, every element number less than argc are command line arguments. You can use each argv element just like a string, or use argv as a two dimensional array. argv[argc] is a null pointer.

How could this be used? Almost any program that wants its parameters to be set when it is executed would use this. One common use is to write a function that takes the name of a file and outputs the entire text of it onto the screen.
#include 
#include

using namespace std;

int main ( int argc, char *argv[] )
{
if ( argc != 2 ) // argc should be 2 for correct execution
// We print argv[0] assuming it is the program name
cout<<"usage: "<< argv[0] <<" \n";
else {
// We assume argv[1] is a filename to open
ifstream the_file ( argv[1] );
// Always check to see if file opening succeeded
if ( !the_file.is_open() )
cout<<"Could not open file\n";
else {
char x;
// the_file.get ( x ) returns false if the end of the file
// is reached or an error occurs
while ( the_file.get ( x ) )
cout<< x;
}
// the_file is closed implicitly here
}
}
This program is fairly simple. It incorporates the full version of main. Then it first checks to ensure the user added the second argument, theoretically a file name. The program then checks to see if the file is valid by trying to open it. This is a standard operation that is effective and easy. If the file is valid, it gets opened in the process. The code is self-explanatory, but is littered with comments, you should have no trouble understanding its operation this far into the tutorial. :-)

Typecasting in c

Lesson 11: Typecasting

Typecasting is making a variable of one type, such as an int, act like another type, a char, for one single operation. To typecast something, simply put the type of variable you want the actual variable to act as inside parentheses in front of the actual variable. (char)a will make 'a' function as a char.

For example:
#include  

using namespace std;

int main()
{
cout<< (char)65 <<"\n";
// The (char) is a typecast, telling the computer to interpret the 65 as a
// character, not as a number. It is going to give the character output of
// the equivalent of the number 65 (It should be the letter A for ASCII).
cin.get();
}
One use for typecasting for is when you want to use the ASCII characters. For example, what if you want to create your own chart of all 256 ASCII characters. To do this, you will need to use to typecast to allow you to print out the integer as its character equivalent.
#include 

using namespace std;

int main()
{
for ( int x = 0; x < 256; x++ ) {
cout<< x <<". "<< (char)x <<" ";
//Note the use of the int version of x to
// output a number and the use of (char) to
// typecast the x into a character
// which outputs the ASCII character that
// corresponds to the current number
}
cin.get();
}
The typecast described above is a C-style cast, C++ supports two other types. First is the function-style cast:
int main()       
{
cout<< char ( 65 ) <<"\n";
cin.get();
}
This is more like a function call than a cast as the type to be cast to is like the name of the function and the value to be cast is like the argument to the function. Next is the named cast, of which there are four:
int main()       
{
cout<< static_cast ( 65 ) <<"\n";
cin.get();
}
static_cast is similar in function to the other casts described above, but the name makes it easier to spot and less tempting to use since it tends to be ugly. Typecasting should be avoided whenever possible. The other three types of named casts are const_cast, reinterpret_cast, and dynamic_cast. They are of no use to us at this time.

C arrays

Arrays are useful critters because they can be used in many ways. For example, a tic-tac-toe board can be held in an array. Arrays are essentially a way to store many values under the same name. You can make an array out of any data-type including structures and classes.

Think about arrays like this:
[][][][][][] 
Each of the bracket pairs is a slot(element) in the array, and you can put information into each one of them. It is almost like having a group of variables side by side.

This would make an integer array with 100 slots, or places to store values(also called elements). To access a specific part element of the array, you merely put the array name and, in brackets, an index number. This corresponds to a specific element of the array. The one trick is that the first index number, and thus the first element, is zero, and the last is the number of elements minus one. 0-99 in a 100 element array, for example.

What can you do with this simple knowledge? Lets say you want to store a string, because C had no built-in datatype for strings, it was common to use arrays of characters to simulate strings. (C++ now has a string type as part of the standard library.)

For example:
char astring[100]; 
will allow you to declare a char array of 100 elements, or slots. Then you can receive input into it it from the user, and if the user types in a long string, it will go in the array. The neat thing is that it is very easy to work with strings in this way, and there is even a header file called cstring. There is another lesson on the uses of strings, so its not necessary to discuss here.

The most useful aspect of arrays is multidimensional arrays. How I think about multi-dimensional arrays:
[][][][][]
[][][][][]
[][][][][]
[][][][][]
[][][][][]
This is a graphic of what a two-dimensional array looks like when I visualize it.

For example:
int twodimensionalarray[8][8];
declares an array that has two dimensions. Think of it as a chessboard. You can easily use this to store information about some kind of game or to write something like tic-tac-toe. To access it, all you need are two variables, one that goes in the first slot and one that goes in the second slot. You can even make a three dimensional array, though you probably won't need to. In fact, you could make a four-hundred dimensional array. It would be confusing to visualize, however. Arrays are treated like any other variable in most ways. You can modify one value in it by putting:
arrayname[arrayindexnumber] = whatever; 
or, for two dimensional arrays
arrayname[arrayindexnumber1][arrayindexnumber2] = whatever;
However, you should never attempt to write data past the last element of the array, such as when you have a 10 element array, and you try to write to the [10] element. The memory for the array that was allocated for it will only be ten locations in memory, but the next location could be anything, which could crash your computer.

You will find lots of useful things to do with arrays, from storing information about certain things under one name, to making games like tic-tac-toe. One suggestion I have is to use for loops when access arrays.
#include 

using namespace std;

int main()
{
int x;
int y;
int array[8][8]; // Declares an array like a chessboard

for ( x = 0; x < 8; x++ ) {
for ( y = 0; y < 8; y++ )
array[x][y] = x * y; // Set each element to a value
}
cout<<"Array Indices:\n";
for ( x = 0; x < 8;x++ ) {
for ( y = 0; y < 8; y++ )
cout<<"["<<<"]["<<<"]="<< array[x][y] <<" ";
cout<<"\n";
}
cin.get();
}
Here you see that the loops work well because they increment the variable for you, and you only need to increment by one. Its the easiest loop to read, and you access the entire array.

One thing that arrays don't require that other variables do, is a reference operator when you want to have a pointer to the string. For example:
char *ptr;
char str[40];
ptr = str; // Gives the memory address without a reference operator(&)
As opposed to
int *ptr;
int num;
ptr = &num; // Requires & to give the memory address to the ptr
The reason for this is that when an array name is used as an expression, it refers to a pointer to the first element, not the entire array. This rule causes a great deal of confusion, for more information please see our Frequently Asked Questions.

C Strings

Strings are arrays of chars. String literals are words surrounded by double quotation marks.
"This is a static string"
To declare a string of 49 letters, you would want to say:
char string[50];
This would declare a string with a length of 50 characters. Do not forget that arrays begin at zero, not 1 for the index number. In addition, a string ends with a null character, literally a '\0' character. However, just remember that there will be an extra character on the end on a string. It is like a period at the end of a sentence, it is not counted as a letter, but it still takes up a space. Technically, in a fifty char array you could only hold 49 letters and one null character at the end to terminate the string.

TAKE NOTE: char *arry; Can also be used as a string. If you have read the tutorial on pointers, you can do something such as:
arry = new char[256];
which allows you to access arry just as if it were an array. Keep in mind that to use delete you must put [] between delete and arry to tell it to free all 256 bytes of memory allocated.

For example:
delete [] arry.
Strings are useful for holding all types of long input. If you want the user to input his or her name, you must use a string. Using cin>> to input a string works, but it will terminate the string after it reads the first space. The best way to handle this situation is to use the function cin.getline. Technically cin is a class (a beast similar to a structure), and you are calling one of its member functions. The most important thing is to understand how to use the function however.

The prototype for that function is:
istream& getline(char *buffer, int length, char terminal_char);
The char *buffer is a pointer to the first element of the character array, so that it can actually be used to access the array. The int length is simply how long the string to be input can be at its maximum (how big the array is). The char terminal_char means that the string will terminate if the user inputs whatever that character is. Keep in mind that it will discard whatever the terminal character is.

It is possible to make a function call of cin.getline(arry, 50); without the terminal character. Note that '\n' is the way of actually telling the compiler you mean a new line, i.e. someone hitting the enter key.

For a example:
#include 

using namespace std;

int main()
{
char string[256]; // A nice long string

cout<<"Please enter a long string: ";
cin.getline ( string, 256, '\n' ); // Input goes into string
cout<<"Your long string was: "<< string <
cin.get();
}
Remember that you are actually passing the address of the array when you pass string because arrays do not require an address operator (&) to be used to pass their address. Other than that, you could make '\n' any character you want (make sure to enclose it with single quotes to inform the compiler of its character status) to have the getline terminate on that character.

cstring is a header file that contains many functions for manipulating strings. One of these is the string comparison function.
int strcmp ( const char *s1, const char *s2 );
strcmp will accept two strings. It will return an integer. This integer will either be:
Negative if s1 is less than s2.
Zero if s1 and s2 are equal.
Positive if s1 is greater than s2.
Strcmp is case sensitive. Strcmp also passes the address of the character array to the function to allow it to be accessed.
char *strcat ( char *dest, const char *src );
strcat is short for string concatenate, which means to add to the end, or append. It adds the second string to the first string. It returns a pointer to the concatenated string. Beware this function, it assumes that dest is large enough to hold the entire contents of src as well as its own contents.
char *strcpy ( char *dest, const char *src );
strcpy is short for string copy, which means it copies the entire contents of src into dest. The contents of dest after strcpy will be exactly the same as src such that strcmp ( dest, src ) will return 0.
size_t strlen ( const char *s );
strlen will return the length of a string, minus the termating character ('\0'). The size_t is nothing to worry about. Just treat it as an integer that cannot be negative, which it is.

Here is a small program using many of the previously described functions:
#include  //For cout
#include //For the string functions

using namespace std;

int main()
{
char name[50];
char lastname[50];
char fullname[100]; // Big enough to hold both name and lastname

cout<<"Please enter your name: ";
cin.getline ( name, 50 );
if ( strcmp ( name, "Julienne" ) == 0 ) // Equal strings
cout<<"That's my name too.\n";
else // Not equal
cout<<"That's not my name.\n";
// Find the length of your name
cout<<"Your name is "<< strlen ( name ) <<" letters long\n";
cout<<"Enter your last name: ";
cin.getline ( lastname, 50 );
fullname[0] = '\0'; // strcat searches for '\0' to cat after
strcat ( fullname, name ); // Copy name into full name
strcat ( fullname, " " ); // We want to separate the names by a space
strcat ( fullname, lastname ); // Copy lastname onto the end of fullname
cout<<"Your full name is "<< fullname <<"\n";
cin.get();
}

Safe Programming

The above string functions all rely on the existence of a null terminator at the end of a string. This isn't always a safe bet. Moreover, some of them, noticeably strcat, rely on the fact that the destination string can hold the entire string being appended onto the end. Although it might seem like you'll never make that sort of mistake, historically, problems based on accidentally writing off the end of an array in a function like strcat, have been a major problem.

Fortunately, in their infinite wisdom, the designers of C have included functions designed to help you avoid these issues. Similar to the way that fgets takes the maximum number of characters that fit into the buffer, there are string functions that take an additional argument to indicate the length of the destination buffer. For instance, the strcpy function has an analogous strncpy function
char *strncpy ( char *dest, const char *src, size_t len );
which will only copy len bytes from src to dest (len should be less than the size of dest or the write could still go beyond the bounds of the array). Unfortunately, strncpy can lead to one niggling issue: it doesn't guarantee that dest will have a null terminator attached to it (this might happen if the string src is longer than dest). You can avoid this problem by using strlen to get the length of src and make sure it will fit in dest. Of course, if you were going to do that, then you probably don't need strncpy in the first place, right? Wrong. Now it forces you to pay attention to this issue, which is a big part of the battle.

Wednesday, August 4, 2010

Finding time of execution of code in c

#include <time.h>

clock_t start;
clock_t diff;
clock_t end;

start= clock();
various algorithm;
end = clock();

diff = end - start;
print diff;

Wednesday, July 28, 2010

Some udfs for arrays in c

1D arrays
Printing 1 D arrays
void printArray (int *array,int size)
{
int i;
for (i = 0; i < size; i++)
     printf("%d",array[i]);
printf("\n");
}
2 D arrays 
Printing 2D arrays
void printArray(int **array, int m, int n)
{
           for(i = 0; i < nrows; i++)  
              for(j= 0; j < nrows; i++)  
                         printf("%d",array[i][j]);
}

Allocating and Deallocating 2 D Arrays 

/*   allocate2D
/*   function to dynamically allocate 2-dimensional array using malloc.
/*
/*   accepts an int** as the "array" to be allocated, and the number of rows and
/*   columns.
*/
void allocate2D(int** array, int nrows, int ncols) {
     
     /*  allocate array of pointers  */
     array = ( int** )malloc( nrows*sizeof( int* ) );
     
     /*  allocate each row  */
     int i;
     for(i = 0; i < nrows; i++) {
          array[i] = ( int* )malloc( ncols*sizeof( int ) );
     }
}
/*   deallocate2D
/*   corresponding function to dynamically deallocate 2-dimensional array using
/*   malloc.
/*
/*   accepts an int** as the "array" to be allocated, and the number of rows. 
/*   as with all dynamic memory allocation, failure to free malloc'ed memory
/*   will result in memory leaks
*/
void deallocate2D(int** array, int nrows) {
     
     /*  deallocate each row  */
     int i;
     for(i = 0; i < nrows; i++) {
          free(array[i]);
     }
     
     /*  deallocate array of pointers  */
     free(array);
     
}
/*   EXAMPLE USAGE:   
int** array1;

allocate2D(array1,1000,1000); //allocates a 1000x1000 array of ints

deallocate2D(array1,1000);    //deallocates the same array

*/

Sunday, December 6, 2009

File Handling in c

/* Program to create a file and write some data the file */
#include
#include
main( )
{
FILE *fp;
char stuff[25];
int index;
fp = fopen("TENLINES.TXT","w"); /* open for writing */
strcpy(stuff,"This is an example line.");
for (index = 1; index <= 10; index++)
fprintf(fp,"%s Line number %d\n", stuff, index);
fclose(fp); /* close the file before ending program */
}






FILE * fopen(char * filename, char * mode)

The mode value in the above example is set to 'r', indicating that we want to read from the file. Other possible values are:

  • r - open a file in read-mode, set the pointer to the beginning of the file.

  • w - open a file in write-mode, set the pointer to the beginning of the file.

  • a - open a file in write-mode, set the pointer to the end of the file.

  • rb - open a binary-file in read-mode, set the pointer to the beginning of the file.

  • wb - open a binary-file in write-mode, set the pointer to the beginning of the file.

  • ab - open a binary-file in write-mode, set the pointer to the end of the file.

  • r+ - open a file in read/write-mode, if the file does not exist, it will not be created.

  • w+ - open a file in read/write-mode, set the pointer to the beginning of the file.

  • a+ - open a file in read/append mode.

  • r+b - open a binary-file in read/write-mode, if the file does not exist, it will not be created.

  • w+b - open a binary-file in read/write-mode, set the pointer to the beginning of the file.

  • a+b - open a binary-file in read/append mode. 



  • /* Program to display the contents of a file on screen */
    fp = fopen("prog.c","r");
    c = getc(fp) ;    //reading
    while (c!= EOF)
    {
    putchar(c);
    c = getc(fp);
    }



    Deleting Files
    The command to delete a file is:
    remove (char * szFileName);


    Writing to files can be done in various ways:

    • putc() - like fputc()
    • fputc() - int fputc (int character, FILE * stream); - write a character to a file
    • fputs() - int fputs (const char * string , FILE * stream); - write a string to a file
    • int fprintf(
      FILE *stream, const char *format, ... )

    The fprintf() function sends information (the arguments) according to the specified format to the file indicated by stream. fprintf() works just like |printf()| as far as the format goes. The return value of fprintf() is the number of characters outputted, or a negative number if an error occurs.
    Egs.
    char name[20] = "Mary";
    ......
    fprintf( out, "Hello %s\n", name );

    The fputs() function writes an array of characters pointed to by str to
    the given output stream. The return value is non-negative on success,
    and EOF on failure.
    just like reading from files:
    (Note: All functions have 1 argument as file pointer, just note the position of file pointer argument in them)
    • getc(FILE * stream) - like fgetc()
    • fgetc(FILE * stream) - int fgetc (FILE * stream); - write a character to a file 
    • fgets() - char * fgets (char * string , int num , FILE * stream); - write a string to a file
    • int fscanf() - int fscanf ( FILE * stream , const char * format
    • [ , argument , ...] ); - works like scanf() except that it reads from a file instead of STDIN
    The getc() function returns the next character from stream, or EOF if the end of file is reached. getc() is identical to |fgetc()|.  

    The function fgets() reads up to num - 1 characters from the given file stream and dumps them into str. fgets() will stop when it reaches the end of a line, in which case str will be terminated with a newline. If fgets() reaches num - 1 characters or encounters the EOF, str will be null-terminated. fgets() returns str on success, and NULL on an error.
    The function fscanf() reads data from the given file stream in a manner exactly like |scanf()|. The return value of fscanf() is the number of variables that are actually assigned values, or EOF if no assignments could be made.

    Reading and writing in binary format
    int fread( void *buffer, size_t size, size_t num, FILE *stream );
    Description:

    The function fread() reads num number of objects (where each object is size bytes) and places them into the array pointed to by buffer.
    The data comes from the given input stream. The return value of the
    function is the number of things read...use |feof()| or |ferror()| to
    figure out if an error occurs.

    int fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
    Description:The fwrite() function writes, from the array buffer, count objects of size size to stream. The return value is the number of objects written.
    Returns EOF on failure:
    fscanf() , fclose(); fputs() , 
    Returns 0 on success
    fclose() 
    Returns NULL on failure:
    fopen(), freopen() , 
    Returns non-0 on success
    feof() 
    Returns negative no. of failure:
    fprintf(); fputs()


    Saturday, December 5, 2009

    Syntax in C

    qualifier:
                volatile
                const

    storage-class: 

                auto            extern
                static          register

    type:
                void            char            short
                int             long            float
                double          signed          unsigned
                enum-specifier
                typedef-name
                struct-or-union-specifier

    Complicated Declaration


    int *p[10];

    This is an array of pointers

    int (*p)[10];

    This is a pointer to a 10 element array



    What is a dangling pointer? What are reference counters with respect to pointers?

    A pointer which points to an object that no longer exists. Its a pointer referring to an area of memory that has been deallocated. Dereferencing such a pointer usually produces garbage.

    Using reference counters which keep track of how many pointers are pointing to this memory location can prevent such issues. The reference counts are incremented when a new pointer starts to point to the memory location and decremented when they no longer need to point to that memory. When the reference count reaches zero, the memory can be safely freed. Also, once freed, the corresponding pointer must be set to NULL. 

    Friday, December 4, 2009

    How to find out if a machine is 32 bit or 64 bit?

    n = sizeof(void *);


    if n==8, than 64 bit 
    if n==4, than 32 bit.

    Operator Precedence in C & CPP

    Operator Precedence Chart 
    Operator Type                                  Operator                               Associativity
    1. Primary Expression Operators     () [] . -> expr++ expr--        left-to-right
    2. Unary Operators                        * & + - ! ~ ++expr --expr    right-to-left
                                                               (typecast) sizeof()    
    3. Binary Operators                       * / %                                           left-to-right
                                                             + -
                                                              >> <<
                                                              < > <= >=
                                                              == !=
                                                             &
                                                             ^
                                                              |
                                                              &&
                                                              ||
    4. Ternary Operator                            ?:                                       right-to-left
    5. Assignment Operators     = += -= *= /= %= >>=            right-to-left
                                                <<=  &= ^= |=
    6. Comma                                      ,                                                left-to-right

    Note: 1,2,3 etc above shows the level of precedence, with 1 being of highest precedence etc.
    Associativities are from left to right....like normal arithematic expression, leaving the case  of assignment operator, unary and ternary operator.
    1. Also note that in binary operators arithematic operators are of highest preference....... A for Arirthematic.
    2. Than follow relational operator...R for Relational operator(like < , > etc.)
    3. Than comes bitwise operator....B for Bitwise(eg...
    4. Than logical operator or Boolean operator...L....(eg. && etc)...
    So learning way is MARBLE .
    Notes:
    Exception to MARBLE is bitwise shift operators which has higher precedence than Relational operators.
    This can be noted by the fact that....>> has greater precedence than >.
    Logical operator ! is of higher precedence being a unary operator.
    Postfix is greater than prefix in precedence.
    () is greater than [] in precedence...

    C++
    In case of C++, We have same precedence with some added operators.
    1. :: operator is of higher precedence, with precedence = () operator.
    2. 
    const_cast  , dynamic_cast , reinterpret_cast ,  static_cast ,
    typeid
    + we have:
     () Type cast, i.e. (type) expr
    sizeof() Size in bytes
    new Dynamically allocate storage
     new [] Dynamically allocate array
    delete Dynamically free storage
    delete [] Dynamically free array 


    That's it.