Problems 4
  1. Theory
    1. Will these functions leak memory?
      void stat(){
      	double a[500];
      }
      
      void vla(size_t n){
      	double a[n];
      }
      
      void mal(){
      	double* a=(double*)malloc(500*sizeof(double));
      }
      
      void maf(){
      	double* a=(double*)malloc(500*sizeof(double));
      	free(a);
      }
      
      double* mar(){
      	double* a=(double*)malloc(500*sizeof(double));
      	return a;
      }
      
    2. Which lines, if any, of the following program are incorrect?
      struct vector {double x,y,z;};
      struct vector v = {1,2,3};
      struct vector x = {1,2,3};
      struct vector v = [1,2,3];
      struct vector u = {.x=1,.y=2,.z=3};
      struct vector w = {.z=3,.y=2,.x=1};
      vector y;
      typedef struct vector vector;
      vector z;
      
    3. Which of the following Bash commands creates a list of '.c'-files in the current directory? Hint: Redirecting to and from the standard file handles.
      ls *.c > cfiles.txt
      ls *.c 1> cfiles.txt
      ls *.c 2> cfiles.txt
      ls *.c &> cfiles.txt
      ls $PWD/*.c | awk -F/ '{print $NF}' > cfiles.txt
      rm -f cfiles.txt; for i in *.c; do echo $i >> cfiles.txt; done
      
    4. What is the meaning of the input parameters of the following main function?
      int main(int argc, char* argv[]) { /* do stuff */ }
      
    5. How can you convert a parameter of the main function into double or int number?
    6. What will the following program print?
      #include<stdio.h>
      #include<stdlib.h>
      double* foo(){ static double a[]={0,0,0}; return a; }
      int main(){
        double* a=foo(); a[2]=1;
        double* b=foo(); b[2]=2;
        printf("a[2] = %g\n",a[2]);
      return EXIT_SUCCESS;}
      
    7. What will the following program print?
      #include<stdio.h>
      #include<stdlib.h>
      double* foo(){ double* a=(double*)malloc(3*sizeof(double)); return a; }
      int main(){
        double* a=foo(); a[2]=1;
        double* b=foo(); b[2]=2;
        printf("a[2] = %g\n",a[2]);
        free(a);a=NULL;
        free(b);b=NULL;
      return EXIT_SUCCESS;}
      
  2. Practice
    1. Consider a representation of complex numbers as the structure typedef struct {double re,im;} my_complex;
      1. Implement the following set of functions to deal with complex numbers:
        my_complex my_complex_add(my_complex a, my_complex b); /* returns a+b */
        my_complex my_complex_sub(my_complex a, my_complex b); /* returns a-b */
        my_complex my_complex_mul(my_complex a, my_complex b); /* returns a*b */
        my_complex my_complex_div(my_complex a, my_complex b); /* returns a/b */
        my_complex my_complex_set(double x, double y); /* returns x+i*y */
        my_complex my_complex_conjugate(my_complex z); /* returns complex conjugate */
        my_complex my_complex_exp(my_complex z); /* returns complex exponential function of the argument: you are only allowed to use real functions from math.h here ;) */
        void my_complex_print(my_complex z); /* prints the complex number */
        int my_complex_equal(my_complex a, my_complex b); /* returns 1 if equal, 0 otherwise */
        
        Hints:
        typedef struct {double re,im;} my_complex;
        
        my_complex my_complex_add(my_complex a, my_complex b){
        	double x = a.re + b.re, y = a.im + b.im;
        	my_complex result = {.im = y, .re = x}; /* ;) */
        	return result;
        	}
        
        int my_complex_equal(my_complex a, my_complex b){
        	if( a.re==b.re && a.im==b.im) return 1; else return 0;
        	}
        
        double my_complex_abs(my_complex z){
           double x=fabs(z.re), y=fabs(z.im);
           if(x==0 && y==0) return 0;
           if(x>y) {double t=y/x; return x*sqrt(1.0+t*t);}
           else    {double t=x/y; return y*sqrt(1.0+t*t);}
        }
        
        my_complex my_complex_div(my_complex a, my_complex b){
           if( fabs(b.im)<abs(b.re) )
              {
                 double e = b.im/b.re;
                 double f = b.re+b.im*e;
                 my_complex result = {.re = (a.re+a.im*e)/f, .im = (a.im-a.re*e)/f};
                 return result;
              }
           else
              {
                 double e = b.re/b.im;
                 double f = b.im+b.re*e;
                 my_complex result = {.re = (a.im+a.re*e)/f, .im = (-a.re+a.im*e)/f};
                 return result;
              }
           }
        ...
        
      2. Write a main program that tests you functions
        Hints:
        my_complex a = {1,2}, b = {3,4}, r = {4,6};
        my_complex c = my_complex_add(a,b);
        if( my_complex_equal(c,r) ) printf("test 'add' passed :) \n");
        else printf("test 'add' failed :( \n");
        
    2. Consider an implementation of matrices using the structure typedef struct {int size1,size2; double* data;} my_matrix;.
      1. Implement the following set of functions to deal with these matices:
        my_matrix* my_matrix_alloc(int size1, int size2); /* allocates memory for a matrix size1-times-size2 */
        void my_matrix_free(my_matrix* m); /* frees the memory */
        void my_matrix_set(my_matrix* m, int i, int j, double value); /* m_{ij} = value */;
        double my_matrix_get(my_matrix* m, int i, int j); /* returns m_{ij} */
        void my_matrix_set_identity(my_matrix* m); /* m = unity matrix */
        void my_matrix_set_zero(my_matrix* m); /* all elements = 0 */
        
        Implement range checking using <assert.h>.
        Hint:
        typedef struct {int size1,size2; double* data;} my_matrix;
        
        my_matrix* my_matrix_alloc(int size1, int size2){
          my_matrix* m = (my_matrix*)malloc(sizeof(my_matrix));
          (*m).size1 = size1;
          (*m).size2 = size2;
          (*m).data = (double*)malloc(size1*size2*sizeof(double));
          if( m==NULL ){
            fprintf(stderr,"error in my_matrix_alloc\n");
            return NULL;
        		}
          return m;
        }
        
        void my_matrix_free(my_matrix* m){ free(m->data); free(m); }
        
        void my_matrix_set(my_matrix* m, int i, int j, double value){
          assert(0<=i && i<(*m).size1);
          assert(0<=j && j<(*m).size2);
          int indx = i*(*m).size2+j;
          (*m).data[indx]=value;
        }