Showing posts with label functions. Show all posts
Showing posts with label functions. Show all posts

Wednesday, September 1, 2010

Returning Multi-dimensional Arrays from Functions

Returning an array from a function only has meaning if the array was created by the function. Otherwise,
no return is necessary since an existing array is passed by the address. However, if the function has
created the array on the heap, you can return the address of element 0.

The problem here is that you can't use the function return type unless you a) return a type or
b) return a pointer to a type. That is, you cannot return a pointer to an array since an array is not
a type. So, if you create an array of int you can return the array as an int*:

Expand|Select|Wrap|Line Numbers
  1. int* func(int arg)
  2. {
  3.     int* temp = new int[arg];
  4.     return temp;
  5. }
  6. int main()
  7. {
  8.     int* arr = func(5);
  9. }
  10.  
This does not work when you create a multi-dimensional array:
Expand|Select|Wrap|Line Numbers
  1. int (*)[5] func(int arg)   // ERROR: Cannot return an array
  2. {
  3.     int (* temp)[5] = new int[arg][5];
  4.     return temp;
  5. }
  6. int main()
  7. {
  8.     int (* arr)[5] = func(4);
  9. }
  10.  
In this case you could pass in the address of a pointer to an array of 5 int:
Expand|Select|Wrap|Line Numbers
  1. void func(int arg, int (**rval)[5])
  2. {
  3.     int (* temp)[5] = new int[arg][5];
  4.     *rval = temp;
  5. }    
  6. int main()
  7. {
  8.     int (* arr)[5] = 0;
  9.     func(4, &arr);
  10.     //arr is now a [4][5] array of int
  11. }
  12.  
However, if you need to use the function as an RVAL, then you need to return a type. Here the easiest thing to do is define a type to be a pointer to an element of your multi-dimensional array. In this example you would need a pointer to an array of 5 int:

Expand|Select|Wrap|Line Numbers
  1. typedef int (*IntArray5Ptr)[5]; 
Now you have a type that can be returned:

Expand|Select|Wrap|Line Numbers
  1. IntArray5Ptr func(int arg)    
  2.     int (* temp)[5] = new int[arg][5]; 
  3.     return temp; 
  4. }
  5.  
  6. int main() 
  7.     int (* arrA)[5] = func(4); 
You can return a pointer to type in addition to returning a type. So you could define a type to be an element of your array (in the example this is an array of 5 int) and return a pointer to that type:

Expand|Select|Wrap|Line Numbers
  1. typedef int IntArray5[5]; 
  2.  
  3. IntArray5* funcB(int arg) 
  4.     int (* temp)[5] = new int[arg][5]; 
  5.     return temp; 
  6.  
  7.  
  8. int main() 
  9.     int (* arr)[5] = func(4); 
Finally, as was stated at the beginning of this article: There are no multi-dimensional arrays in C++.
Therefore, a function could just create a one-dimensional array of the correct number of elements and return
the address of element 0. In this case, element 0 is a type and you can use the return type of a function
to return a pointer to a type. Then the calling function could typecast the return so the array can be
used with muliple dimensions:

Expand|Select|Wrap|Line Numbers
  1. int* func(int arg)
  2. {
  3.     int * temp = new int[arg];
  4.     return temp;
  5. }    
  6. int main()
  7. {
  8.     //This is arr[60]
  9.     int* arr = func(60);
  10.  
  11.     //This is arr[12][5] --> 12 x 5 = 60
  12.     int (*arr1)[5] = (int(*)[5])func(60);
  13.  
  14.     //This is arr[3][4][5] -> 3 * 4 * 5 = 60
  15.     int (*arr2)[4][5] = (int(*)[4][5])func(60);
  16.  
  17.     //This is arr[1][3][4][5] -> 1*3*4*5 = 60;
  18.     int (*arr3)[3][4][5] = (int(*)[3][4][5])func(60);
  19.  
  20.  
  21.  
  22. }
  23.  

Tuesday, August 31, 2010

Introduction to Pointer to function in c/cpp

Function Pointers provide some extremely interesting, efficient and elegant programming techniques. You can use them to replace switch/if-statements, to realize your own late-binding or to implement callbacks. Unfortunately - probably due to their complicated syntax - they are treated quite stepmotherly in most computer books and documentations. If at all, they are addressed quite briefly and superficially. They are less error prone than normal pointers cause you will never allocate or deallocate memory with them. All you've got to do is to understand what they are and to learn their syntax. But keep in mind: Always ask yourself if you really need a function pointer. It's nice to realize one's own late-binding but to use the existing structures of C++ may make your code more readable and clear. One aspect in the case of late-binding is runtime: If you call a virtual function, your program has got to determine which one has got to be called. It does this using a V-Table containing all the possible functions. This costs some time each call and maybe you can save some time using function pointers instead of virtual functions.

What is a Function Pointer?

Function Pointers are pointers, i.e. variables, which point to the address of a function. You must keep in mind, that a running program gets a certain space in the main-memory. Both, the executable compiled program code and the used variables, are put inside this memory. Thus a function in the program code is, like e.g. a character field, nothing else than an address. It is only important how you, or better your compiler/processor, interpret the memory a pointer points to.

Introductory Example or How to Replace a Switch-Statement

Switch case uses jump-tables, therefore we keep ourself to int as cases, viewing it from efficiency point of view. We will see how it works here.
When you want to call a function DoIt() at a certain point called label in your program, you just put the call of the function DoIt() at the point label in your source code. Then you compile your code and every time your program comes up to the point label, your function is called. Everything is ok. But what can you do, if you don't know at build-time which function has got to be called? What do you do, when you want to decide it at runtime? Maybe you want to use a so called Callback-Function or you want to select one function out of a pool of possible functions. However you can also solve the latter problem using a switch-statement, where you call the functions just like you want it, in the different branches. But there's still another way: Use a function pointer!
In the following example we regard the task to perform one of the four basic arithmetic operations. The task is first solved using a switch-statement. Then it is shown, how the same can be done using a function pointer. It's only an example and the task is so easy that I suppose nobody will ever use a function pointer for it ;-)

//------------------------------------------------------------------------------------
// 1.2 Introductory Example or How to Replace a Switch-Statement
// Task: Perform one of the four basic arithmetic operations specified by the
// characters '+', '-', '*' or '/'.



// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer

float Plus (float a, float b) { return a+b; }
float Minus (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }


// Solution with a switch-statement - specifies which operation to execute
void Switch(float a, float b, char opCode)
{
float result;

// execute operation
switch(opCode)
{
case '+' : result = Plus (a, b); break;
case '-' : result = Minus (a, b); break;
case '*' : result = Multiply (a, b); break;
case '/' : result = Divide (a, b); break;
}

cout << "Switch: 2+5=" << result << endl; // display result
}


// Solution with a function pointer - is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.

void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
float result = pt2Func(a, b); // call using function pointer

cout << "Switch replaced by function pointer: 2-5="; // display result
cout << result << endl;
}


// Execute example code
void Replace_A_Switch()
{
cout << endl << "Executing function 'Replace_A_Switch'" << endl;

Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}


 mportant note: A function pointer always points to a function with a specific signature! Thus all functions, you want to use with the same function pointer, must have the same parameters and return-type!

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

*/

Saturday, December 5, 2009

How can I write a function that takes a variable number of arguments? What are the limitations with this? What is vprintf()?

The header stdarg.h provides this functionality. All functions like printf()scanf() etc use this functionality.


The program below uses a var_arg type of function to count the overall length of strings passed to the function.


#include 

int myfunction(char *first_argument,...)
{
   int length;
   va_list argp;
   va_start(argp, first);
   char *p;

   length = strlen(first_argument);
   while((p = va_arg(argp, char *)) != NULL)
   {
     length = length + strlen(p);
   }

   va_end(argp);
   return(length);
}

int main()
{
  int length;
  length = myfunction("Hello","Hi","Hey!",(char *)NULL);
  return(0);
}





How can I find how many arguments a function was passed?

Any function which takes a variable number of arguments must be able to determine from the arguments themselves, how many of them there have been passed. printf() and some similar functions achieve this by looking for the format string. This is also why these functions fail badly if the format string does not match the argument list. Another common technique, applicable when the arguments are all of the same type, is to use a sentinel value (often 0, -1, or an appropriately-cast null pointer) at the end of the list. Also, one can pass an explicit count of the number of variable arguments. Some older compilers did provided a nargs() function, but it was never portable.



Is this allowed?


int f(...)
{
  ...
}


No! Standard C requires at least one fixed argument, in part so that you can hand it to va_start().




So how do I get floating point numbers passed as arguments?

Arguments of type float are always promoted to type double, and types char and short int are promoted to int. Therefore, it is never correct to invoke


va_arg(argp, float);


instead you should always use


va_arg(argp, double)


Similarly, use


va_arg(argp, int)


to retrieve arguments which were originally char, short, or int.




How can I create a function which takes a variable number of arguments and passes them to some other function (which takes a variable number of arguments)?

You should provide a version of that other function which accepts a va_list type of pointer.



So how can I call a function with an argument list built up at run time?

There is no portable way to do this. Instead of an actual argument list, you might want to pass an array of generic (void *) pointers. The called function can then step through the array, much like main() steps through char *argv[].




What is the use of vprintf()vfprintf() and vsprintf()?

Below, the myerror() function prints an error message, preceded by the string "error: " and terminated with a newline:


#include 
#include 
void myerror(char *fmt, ...)
{
  va_list argp;
  fprintf(stderr, "error: ");
  va_start(argp, fmt);
  vfprintf(stderr, fmt, argp);
  va_end(argp);
  fprintf(stderr, "\n");
}

C code to return a string from a function

This C program wont work!


char *myfunction(int n)
{
   char buffer[20];
   sprintf(buffer, "%d", n);
   return retbuf;
}



This wont work either!


char *myfunc1()
{
  char temp[] = "string";
  return temp;
}


char *myfunc2()
{
   char temp[] = {'s', 't', 'r', 'i', 'n', 'g', '\0'};
   return temp;
}


This will work
The returned pointer should be to a static buffer (like static char buffer[20];), or to a buffer passed in by the caller function, or to memory obtained using malloc(), but not to a local array. 


char *myfunc()
{
   char *temp = "string";
   return temp;
}

int main()
{
   puts(myfunc());
}



So will this


calling_function()
{
  char *string;
  return_string(&string);
  printf(?\n[%s]\n?, string);
}

boolean return_string(char **mode_string /*Pointer to a pointer! */)
{
   *string = (char *) malloc(100 * sizeof(char));
   DISCARD strcpy((char *)*string, (char *)?Something?);
}

Thursday, December 3, 2009

Questions about printf

1. Look at the code below (funny question)
void main() { 

if(X)

{

printf("Hello");

}

else

{

printf(" World");

}

}
 What should X be replaced with inorder to get the output as "Hello World"?
And here comes the answer....
#include  

int main(){

if(!printf("Hello"))

{

printf("Hello");

}

else

{

printf(" World");

}

}

2.
#include
int main()
{
int i=448;
printf("%d\n",printf("%d",printf("%d",i))); return 0;
}

Output: 44831

3.

main()
{
int i=0;
for(;i++;printf("%d",i)) ;
printf("%d",i);
}
Answer:
1
Explanation:
before entering into the for loop the checking condition is "evaluated".
Here it evaluates to 0 (false) and comes out of the loop, and i is
incremented (note the semicolon after the for loop).

Return values of some functions in c

scanf

scanf("%d" , & i); //10 is given as input

Scanf returns number of items successfully read and not 1/0. Here 10 is given as input which should have been scanned successfully. So number of items read is 1.

printf
Upon a successful return, the printf() function returns the number of characters printed (not including the trailing '\0' used to end output to strings). If the output was truncated due to this limit then the return value is the number of characters (not including the trailing '\0') which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated. If an output error is encountered, a negative value is returned.
eg.
#include
int main()
{
int i=448;
printf("%d\n",printf("%d",printf("%d",i))); return 0;
}

Output: 44831
We proceed from right to left ... 1st 448 is printed, that has 3 characters, than 3 is printed and finally as 3 is 1 digit no. we print 1
alternatively if we use the string :
printf("%d\n",printf("%d a ",printf("%d b ",i)));
Output: 448 b 6 a 4
Now we have to count 448+1 space + b+1 space = 6 characters 
6 +1 space + a + 1 space = 4

Saturday, June 27, 2009

Passing 2 D array to function

double f(double values[][4], int n);

int main() {
  double beans[3][4] = {
                         { 1.0,  2.0,  3.0,  4.0},
                         { 5.0,  6.0,  7.0,  8.0},
                         { 9.0, 10.0, 11.0, 12.0}
                       };

 printf(" %f\n",f(beans, sizeof beans/sizeof beans[0]));
 getch();
  return 0;
}

double f(double array[][4], int size) {
  double sum = 0.0;
  int i,j;
  for( i = 0 ; i < size ; i++)      
    for( j = 0 ; j < 4 ; j++)       
      sum += array[i][j];
     
  return sum;
}

Another method is you dynamically allocate array and than pass its pointer to the function.
#include
#include
#include
// Ref : http://www.eskimo.com/~scs/cclass/int/sx9b.html
void printArray(int **array, int m, int n)
{
     int i,j;
 for(i=0;i
   for( j=0;j
printf("%d\n",array[i][j]);

     printf("\n");
}
int main()
{
      int i,j,k=0, m=5, n=20;
      int **a=(int **)malloc(m*sizeof(int *));
      for(i=0;i
      for(i=0;i      //for(i=0;i
      printArray(a,m,n);
      system("PAUSE");
      return 0;
}