Monday, June 3, 2013

ANSI C (2)

12. recursion
#include <stdio.h>

void binary_to_ascii( unsigned int value)

{

   unsigned int quotient;

   quotient=value/10;

   if(quotient!=0)

      binary_to_ascii(quotient);//recursion

   putchar(value%10+'0');



}



value=4267  quotient=?

value=4267  quotient=426

value=426  quotient=42

value=42  quotient=4

value=4  quotient=0

value=42  quotient=4

value=426 quotient=42

value=4267  quotient=426


13.variable parameter

#include <stdarg.h>

float average(int n_values,...)

{

  va_list var_arg;

  int count;

 float sum=0;



 var_start(var_arg,n_values);

for(count=0; count<n_values;count+=1)

{

   sum+=va_arg(var_arg, int);

}

va_end(var_arg);

return sum/n_values;

}


14. array
//(1)

int array[10];

2[array]  ==  *(2+(array)) ==array[2];



//(2)

int array[10], a;

for(a=0;a<10;a=a+1)

     array[a]=0;



int array[10], *ap;

for(ap=array; ap<array+10;ap++)  // more efficient here than array

   *ap=0;

// when   accessing the array elements by a fixed increment,  using pointer would more efficient than that of array index;



//(3)

#include <stdio.h>

#include <stdlib.h>

void my_parameter1(char string[]);

void my_parameter2(char *string);

int main()

{

    char arr[]="zhiguang";

    char *arr1="zhiguang";

    printf("%d\n",sizeof(arr));//9--array: 'z'  'h' ... 'g','\0'

    printf("%d\n",strlen(arr));//8--array:  'z'  'h' ... 'g'

    printf("%d\n",sizeof(arr1));//4--pointer size

    printf("%d\n",strlen(arr1));//8-- the content length the pointer points to

    my_parameter1(arr);//4--pointer size, it is not 9, because it only pass the array as pointer in fact

    my_parameter1(arr1);//4--pointer size

    my_parameter2(arr);//4--pointer size

    my_parameter2(arr1);//4--pointer size

    return 0;

}

void my_parameter1(char string[])

{

   printf("%d\n",sizeof(string));

}

void my_parameter2(char *string)

{

   printf("%d\n",sizeof(string));

}



//(4)

    char arr[]="zhiguang";

    char *arr1="zhiguang";//constant

    arr[2]='w';// ok

    arr1[2]='w';//error, because it is constant

    *(arr1+2)='w';//error, because it is constant



//(5)

int matrix[3][10];

matrix;//pointer, points to the first whole row, 10 elements

matrix+1;//pointer, points to the second whole row, 10 elements

*(matrix+1);// it is an array, also the points to the first element in second row;

*(matrix+1)+5;//pointer, points to matrix[1][5]

*(*(matrix+1)+5);//value, content of matrix[1][5]

*(matrix[1]+5);//value, content of matrix[1][5]

matrix[4,3]==matrix[3];//because of ','



//(6)

int vector[10], *vp=vector;//ok

int matrix[3][10], *mp=matrix;//error;

int (*p)[10]=matrix;//ok, p is a pointer first, points to an array with 10 elements;

int *pi=&matrix[0][0];//ok

int *pi=matrix[0];//ok



//(7)

// if the parameter mat is 2-D array, you can declare the function as:

void fun(int (*mat)[10]);//ok

void fun(mat[][10]);//ok

//however, the following is wrong

void func2(int **mat);//error



//(8)

char  *keyword[5];// an array, each element is a pointer;

char const *keyword[]={"do","for","while"};

// the best way to determine the length of this array is:

sizeof(keyword)/sizeof(keyword[0]);



//(9)
void function0(int);
void function1(int);
void function2(int);
int main(void)
{
   void (*f[3])(int) = {function0,function1,function2};
//f is first an array, each element is a pointer, pointing to a func with an int parameter
   return 0;
}


15. string
//strlen returns an unsigned in, so

if(strlen(x)>strlen(y)) //always right

if(strlen(x)-strlen(y)>=0) //sometimes, error

if(strlen(x)>=10)//always right

if(strlen(x)-10>=0) //sometimes, error


16. void *
//any type pointer could be converted to void*, and that is why

void  *memcpy(void *dst, void const *src, size_t length);

void  *memmove(void *dst, void const *src, size_t length);

void  *memcmp(void *a, void const *b, size_t length);

//...


17. structure
//(1)

struct{

   int a;

   int b;

}x;



struct SIMPLE{

   int a;

   int b;

};

struct SIMPLE x;



typedef struct {

   int a;

   int b;

} Simple;

Simple x;



//(2)

typedef struct{

    int a;

    struct SELF_REF3 *b;//error, there is no SELF_REF3 yet;

    int c;

} SELF_REF3; 



typedef struct SELF_REF3_TAG{

    int a;

    struct SELF_REF3_TAG *b;//OK, there is SELF_REF3_TAG already;

    int c;

} SELF_REF3_TAG; 



//(3)

// the following is error

struct A{

struct B *partner;

};

struct B{

struct A *partner;

}

//the following is correct

struct B;// declare first, even if it is not complete

struct A{

struct B *partner;

};

struct B{

struct A *partner;


18. memory
//(1)

void *malloc(size_t size);

void free(void *pointer);

// if malloc failed, it would return an NULL



//(2)

int *pi;

pi=malloc(25*sizeof(int));

if(pi==NULL)

{

   printf("out of memory!\n");

   exit(1);

}



//(3)

// the pointer passed to free must be generated by malloc, calloc, or realloc, not others;



//(4)

// simplest way of memory leak

for(int i=0; i<10;i++)

    int *p=malloc(25*sizeof(int));

No comments:

Post a Comment