Monday, April 27, 2015

1. Functions
Khai báo:

 return_type function_name( parameter list );  

return_type là kiểu dữ liệu trả về: char, int, float, void, *void, struct, union, enum

Ex:
functions.c
 #include <stdio.h>  
 /* function declaration */  
 int max(int num1, int num2);  
 int main ()  
 {  
   /* local variable definition */  
   int a = 100;  
   int b = 200;  
   int retmax;  

   /* calling a function to get max value */  
   retmax = max(a, b);  
   printf( "Max value is : %d\n", retmax ); 
 
   return 0;  
 }  
 /* function returning the max between two numbers */  
 int max(int num1, int num2)  
 {  
   /* local variable declaration */  
   int ret;  
   if (num1 > num2)  
    ret = num1;  
   else  
    ret = num2;  
   return ret;  
 }  

2. Functions & Pointer
Bản chất của quá trình truyền tham số vào hàm là tạo ra một bản sao (copy) của các biến tham số đầu vào và các biến bên ngoài hàm, ví dụ

 void max(int *ret, int num1, int num2);   
 int main ()   
 {   
   int a = 100;  
   int b = 200;  
   int *retmax = NULL;
  
   retmax = (int*)malloc(sizeof(int));  
   if(!retmax) return 0; 
 
   /* calling a function to get max value */  
   max(retmax, a, b); 
 
 }   

Khi gọi max(retmax, a, b) thì chương trình sẽ thực hiện việc copy dữ liệu của các tham số
 ret = retmax; /* ret va retmax là hai biến khác nhau và cùng trỏ đến một vùng nhớ */  
 num1 = a;  
 num2 = b;  


2.1 Pointer
Trong ví dụ functions.c thì kết quả của hàm được return lại khi exit hàm, ở mục này sẽ không cần dùng return mà dùng pointer để lấy kết quả trả về, với việc dùng pointer thì sẽ có thể đưa được nhiều biến từ ngoài vào bên trong một hàm để xử lý hàm hơn.

Ex:
functions-pointer1.c
 #include <stdio.h>  
 /* function declaration */  
 void max(int *ret, int num1, int num2);  
 int main ()  
 {  
   /* local variable definition */  
   int a = 100;  
   int b = 200;  
   int retmax;
  
   /* calling a function to get max value */  
   max(&retmax, a, b);  
   printf( "Max value is : %d\n", retmax ); 
 
   return 0;  
 }  
 /* function returning the max between two numbers */  
 void max(int *ret, int num1, int num2)  
 {  
   /* local variable declaration */  
   int result;  
   if (num1 > num2)  
     result = num1;  
   else  
     result = num2;  

   *ret = result; /* bien con tro ret tro den bien retmax */ 
   return;  
 }  


hoặc:
functions-pointer2.c
 #include <stdio.h>  
 #include <stdlib.h>  
 /* function declaration */  
 void max(int *ret, int num1, int num2);  
 int main ()  
 {  
   /* local variable definition */  
   int a = 100;  
   int b = 200; 
 
   int *retmax = NULL;  
   retmax = (int*)malloc(sizeof(int));  
   if(!retmax) return 0;  

   /* calling a function to get max value */  
   max(retmax, a, b);  
   printf( "Max value is : %d\n", *retmax ); 
 
   free(retmax);  

   return 0;  
 }  
 /* function returning the max between two numbers */  
 void max(int *ret, int num1, int num2)  
 {  
   /* local variable declaration */  
   int result;  
   if (num1 > num2)  
     result = num1;  
   else  
     result = num2;  
   /* ret va retmax là hai biến khác nhau và cùng trỏ đến một vùng nhớ */
   *ret = result;  
   return;  
 }  


2.2 Pointer-to-Pointer
Như đã giải thích ở trên, việc truyền tham số bản chất là quá trình tạo ra bản sao của các tham số, như vậy nếu khai báo là

void max(int *ret, int num1, int num2); 
/* ret va tham so truyen vao cung tro den mot vung nho */
thì sẽ không thể đưa nguyên một pointer vào trong hàm, muốn làm được điều này thì cần có
pointer-to-pointer

Ex:
functions-pointer2pointer.c
 #include <stdio.h>  
 #include <stdlib.h>  
 #include <stdbool.h> 
 
 /* function declaration */  
 bool max(int **ret, int num1, int num2);  

 int main ()  
 {  
   /* local variable definition */  
   int a = 100;  
   int b = 200;  
   int *retmax = NULL; 
 
   /* calling a function to get max value */  
   if(max(&retmax, a, b)){  
     printf( "Max value is : %d\n", *retmax );  
     free(ret);  
   }  

   return 0;  
 } 
 
 /* function returning the max between two numbers */  
 bool max(int **ret, int num1, int num2)  
 {  
   int *result = NULL;  
   result = (int*)malloc(sizeof(int));  
   if(!result) return false;  
   if (num1 > num2)  
     *result = num1;  
   else  
     *result = num2; 
 
   /*  
    * vi ret la pointer-to-pointer nen *ret chua dia chi cua pointer ma no tro den  
    * tuc la *ret = retmax  
    * nhu vay nho co pointer-to-pointer ma ta co the dua pointer tu ngoai vao  
    * trong ham de cap phat bo nho va thao tac du lieu tren no  
   */  
   *ret = result;  
   return true;  
 }  

Ứng dụng tương tự như ở chương trình trên là dùng trong các hàm đệ quy mà trong hàm đó cần cấp phát động một mảng dữ liệu, sẽ được đề cập sau ở một bài toán thực tế quản lý danh sách các media file trong storage (usb, sdcard, ...). Link (updating)

2.3 Function pointer
Đã được đề cập sơ bộ ở phần Pointer, ở bài viết này thêm ví dụ về việc khai báo con trỏ hàm thông qua typedef

Ex:
functions-pointer3.c
 #include <stdio.h>  
 #include <stdlib.h>  
 //=====================================================  
 int add(int a, int b){  
   return (a+b);  
 }  
 int sub(int a, int b){  
   return (a-b);  
 }  
 //=====================================================  
 int operator_math1(int a, int b, int (*ope_func)(int, int)){  
   return ope_func(a, b);  
 }  
 //=====================================================  
 typedef int (*ope_function)(int, int);  
 int operator_math2(int a, int b, ope_function ope){  
   return ope(a, b);  
 }  
 //=====================================================  
 int main ()  
 {  
   int a = 3;  
   int b = 2;  
   int ret;
  
   ret =  operator_math1(a, b, &add); /* hoac operator_math(a, b, add) */  
   printf("a+b= %d \n", ret);  
   ret =  operator_math1(a, b, &sub); /* hoac operator_math(a, b, sub) */  
   printf("a-b= %d \n", ret);  

   ret =  operator_math2(a, b, &add); /* hoac operator_math2(a, b, add) */  
   printf("a+b= %d \n", ret);  
   ret =  operator_math2(a, b, &sub); /* hoac operator_math2(a, b, sub) */  
   printf("a-b= %d \n", ret); 
 
   return 0;  
 }  


Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Lập trình hệ thống nhúng Linux . Powered by Luong Duy Ninh -