2012年11月13日 星期二

利用Makefile技巧,製作release version 或 debug version bin檔 (Using Makefile to compile release or debug bin file)

We can add some LABEL to mark some debug message that need to be show up in "debug version".
Oppositely , we can disable these debug message for "release version"with the
same source.


========= Makefile===============================

ifeq ($(DEBUG),y)
CFLAGS :=$(CFLAGS) -DDEBUG
endif

=========compile command =========================
 release mode:
 make clean; make

debug mode:
make clean; make DEBUG:=y

出貨給客戶,就編release mode給他,如此一來他們不會看到任何message從terminal
跑出來

若是自己要debug 相同的code就編debug mode,方便自己看message
就不需要進去code在修修改改了

=======Source code example==========================

      #ifdef DEBUG
       printf ( "debug message" );
      #endif

  if debug mode , "debug message" will show up , and release mode doesn't.


    為了整齊美觀,可以特地寫一個小function
    把debug message 寫在裡面
    就不會整篇code看到一大堆 #ifdef DEBUG



 
   for example:

   void debug_print_info_variable ( char *info , char *var)
{
    #ifdef DEBUG
    printf ( "%s , %s\n" , info , var );
    #endif
}









.....
....
.......
source code:
src_child_status =  g_match_info_fetch ( child_match_info , 6 ) debug_print_info_variable ("\nSTATUS= %s\n", src_child_status);
src_real_child_status = update_treeview_TransferDeviceStatus( src_child_status );
debug_print_info_variable ("\nREAL STATUS= %s\n", src_real_child_status);
       

二維陣列 行與列 Two-dimensional array row and column

國字的行跟列,其實我自己從國小放學要排隊伍回家,

就常常搞不清楚。

直的是行  還是橫的是行???

轉個方向,好像這樣又是行,那樣才是列。

古語不是有句話 橫看成嶺側成峰,遠近高低皆不同。

長大之後,學程式語言,又遇到 行  與  列

考試常常忘記

How to declare 2-dimensional array:

int array_name [row][column];

for example:

int M[2][3] = { {1,2,3},
                         {4,5,6} };


array layout:

M
(0,0)    1     |  (0,1)    2   |  (0,2)    3    |         ---->row 0

(1,0)   4      |  (1,1)    5   |   (1,2)   6    |         ---->row 1

row-major: (c/c++ default)
1,2,3,4,5,6

column-major:
1,4,2,5,3,6

2012年11月10日 星期六

IEEE754 convert

for example : 47.75


(1) convert to binary :

    47.75 = 10111.11

(2) Normalization:

    1.011111 x 2^5

(3)

   The exponent ---> +5

   +5 + 127 = +132

  132 = 10000100


(4)

1bit                          8bits                      23bits
0 : postive
1 : negative            exponent                  others
0                         10000100                   01111100000000000000000
   

2012年11月6日 星期二

容易忘記的運算符縮寫 ( Operators in C )

(Addition assignment)   a += b  ---> a = a + b


(Subtraction assignment) a -= b ---> a = a - b





Ternary conditional (三元條件)

c = (a > b) ? 1 : 2

means:

if (a > b )
{
    c = 1;
}else
{
    c= 2;
}



2012年11月5日 星期一

ANCI C 字串轉小寫( string convert lower case)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

char *dot_location = "ABCDEF";
int String_length;
if ( dot_location != NULL  )
        {
            String_length = strlen ( dot_location );
            dot_location = tolower_extension( dot_location , String_length);
        }


.....
........
............
char *tolower_extension( char *dot_location , int length   )
{
   
           printf ( "length= %d\n" , length);
           int i ;
            for (i = 1 ; i < length + 1 ; i++ )
            {
                dot_location[i] = tolower( dot_location[i] );          
            }   
            printf( "%s\n", dot_location );
           
   
    return dot_location;
}     


====output================================
 length=6  (p.s: strlen don't include NULL character)
 abcdef

2012年11月4日 星期日

分辨副檔名 ( Distinguish Filename Extension)

strrchr : Locate last occurrence of character in string
              for example : filename is  hi_.mp3.txt
              its Filename Extension is .txt , not .mp3
              this is what I think to use "strrchr"
              你要找的字元,在該字串中最後一次出現的位置
              我故意取一個怪怪的檔名  hi_.mp3.txt   他的副檔名應該是.txt
              有兩種應用方法,如下所示:

char *dot_location;
char *filename = "hi_.mp3.txt" ;

dot_location = strrchr( filename , '.' );
printf ("Filename Extension = %s \n", dot_location  );
printf ("Last occurence of '.' found at %d \n", dot_location - filename + 1 );

 if ( (dot_location != NULL ) &&
                ((!strcmp( dot_location,".txt")) ||
                (!strcmp( dot_location,".doc"))  ||
                (!strcmp( dot_location,".pdf")) )
           ) 
            
        {
            printf ("document match!\n");
         }

======output=====================
Filename Extension = .txt
Last occurence of '.' found at 8
document match!

2012年11月2日 星期五

Link list example

想設計一個link list去儲存資料夾中的檔案名稱名與檔案大小
因為資料夾中的檔案隨時都會更動,想說用link list比較有彈性空間
以下是我自己寫的

我的領悟力一向很低,記得以前在學校學link list怎麼都學不會
聽也聽不懂這是什麼鬼東西!!!>"<
現在自己出來工作之後,有點時間靜下心來寫看看
原來這個鬼東西還滿好用低!嗯~

I want to design a link list to store file's name and file's size in a directory.
This is a simple code, very simple , I wrote it.

struct image_list{
       
        char *filename;
        int size;
        struct image_list *next;
    };   
   


    struct image_list *head = NULL;
    struct image_list *prev , *current;
    //initial a node , first node
    current = (struct image_list *)malloc (sizeof(struct image_list));
    current->filename = "file1";
    current->size = 500;
    current->next = NULL;
    head = current;
    printf ("current->filename.........=%s\n" ,current->filename );
    printf ("current->size.........=%d\n" ,current->size);
   
    //new a node , second node
    prev = current;
    current = (struct image_list *)malloc (sizeof(struct image_list));
    current->filename = "file2";
    current->size = 3400;
    current->next = NULL;
    prev->next = current;
    printf ("current->filename.........=%s\n" ,current->filename );
    printf ("current->size.........=%d\n" ,current->size);
   
    //go travel each node
    printf ("go travel each node---------------------------------\n" );
    current = head; // go to the first node
    while (current != NULL)
    {
        printf ("current->filename.........=%s\n" ,current->filename );
        printf ("current->size.........=%d\n" ,current->size);
        current = current->next;
   
    }




======output=====================================

current->filename.........=file1
current->size.........=500
current->filename.........=file2
current->size.........=3400
go travel each node---------------------------------
current->filename.........=file1
current->size.........=500
current->filename.........=file2
current->size.........=3400

跟黏土一樣 !好用的sprintf

I want to introduce how to combine or stick your Linux command and variable.
I use sprintf .....it is useful!!! awesome!!!

我要做的指令是:

cp /var/web/enter_folder.asp  /var/web/mount/sda1/"new dir"/."new dir".asp

/var/web/mount/sda1/"new dir"/."new dir.asp"   之所以會在檔名前後加上雙引號
quote ("") 是為了把檔名好好包起來XD
避免linux中空白字元會被系統認為指令已經中止了

#include <stdio.h>

char temp[512] = {0};

sprintf (temp , "cp %s/enter_folder.asp %s/%s/\"%s\"/.\"%s\".asp" , mount_point , mount_point , path_for_href , folder_name  ,folder_name);

system (temp);

就可以把我要的變數跟指令"黏"在一起 丟出去使用了!

裡面如果遇到 quote (") 要用跳脫字元(escape) Backslash (\) , 讓( " ) 忠實地
呈現在字串中,否則會被sprintf 忽略




2012年11月1日 星期四

Linux中,要讀出一個資料夾中所有檔案資訊(名稱,權限,大小等)

In Linux , How to open a directory and read all files in this directory?
read all file's information (filename , permission , size ..etc)

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>


struct stat attr;
struct dirent *entry = NULL;


DIR *mydir = opendir( "/var/web/mount" );
stat ( "/var/web/mount" , &attr );
 while((entry = readdir(mydir))) /* If we get EOF, the expression is 0 and
                                                    * the loop stops. */
    {
       
      
        printf ("Filename = %s\n" ,entry->d_name );
        printf ("FileType = %d\n", entry->d_type);

        printf("Size: %d K\n", (unsigned)attr.st_size/1024 +1 );
        printf("Permissions: %o\n", (int)attr.st_mode & 07777);
        printf("Is directory? %d\n", attr.st_mode & ST_ISDIR);
    }






===============================================
struct--stat
----------------------------------------------------
struct stat {
    mode_t    st_mode;    // file type & mode(permissions)
    ino_t     st_ino;     // i-node number(serial number)
    dev_t     st_dev;     // device number(filesystem)
    dev_t     st_rdev;    // device number for specials files
    nlink_t   st_nlink;   // number of links
    uid_t     st_uid;     // user ID of owner
    gid_t     st_gid;     // group ID of owner
    off_t     st_size;    // size in bytes, for regular files
    time_t    st_atime;   // time of last access
    time_t    st_mtime;   // time of last modification
    time_t    st_ctime;   // time of last file status change
    long      st_blksize; // best I/O block size
    long      st_blocks; -// number of 512-byte blocks allocated
};

===============================================


配合struct dirent,定義如下:
struct dirent {
    ino_t d_ino;
    off_t d_off;
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];
};
d_ino 此目錄進入點的inode
d_off 目錄文件開頭至此目錄進入點的位移
d_reclen d_name的長度,不包含NULL字符
d_type d_name所指的檔案類型
d_name 檔名
其中unsigned cahr d_type;可以來判斷是子目錄或是一般的檔案。
 
 

struct 什麼時候要用點(.) 什麼時候要用箭頭 (->)

struct 什麼時候要用點(.)  什麼時候要用箭頭 (->)
當你new一個struct時候,就用 點(.)
當這個struct不是你new出來的,就用箭頭 (->)訪問他
目前暫時是這樣理解的

I mean ,
In struct data type, when we should use dot / period (.) to access its data
                                when we should use arrow (->) to access its data

if we " new " a struct , we should use dot / period (.) to access its data
here is an example as below:


#include   <stdio.h>
#include   <stdlib.h>
struct   point
{
      int   x,y;
};

int   main(int   argc,   char   *argv[])
{
    struct     point   one;
    one.x=1;
    one.y=2;
    printf( "%d         %d\n ",one.x,one.y);
    struct     point   *two;
    two=&one;
    printf( "%d         %d\n ",two-> x,two-> y);
   
    system( "PAUSE ");
    return   0;
}


************************
1       2(one.x和one.y)
1       2(two.x和two.y)