User Tag List

+ Trả lời chủ đề
Trang 1/3 123 CuốiCuối
Hiện kết quả từ 1 tới 10 của 24

Chủ đề: Programming Style

  1. #1
    Quân Nhân Danh Dự
    Tham gia ngày
    Jan 2004
    Bài gửi
    1.404

    Mặc định Programming Style

    Sau một thời gian ra trường và đi làm với công việc chính là lập trình, nhiều khi tôi nhìn lại thời đại học và giật mình vì thấy mình đã học lập trình một cách quá hời hợt. Có rất nhiều kiến thức cơ bản mà tôi đã không học (hay không được dạy?). Nhớ lại hồi năm thứ nhất học Pascal, chúng tôi được học các lệnh if the, while, for…với các ví dụ kiểu như tìm tất cả các ước số của một số nguyên, hay quản lí sắp xếp sinh viên…Đến năm thứ 3 học C, chúng tôi vẫn học từng ý lệnh với từng ý kiểu bài tập. Có quá nhiều những kiến thức vô cùng quan trọng mà các thầy không hề nhắc đến (chứ chưa nói gì đến dạy), chẳng hạn như: Phong cách lập trình (Programming Style), kĩ thuật gỡ lỗi (debug), kiểm thử (test), hiệu năng của chương trình (performance), tính khả chuyển (portable)…Đáng tiếc là sự tồn tại của những kiến thức này lại không hiển nhiên cho lắm để sinh viên có thể tự tìm sách để đọc.

    Một trong những cuốn sách tuyệt vời viết về những chủ đề nói trên là cuốn “The practice of Programming” của Brian W. Kernighan và Rob Pike (tôi ước là mình biết đến cuốn sách này sớm hơn). Đây là một cuốn sách được “recommend” cho tất cả các lập trình viên của tất cả các ngôn ngữ lập trình. Trong bài viết này tôi muốn giới thiệu chương đầu tiên của cuốn sách với tiêu đề “Style”. Những chương tiếp theo tôi sẽ giới thiệu khi có thời gian, hoặc tốt nhất là mọi người tự tìm đọc bản tiếng Anh để hấp thu được toàn bộ sự sâu sắc của cuốn sách. (Tôi có bản mềm của cuốn sách này, ai cần có thể PM)

    Chương 1: Phong cách lập trình (programming style)

    Mở đầu

    Hãy xem đoạn mã sau đây:

    Mã:
    if( ( country == SING ) || ( country == BRNI )  ||
         ( country == POL ) || ( country == ITALY ) ) {
    
    /*
     * If the country is Singapore, Brunei or Poland
     * then the current time is the answer time 
     * rather than the off hook time
     * Reset answer time and set day of week
     */
    …
    }
    Đoạn mã trên được viết một cách rất đẹp đẽ, được comment cẩn thận và là một phần trong một chương trình chạy hoàn toàn đúng. Tuy nhiên đoạn mã này vẫn gây ra một chút băn khoăn cho người đọc: Những đất nước Singapore, Brunei, Poland và Italy có mối liên hệ gì với nhau? Tại sao Italy lại không được nói đến trong phần comment? Vì đoạn mã và phần comment có sự khác nhau nên một trong hai thứ phải sai mà cũng có thể là cả hai đều sai. Đoạn mã có nhiều khả năng đúng hơn vì nó đã được test; có thể phần comment đã không được cập nhật theo sự thay đổi của đoạn mã. Nếu là người bảo trì cho đoạn chương trình này, rất có thể bạn cần phải biết mối quan hệ giữa các quốc gia được nhắc đến.

    Đoạn chương trình nói trên đại diện cho phần lớn các chương trình trong thực tế: Hầu hết chạy đúng nhưng vẫn cần phải cải tiến.

    Mục đích của style là làm cho chương trình trở nên dễ đọc đối với người viết và những người khác, một style tốt là một phần thiết yếu của việc lập trình tốt. Viết một chương trình chạy đúng là chưa đủ bởi chương trình không chỉ để cho máy tính đọc mà còn để các lập trình viên khác đọc. Hơn nữa, một chương trình có style tốt luôn có nhiều khả năng chạy đúng hơn một chương trình có style tồi.
    Vậy thế nào là một style tốt? Điều đó tùy thuộc vào quy định của từng công ty, tổ chức, dự án…Phần sau đây giới thiệu những style cơ bản nhất.

    1.1 Cách đặt tên cho biến và hàm

    Tên của biến hay hàm “đánh dấu” cho biến/hàm đó và mang thông tin về mục đích của đối tượng mà nó mô tả. Tên phải mang thông tin, rõ ràng, dễ nhớ và tốt nhất là phải phát âm được. Tên biến phải phù hợp với phạm vi (scope) của biến đó, phạm vi của biến càng rộng thì tên biến càng phải mang nhiều thông tin.

    Quy tắc 1: Đặt tên giàu tính mô tả cho các biến toàn cục và tên ngắn gọn cho các biến cục bộ.

    Các biến toàn cục có thể được sử dụng trong toàn chương trình, bởi vậy cần đặt tên đủ dài và đủ ý nghĩa để nhắc nhở người đọc về ý nghĩa của chúng. Nên viết comment bên cạnh phần khai báo của biến toàn cục. Ví dụ:

    Mã:
    int npending = 0; /* độ dài hiện thời của hàng đợi */
    Các hàm, lớp hay cấu trúc toàn cục cũng cần có các tên giàu tính mô tả về vai trò của chúng trong chương trình.

    Trái lại, các biến cục bộ chỉ cần các tên ngắn gọn. Đối với một biến cục bộ, chỉ cần đặt tên n hoặc npoints là đủ. Một tên đại loại như numberOfPoints là quá thừa! Theo thônglệ, các tên i và j được dành cho các chỉ số, p và q dành cho các con trỏ, s và t dành cho các xâu. Vì vậy, hoàn toàn không cần thiết để dùng các tên biết dài loằng ngoằng như sau:

    Mã:
    for( theElementIndex = 0; theElementIndex < numberOfElement; theElementIndex++ )
    
      elementArray[ theElementIndex ] = theElementIndex;
    Vòng lặp này có thể viết lại như sau mà vẫn đảm bảo tính dễ hiểu:

    Mã:
    for( i = 0; i < nelems, i++ ) 
      elem[ i ] = i;
    Các lập trình viên thường có xu hướng sử dụng các tên biến dài bất kể ngữ cảnh. Đó là một sai lầm bởi sự rõ ràng thường đạt được nhờ sự ngắn gọn. Thông thường người ta dùng các tên bắt đầu hoặc kết thúc bởi chữ “p” cho các biến con trỏ (chẳng hạn nodep), các tên bắt đầu bằng chữ hoa cho biến toàn cục (chẳng hạn Globals) và tất cả chữ cái hoa cho các hằng số (chẳng hạn CONSTANTS).

    Các namespace trong C++ và package trong Java góp phần làm rõ nghĩa của các tên mà không cần sử dụng các tên dài.

    Quy tắc 2: Đặt tên một cách nhất quán

    Các biến có liên quan phải được đặt các tên có liên quan, đồng thời phải làm nổi bật được sự khác nhau của chúng. Các tên trong lớp sau đây vừa quá dài vừa không hề nhất quán:
    Mã:
    class UserQueue
    {
      int noOfItemsInQ, frontOfTheQueue, queueCapacity;
    
      public int noOfUsersInQueue() {…}
    
    }
    Thứ nhất, cùng một nội dung là queue nhưng được biểu diễn bởi ba dấu hiệu: Q, Queue và queue. Thứ hai, các biến và các hàm thành phần của lớp UserQueue chỉ có thể được sử dụng bởi các đối tượng của lớp này, do vậy viết

    Mã:
    queue.queueCapacity
    hay

    Mã:
    queue.noOfUsersInQueue()
    rõ ràng là thừa. Chúng ta có thể viết lại lớp này với các tên mới như sau:

    Mã:
    class UserQueue
    {
      int nitems, front, capacity;
    
      public int nusers() {…}
    }
    Không chỉ bản thân đoạn mã định nghĩa lớp đó dễ hiểu hơn, mà những đoạn mã sử dụng lớp UserQueue cũng dễ hiểu hơn:

    Mã:
    queue.capacity++;
    n = queue.nusers();
    Lớp UserQueue vẫn có thể cải tiến thêm, bởi nitems và nusers thực chất là cùng biểu diễn một khái niệm và do đó chỉ cần sử dụng một trong hai tên đó mà thôi.

    Quy tắc 3: Đặt các tên “động” cho hàm

    Tên hàm nên là một động từ theo sau bởi một danh từ. Ví dụ:

    Mã:
    now = date.getTime();
    Các hàm trả về giá trị boolean nên được đặt tên thể hiện giá trị mà nó trả về. Ví dụ:

    Mã:
    isOctal( c )
    thì tốt hơn là

    Mã:
    checkOctal( c );
    vì cách đặt tên thứ nhất cho biết ngay rằng hàm trả về giá trị true nếu c là một số octal và trả về false trong trường hợp ngược lại.

    Quy tắc 4: Tên hàm phải phù hợp với chức năng

    Tên một hàm mô tả chức năng của hàm đó. Bởi vậy đặt tên hàm sai dễ dẫn đến việc hiểu sai chức năng của hàm. Ngược lại, một tên hàm đúng có thể giúp người đọc phát hiện ra các lỗi trong định nghĩa hàm. Dưới đây là một macro được đặt tên đúng nhưng định nghĩa lại sai:

    Mã:
    #define isoctal( c ) ( ( c ) >= ‘0’ && ( c ) <= ‘8’ )
    Trong trường hợp này, việc đặt tên đúng giúp chúng ta dễ dàng phát hiện ra lỗi sai. Định nghĩa đúng cho macro này phải là:

    Mã:
    #define isoctal( c ) ( ( c ) >= ‘0’ && ( c ) <= ‘7’ )
    Sau đây là một hàm với các tên hoàn toàn mâu thuẫn với chức năng của nó:

    Mã:
    public boolean inTable( Object obj ) {
    
      int j = this.getIndex( obj );
    
      return ( j == nTable );
      
    }
    Hàm getIndex trả về một giá trị trong đoạn 0 đến nTable – 1 nếu obj có mặt trong bảng và trả về nTable trong trường hợp ngược lại. Bởi vậy, hàm inTable sẽ trả về true khi j == nTable, tức là khi obj không có mặt trong bảng. Rõ ràng điều này hoàn toàn mâu thuẫn với tên hàm. Những sai làm kiểu này sẽ gây nên rắc rối lớn khi chương trình được bảo trì, phát triển bởi các lập trình viên khác trong tương lai.


    1.2: Biểu thức và lệnh

    Cũng giống như việc đặt tên cho hàm và biến, chúng ta cần viết các biểu thức và câu lệnh càng dễ hiểu càng tốt. Nên nhớ rằng các chương trình do bạn viết ra không chỉ để cho bạn đọc mà còn dành cho nhiều người khác đọc nữa.

    Quy tắc 1: Viết các lệnh “thò ra thụt vào” (indent) để nêu bật cấu trúc của chương trình
    Xem vòng lặp sau đây:

    Mã:
    for(n++;n<100;field[n++]=’\0’);
    *i = ‘\0’; return( ‘\n’);
    Định dạng lại ta có đoạn mã tốt hơn sau đây

    Mã:
    for(n++, n < 100; field[n++] = ‘\0’ )
        ;
    *i = ‘\0’;
    return( ‘\n’);
    Chúng ta còn thu được đoạn mã tốt hơn nữa khi sau khi đưa phép gán vào trong thân vòng lặp và tách lệnh tăng n ra:

    Mã:
    for( n++; n < 100; n++ ) 
      field[ n ] = ‘\0’;
    *i = ‘\0’;
    return ‘n’;
    Quy tắc 2: Viết các biểu thức ở dạng “tự nhiên”

    Hãy viết các biểu thức ở dạng mà chúng ta nói về chúng. Ví dụ đoạn mã sau đây khá khó hiểu:

    Mã:
    if( ! ( block_id < actblks ) || ! ( block_id >= unblocks ) )
    Biến đổi tương đương chúng ta có đoạn mã “tự nhiên” hơn sau đây:

    Mã:
    if( ( block_id >= actblks ) || ( blockId < unblocks ) )
    Quy tắc 3: Sử dụng cặp dấu ngoặc (,) để tránh nhập nhằng về thứ tự thực hiện của các toán tử

    Vì phép toán logic có độ ưu tiên cao hơn phép gán nên cần sử dụng dấu ngoặc cho hầu hết các biểu thức có mặt chúng đồng thời:

    Mã:
    while( ( c == getchar() ) != EOF )
      …
    Các toán tử thao tác bit & và | có mức ưu tiên thấp hơn các toán tử so sánh như == nên khi nhìn thấy biểu thức

    Mã:
    if( x & MASK == BITS )
    thì thực tế thứ tự thực hiện là

    Mã:
    if( x & ( MASK == BITS ) )
    Chắc hẳn đây không phải là chủ định của lập trình viên viết biểu thức này.

    Chúng ta nên sử dụng các dấu ngoặc kể cả khi không bắt buộc. Hãy so sánh hai cách viết sau đây xem cách nào tốt hơn:

    Mã:
    leap_year = y % 4 == 0 && y % 100 != 0 || y % 400 == 0


    Mã:
    leap_year = ( ( y%4 == 0 ) && ( y%100 != 0 ) ) || ( y%400 == 0 )
    Chú ý rằng các dấu cách xung quanh các toán tử % đã được bỏ đi nhằm thể hiển rõ hơn cấu trúc của biểu thức.

    Quy tắc 4: Tách các biểu thức phức tạp thành các biểu thức đơn giản hơn

    Biểu thức sau đây rất ngắn gọn nhưng lại chứa quá nhiều phép toán:

    Mã:
    *x += ( *xp = ( 2*k < ( n – m ) ? c[ k + 1 ] : d[ k -- ] ) );
    Chúng ta nên viết lại như sau:

    Mã:
    if( 2*k < n – m ) 
      *xp = c[ k + 1 ];
    else
      *xp = d[ k-- ];
    *x += *xp;
    Quy tắc 5: Viết các lệnh dễ hiểu, không viết các lệnh “khôn ngoan”

    Các lập trình viên thường thích viết các lệnh càng ngắn gọn càng tốt. Tuy nhiên điều này thường gây phiền toái cho người khác. Hãy xem biểu thức sau đây làm gì:

    Mã:
    subkey = subkey >> ( bitoff – ( ( bitoff >> 3 ) << 3 ) );
    Biểu thức trong cùng ( bitoff >> 3 ) dịch phải bitoff 3 bit. Kết quả thu được lại được dịch trái 3 bit. Bởi vậy 3 bit cuối cùng của bitoff được thay thế bởi các số 0. Kết quả này lại được trừ đi bởi giá trị ban đầu của bitoff, kết quả của phép trừ chính là 3 bit cuối cùng trong giá trị ban đầu của bitoff. Ba bit này được dùng để dịch subkey sang phải.

    Bởi vậy, biểu thức nói trên tương đương với biểu thức sau đây:

    Mã:
    subkeu = subkey >> ( bitoff & 0x7 );
    Rõ ràng cách viết thứ hai dễ hiểu hơn nhiều. Một ví dụ khác về cách viết biểu thức ngắn gọn nhưng làm phức tạp hóa vấn đề:

    Mã:
    child = ( ! LC && ! RC ) ? 0 : ( ! LC ? RC : LC );
    Cách viết dưới đây dài hơn, nhưng dễ hiểu hơn nhiều:

    Mã:
    if( LC == 0 && RC == 0 )
      child = 0;
    else if( LC == 0 )
      child = RC;
    else
      chiđ = LC;
    Toán tử ?: chỉ thích hợp cho những biểu thức ngắn kiểu như sau đây:

    Mã:
    max = ( a > b ) ? a : b;
    hoặc

    Mã:
    printf( “The list has %d item%s\n”, n, n == 1 ? “” : “s” );
    Hãy nhớ rằng mục tiêu của chúng ta là viết những đoạn mã dễ hiểu, chứ không phải các đoạn mã ngắn gọn.

    Quy tắc 6: Cẩn thận với hiệu ứng lề (side effect)

    Toán tử ++ gây ra hiệu ứng lề: Bên cạnh việc trả về giá trị của biến, nó còn tăng giá trị của biến thêm 1 đơn vị. Điều này có thể rất tiện lợi trong nhiều trường hợp, song cũng có thể gây ra rất nhiều phiền toái. Vấn đề nằm ở chỗ việc lấy ra giá trị và việc tăng giá trị của biến có thể không xảy ra cùng lúc. Trong C và C++, thứ tự thực hiện của các hiệu ứng lề là không được định nghĩa. Vì vậy câu lệnh sau đây có thể cho kết quả sai:

    Mã:
    str[ i++ ] = str[ i++ ] = ‘ ‘;
    Chủ định của người viết là thêm hai dấu cách vào hai vị trí tiếp theo của xâu str. Tuy nhiên, tùy thuộc vào thời điểm chỉ số i được cập nhật mà sau khi thực hiện lệnh có một hoặc hai dấu cách được thêm vào xâu str cũng như i được tăng lên một hay hai đơn vị. Tốt nhất nên tách lệnh trên thành hai lệnh:

    Mã:
    str[ i++ ] = ‘ ‘;
    str[ i++ ] = ‘ ‘;
    Tương tự, lệnh sau đây có thể cho nhiều kết quả khác nhau:

    Mã:
    array[ i++ ] = i;
    Nếu giá trị ban đầu của i là 3, phần tử array[ 4 ] có thể nhận giá trị 3 hoặc 4.

    Các thao tác vào/ra dữ liệu cũng thường gây ra hiệu ứng lề. Lệnh sau đây cố gắng đọc hai giá trị số có liên quan từ thiết bị nhập chuẩn:

    Mã:
    scanf( “ %d %d”, &yr, &profit[ yr ] );
    Chủ định của người viết là sử dụng giá trị mới của yr trong profit[ yr ]. Tuy nhiên, câu lệnh này sai ở chỗ: Một phần của lệnh thay đổi giá trị của yr trong khi một phần khác lại sử dụng giá trị đó. Nhớ rằng tất cả các tham số của scanf đều được tính toán trước khi scanf thực sự được gọi. Bởi vậy giá trị của yr trong profit[ yr ] luôn là giá trị cũ. Để sửa lỗi này, như thường lệ, hãy viết lại lệnh trên thành hai lệnh dưới đây:

    Mã:
    scanf( “%d”, &yr );
    scanf( “%d”, &profit[ yr ] );
    Sau đây là một số bài tập cho phần 1.1 và 1.2

    1-Đánh giá cách đặt tên của đoạn mã sau đây:

    Mã:
    #define TRUE    0
    #define FALSE   1
    
    if( ( ch = getchar() ) == EOF )
      not_eof = FALSE;
    2-Cải tiến hàm sau đây

    Mã:
    int smaller( chả *s, char *t ) {
    
      if( strcmp( s, t ) < 1 )
        return 1;
      else
        return 0;
    
    }
    3-Thử đọc to đoạn mã này lên

    Mã:
    if( ( falloc( SMRHSHSCRTCH, S_IFEXT|0644, MAXRCDDHSH ) ) < 0 )
    4-Cải tiến những đoạn mã sau

    Mã:
    if( ! ( c == ‘y’  || c == ‘Y’ ) )
      return;
    Mã:
    length = ( length < BUFSIZE ) ? length : BUFSIZE
    Mã:
    flag = flag ? 0 : 1;
    Mã:
    quote = ( *line == ‘”’ ) ? 1 : 0;
    Mã:
    if( val & 1 )
      bit = 1;
    else
      bit = 0;
    5-Đoạn mã sau sai ở đâu

    Mã:
    int read( int *ip ) {
      scanf( “%d”, ip );
      return *ip;
    }
    …
    insert( &graph[ vert ], read( &val ), read( &ch ) );
    6-Liệt kê tất cả các kết quả có thể có của lệnh sau (hãy thử trên thật nhiều trình dịch)

    Mã:
    n = 1
    
    printf( “%d %d\n”, n++, n++ );

  2. Có 6 thành viên cảm ơn bài viết của Nistelrooy có chất lượng:


  3. #2
    HUT's Student Avatar của langtusaobang
    Tham gia ngày
    Mar 2004
    Bài gửi
    128

    Mặc định

    Lâu lắm rồi mới thấy 1 bài hay thế này, Cám ơn bác Nistelrooy nhiều. Hôm trước đọc cuốn Beautiful Code cũng hay lém. Hy vọng bác tiếp tục có những bài viết hay để em tham khảo cùng nhé.
    Mẹ Maria mang thai mà không có "tội", lạy trời dù tụi con có "tội" nhưng đừng mang thai!

  4. Tớ cảm ơn langtusaobang đã chia sẻ.


  5. #3
    ENOLA Avatar của MiSuk
    Tham gia ngày
    Jun 2010
    Bài gửi
    679

    Mặc định Re: Programming Style

    thanks anh nhé em cũng mới bước vào it em sẽ để ý mấy chỗ các thầy k dạy

  6. #4
    svBK's Newbie
    Tham gia ngày
    Apr 2010
    Bài gửi
    1

    Mặc định Re: Programming Style

    anh ơi, em đang cần quyển The practice of Programming” của Brian W. Kernighan và Rob Pike . Anh có thể gửi cho em qua gmail : haictv.topica@gmail.com được ko?. Kỳ này bọn em học kỹ thuật lập trình, toàn về phần phong cách lập trình với gỡ lỗi,.....

  7. #5
    .:: Grumpy svBKer ::. Avatar của 1973
    Tham gia ngày
    Mar 2010
    Bài gửi
    3.793

    Mặc định Re: Programming Style

    Sao bạn không vào google để tìm?
    Contact me:
    Email: sangnd [at] svBK.vn
    Personal website: My Blog | Chat với người lạ
    Facebook Page của Bách Khoa Forum: http://www.facebook.com/svbk.vn

  8. #6
    svBK's Newbie
    Tham gia ngày
    Oct 2009
    Bài gửi
    6

    Mặc định Re: Programming Style

    Lật mồ lên 1 tí, điều mà bác mong mỏi ngày xưa giờ khoa mình đã và đang làm rồi bác ạ. Đã có môn Kỹ thuật lập trình, tuy thời lượng không nhiều nhưng cũng đã giới thiệu một phần nào các quy tắc lập trình sao cho chương trình đọc dễ hiểu, có hiệu năng cao, ít lỗi.

  9. #7
    Le chevalier du ciel Avatar của luugu
    Tham gia ngày
    Dec 2008
    Bài gửi
    717

    Mặc định Re: Programming Style

    Programming style đúng là thứ mà những bọn hay tiếp xúc với lập trình như tụi em luôn trăn trở, nhìn code phát là biết newbie hay pro

  10. #8
    Điều hành viên Avatar của hunterXhunter_1990
    Tham gia ngày
    Dec 2009
    Bài gửi
    482

    Mặc định Re: Programming Style

    Quote Nguyên văn bởi luugu Xem bài viết
    Programming style đúng là thứ mà những bọn hay tiếp xúc với lập trình như tụi em luôn trăn trở, nhìn code phát là biết newbie hay pro
    Bạn nói vậy chắc biết cách lập trình thế nào cho pro nhỉ. Viết 1 bài guide cho mình học tập đi
    TODAY is a NEW DAY!!!!

  11. #9
    .:: Grumpy svBKer ::. Avatar của 1973
    Tham gia ngày
    Mar 2010
    Bài gửi
    3.793

    Mặc định Re: Programming Style

    Quote Nguyên văn bởi luugu Xem bài viết
    Programming style đúng là thứ mà những bọn hay tiếp xúc với lập trình như tụi em luôn trăn trở, nhìn code phát là biết newbie hay pro
    Thật ra không phải như vậy, nhiều ông giỏi lắm nhưng mà ông ý không để ý đến hình thức khi code. Bản thân em code cũng đẹp lắm nhưng mà vẫn newbie đấy thôi

  12. #10
    Le chevalier du ciel Avatar của luugu
    Tham gia ngày
    Dec 2008
    Bài gửi
    717

    Mặc định Re: Programming Style

    Quote Nguyên văn bởi hunterXhunter_1990 Xem bài viết
    Bạn nói vậy chắc biết cách lập trình thế nào cho pro nhỉ. Viết 1 bài guide cho mình học tập đi
    Hehe, bác em tìm cuốn "The Practice of Programming" của chủ thớt mà đọc. Nhận xét của em có thể coi như là của một thực khách khi vào ăn quán, cần gì phải nấu ăn giỏi mới biết là món ăn ngon phỏng bác? Trong một chừng mực nào đó, thì việc nhận ra một đoạn code nào là tốt là tối ưu (chưa chắc đã đẹp) cũng đòi hỏi một trình độ nhất định, nhưng khi đã pro món lập trình em nghĩ chắc code nó cũng hoàn thiện và cái style nó hiện ra rõ ràng hơn, người khác nhìn vào biết ngay.

    Just my opinion, hehe.

    P/S: Mình lấy luôn một ví dụ nho nhỏ của thầy Phạm Ngọc Nam:

    Eg.1:

    Mã:
    int a, b, c, d;
    ...blah blah
              s1 = a + b + c;
              s2 = a + b + c + d;
    ...blah blah
    Eg.2:

    Mã:
    int a, b, c, d;
    ...blah blah
              s1 = a + b + c;
              s2 = s1 + d;
    ...blah blah
    Đây chỉ là 1 ví dụ rất rất nhỏ về việc tối ưu code, nếu nói về phần cứng thì ở ví dụ 1 ta phải nhét tham số vào ALU và bắt nó tính nhiều lần trong khi ở ví dụ 2, kết quả của s1 có thể lưu vào stack và sử dụng lại để tính s2. Các bạn thấy sao về đoạn code này? Chỉ những chi tiết rất nhỏ nhỏ như vậy sẽ khiến 1 chương trình chạy nhanh hơn.

    Về code thế nào cho đẹp, cái này thẩm mỹ mỗi người mỗi khác, tuy nhiên cũng có sự thống nhất chung trong việc viết code, như là lùi dòng chẳng hạn:

    Eg.3: Một đoạn code VHDL nho nhỏ mình viết, chắc chắn là chưa pro nhưng mình tạm coi là dễ nhìn:

    Mã:
    --Declaration of the Full-Adder (FA)
    
    Library IEEE;
    Use IEEE.std_logic_1164.all;
    Entity FA is
    	Port(
    		a, b, ci: in std_logic;
    		co, s: out std_logic
    		);
    End FA;
    
    Architecture Behave of FA is
    Begin
    	co <= ci xor (a xor b);
    	s  <= (not (a xor b) and b) or ((a xor b) and ci);
    
    End Behave;
    
    --------------------------------------------------------
    
    Library IEEE;
    Use IEEE.std_logic_1164.all;
    Entity part3 is
    	Port(
    		SW: in std_logic_vector (8 downto 0);  --A: SW(7 downto 4), B: SW(3 downto 0), Carry Bit Co: SW(8);
    		LEDR: out std_logic_vector (8 downto 0);
    		LEDG: out std_logic_vector (4 downto 0)
    		);
    End part3;
    
    Architecture Behave of part3 is
    
    Component FA is
    	Port(
    		a, b, ci: in std_logic;
    		co, s: out std_logic
    		);
    End Component;
    
    Signal C: std_logic_vector (2 downto 0);		--The Carry Bit Signal C<= C0;
    
    Begin
    	FullAdder1: FA port map (SW(0), SW(4), '0', C(0), LEDG(0));
    	FullAdder2: FA port map (SW(1), SW(5), C(0), C(1), LEDG(1));
    	FullAdder3: FA port map (SW(2), SW(6), C(1), C(2), LEDG(2));
    	FullAdder4: FA port map (SW(3), SW(7), C(2), LEDG(4), LEDG(3));
    	
    	LEDR <= SW;
    
    End Behave;
    Lần sửa cuối bởi luugu; 25-05-2011 lúc 06:38 PM

  13. Tớ cảm ơn luugu đã chia sẻ.


+ Trả lời chủ đề
Trang 1/3 123 CuốiCuối

Thông tin chủ đề

Users Browsing this Thread

Hiện có 1 người đọc bài này. (0 thành viên và 1 khách)

Từ khóa (Tag) của chủ đề này

Quyền viết bài

  • Bạn không thể gửi chủ đề mới
  • Bạn không thể gửi trả lời
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình


About svBK.VN

    Bách Khoa Forum - Diễn đàn thảo luận chung của sinh viên ĐH Bách Khoa Hà Nội. Nơi giao lưu giữa sinh viên - cựu sinh viên - giảng viên của trường.

Follow us on

Twitter Facebook youtube