Moriator - I can do it!

Linux dễ dàng hơn bạn nghĩ!

Archive for November, 2007

Sử dụng StarDict trên Ubuntu 7.10

Posted by moriator on 24th November 2007

Bộ từ điển StarDict có thể nói là quá nổi tiếng trong thế giới nguồn mở và hầu như ai cũng phải cài đặt nó cả. Tuy nhiên, StarDict lại bị lỗi trên Ubuntu 7.10. Nếu bạn cài từ Add/Remove… , khi sử dụng chức năng scan bạn không thể đưa chuột vào trong cửa sổ được (nó nhảy lên góc trên trái và… biến mất). Nguyên nhân là phiên bản StarDict này đã cũ, và cách khắc phục đơn giản nhất là tải phiên bản mới về tại đây. :D

Cài đặt xong, bạn lên trang http://stardict.sourceforge.net/Dictionaries_misc.php để tải các bộ từ điển về (tình hình là có rất nhiều, đi lòng vòng tải về một đống :D ). Bạn giải nén và đưa vào /usr/share/stardict/dic

Còn đây là gói âm thanh để StarDict “biết nói”: tải về giải nén rồi đưa vào /usr/share/stardict/sounds

Một số thủ thuật:

- Chức năng scan của Stardict rất tiện dụng, nhưng đôi khi lại gây phiền phức. Cứ mỗi lần bạn bôi đen một đoạn văn bản là StarDict lại “nhảy ra, nhảy vào” làm hoa cả mắt. Cách khắc phục là bạn vào Preferences, Categories -> Scan Selection, chọn cả 2 ô rồi vào Scan modifier key chọn phím tắt phù hợp. Thế là từ nay StarDict chỉ nhảy ra khi nào bạn nhấn kèm phím tắt thôi.

- StarDict có thể dịch 1 đoạn văn bản từ ngôn ngữ này ra ngôn ngữ khác (tiếc là chưa có tiếng việt). Bạn vào Full-text Translation chọn bộ dịch (Google, Yahoo…) rồi sử dụng.

- Một trò nữa khá vui là bạn có thể tra cứu wikipedia bằng… StarDict. Bạn vào Manage Dictionaries -> Network Dictionaries -> Add -> Wikipedia -> viwiki (tiếng Việt). Sau đó bạn vào Preferences -> Net Dict -> Enable Network Dictionaries. Thế là xong!

Có nhiều điều hấp dẫn trong StarDict, bạn vọc thử rồi cho tôi biết kết quả nhé :)

Posted in Linux, Linux Tutorial, Ubuntu | 8 Comments »

Tăng tốc download cho Firefox

Posted by moriator on 21st November 2007

Đối với những người dùng Internet thì việc tăng tốc download là vô cùng quan trọng. Trong Linux cũng có một số phần mềm hỗ trợ download, nhưng vẫn chưa có một phần mềm nào đủ sức so kè với Internet Download Manager trong Windows (cũng có thể tôi chưa tìm ra).

- MultiGet Download Manager: tương tự như FlashGet bên Windows, nhưng không tự động bắt link, khá bất tiện.

- wxDownload Fast: tương tự như IDM, nếu kết hợp chung với Extension FlashGot của Firefox thì có khả năng bắt link tự động. Nhưng không hiểu sao khi cài trên Ubuntu, chạy được 1 lúc thì nó tự nhiên biến mất :(

Nhưng ta không cần phải mất công đến thế :D Firefox có một Extension hỗ trợ download khá tốt là DownThemAll! Khi muốn download, bạn chỉ cần click phải lên link và sẽ thấy 2 lựa chọn DownThemAll!…dTa OneClick!…

Bạn chọn DownThemAll! hay dTaOneClick! đều được cả. Khi download thì nó có cửa sổ thế này:

Bạn có thể chia nhỏ file tối đa thành 10 phần để download. Chương trình chạy rất tốt và khá nhanh, đủ khả năng đáp ứng nhu cần download của các bạn :D

Ai biết chương trình gì hay hơn hoặc có ý kiến xin để lại comment.

Chúc vui!

Posted in Thủ thuật máy tính | 4 Comments »

Cắt và ghép file

Posted by moriator on 15th November 2007

Hôm trước một người bạn hỏi tôi trong Linux phải dùng phần mềm nào để cắt 1 file thành nhiều file nhỏ hơn, tiện cho việc di chuyển. Thật ra, với sức mạnh của Linux thì chẳng cần phải dùng phần mềm nào cả. Chúng ta sử dụng lệnh splitcat để làm việc này.

Ví dụ, tôi có 1 file Spiderman.avi dung lượng 1.2GB. Tôi muốn chia ra thành 2 file để nhét vừa vào 2 ổ CD (vì không có đầu ghi DVD).

$ split -b 650m Spiderman.avi Spiderman

  • Tham số -b là dung lượng của mỗi file sau khi cắt, tính theo byte. Bạn có thêm thêm vào k (kilo) hoặc m (mega) ở cuối con số (như ví dụ trên, tôi muốn mỗi file là 650MB). Nếu không có tham số -b thì mặc định sẽ là 1MB.
  • Tiếp theo là file input cần cắt nhỏ.
  • Cuối cùng là tiền tố của tên file sau khi cắt. Các file sau khi cắt sẽ có tiền tố này và cộng thêm 2 chữ vào để chúng không trùng nhau “aa”, “ab”, “ac”,…

Như ví dụ trên, sau khi thực hiện xong tôi sẽ có 2 file là Spidermanaa và Spidermanab

Để ghép 2 file lại, bạn chép 2 file này vào cùng thư mục, gõ lệnh:

$ cat Spiderman* > Spiderman.avi

Thế là xong! Nhanh chóng và đơn giản vô cùng:D

Để hiểu thêm về lệnh split và cat, hãy dùng lệnh man trong Terminal:)

Posted in Linux, Linux Tutorial | 3 Comments »

Cài đặt phần mềm và quản lý các gói trong Ubuntu

Posted by moriator on 13th November 2007

I. CÀI ĐẶT PHẦN MỀM:

Đối với những người dùng Windows sau khi chuyển sang Linux thì việc cài đặt, gỡ bỏ và nâng cấp 1 phần mềm sẽ vô cùng căng thẳng. Trong Windows chúng ta chỉ có 1 cách rất thông thường là click vào file setup.exe hay install.exe, chờ 1 xí và xài:D. Còn trong Linux, chúng ta có khá nhiều cách để làm chuyện đó. Trong bài này tôi sẽ giới thiệu 1 vài cách thông dụng khi cài phần mềm trong Ubuntu.

1. Cài đặt từ Add/Remove: Đây là cách đơn giản và hiệu quả nhất. Cài bằng cách này sẽ dễ dàng gỡ bỏ và nâng cấp hơn. Tuy nhiên, cách này chỉ thực hiện được khi máy có kết nối internet mà thôi. Bạn chỉ cần vào Applications -> Add/Remove…, tìm phần mềm muốn cài, chọn và Apply, ngồi đợi Ubuntu tải các gói về cài đặt. Thế là xong!

Chú ý, ở ListBox Show (phía trên bên phải), bạn chọn “All available applications” để thấy tất cả phần mềm có thể sử dụng

.2. Cài đặt từ gói .deb:

Cách này cũng đơn giản không kém gì cách thứ nhất, do gói .deb đã được biên dịch sẵn nên bạn chẳng cần phải làm gì nhiều. Bạn chỉ việc dùng chuột kích hoạt gói và chương trình sẽ tự động cài đặt (giống như file setup.exe bên Windows). Khi cài, đôi khi xuất hiện yêu cầu các gói phụ thuộc (dependencies). Bạn tìm các gói đó về cài vào là OK.

Nếu thích dùng lệnh, bạn gõ trong Terminal:

$ sudo dpkg -i [ten_goi].deb

Khi cài 1 loạt các gói .deb:

$ sudo dpkg -i *.deb

3. Cài đặt từ gói .rpm:

Đây là gói biên dịch cho Redhat. Muốn chuyển sang gói .deb cho Ubuntu, bạn có thể cài phần mềm alien:

$ sudo apt-get update
$ sudo apt-get install alien

Chuyển vào thư mục chứa file .rpm

$ sudo alien -k [ten_file].rpm

- Lệnh này sẽ chuyển gói .rpm thành gói .deb
- Tham số -k sẽ giữ nguyên số phiên bản

Sau đó bạn cài gói .deb như cách 2.

3. Sử dụng trình quản lý gói Synaptic (trong Kubuntu là Kynaptic)

Bạn vào System > Administration > Synaptic Package Manager, tìm gói cần cài rồi Install/Reinstal/Remove… Cái này cũng đơn giản không kém, bạn tự vọc nhé :D

4. Cài đặt bằng dòng lệnh (trình bày chi tiết ở phần sau) Muốn cài gói nào, bạn chỉ việc gõ vào Terminal:

sudo apt-get install [ten_goi]

Gỡ bỏ:

sudo apt-get remove [ten_goi]

5. Biên dịch từ mã nguồn:

Nếu bạn chỉ có mã nguồn trong tay, hãy thực hiện những bước sau:

- Cài chương trình biên dịch:

$ sudo apt-get install build-essential

- Lấy mã nguồn về (có thể dùng lệnh wget để tải)

- Giải nén: tar xvzf [ten_file] (.tar.bz2, .tar.bz, tar.gz,…)

- Biên dịch và cài: vào trong thư mục vừa giải nén

$ ./configure

$ make

$ sudo make install

Đôi khi việc cài đặt không thực hiện được do thiếu các thư viện phụ thuộc. Bạn có thể thấy chúng khi báo lỗi

II. Quản lý các gói trong Ubuntu:

dpkg: đây là trình quản lý gói cơ bản và đơn giản nhất trong Debian. Bạn có thể tham khảo ở bảng sau:

Cú pháp Mô tả Ví dụ
dpkg -i {.deb package} Cài đặt gói hoặc nâng cấp nếu đã cài rồi dpkg -i zip_2.31-3_i386.deb
dpkg -R {Directory-name} Cài đặt toàn bộ các gói trong thư mục dpkg -R /tmp/downloads
dpkg -r {package} Gỡ bỏ gói trừ các file cấu hình dpkg -r zip
dpkg -P {package} Gỡ bỏ gói kể các các file cấu hình dpkg -P apache-perl
dpkg -l Liệt kê các gói đã cài đặt, phiên bản và mô tả ngắn dpkg -l dokg -l | less
dpkg -l ‘*apache*’
dpkg -l | grep -i ’sudo’
dpkg -l {package} Liệt kê các gói riêng đã cài đặt, phiên bản và mô tả ngắn dpkg -l apache-perl
dpkg -L {package} Liệt kê các file đã cài đặt dpkg -L apache-perl
dpkg -L perl
dpkg -c {.Deb package} Liệt kê những file bên trong gói .deb dpkg -c dc_1.06-19_i386.deb
dpkg -S {/path/to/file} Tìm gói mà file phụ thuộc dpkg -S /bin/netstat
dpkg -S /sbin/ippool
dpkg -p {package} Mô tả chi tiết gói: nhóm, phiên bản, bảo trì, cấu trúc, các
gói phụ thuộc, mô tả,…
dpkg -p lsof
dpkg -s {package} | grep Status Tìm xem gói đã được cài hay chưa dpkg -s lsof | grep Status

Nguồn: http://www.cyberciti.biz/howto/question/linux/dpkg-cheat-sheet.php

apt:

Cú pháp Mô tả Ví dụ
apt-get install {package} Cài đặt hoặc nâng cấp gói apt-get install zip
apt-get install lsof samba mysql-client
apt-get remove {package} Gỡ bỏ gói trừ các file cấu hình apt-get remove zip
apt-get –purge remove {package} Gỡ bỏ gói kể cả các file cấu hình apt-get –purge remove mysql-server
apt-get update apt-get upgrade Cập nhật hệ thống apt-get update
apt-get upgrade
apt-get update apt-get dist-upgrade Nâng cấp hệ thống lên phiên bản mới apt-get update
apt-get dist-upgrade
apt-cache search keywords Tìm gói theo từ khóa apt-cache search alien
apt-cache show program Lấy thông tin về gói apt-cache show rar

Nguồn: http://www.cyberciti.biz/howto/question/linux/apt-get-cheat-sheet.php

Posted in Linux, Ubuntu | 3 Comments »

Ubuntu Satanic Edition: Quà tặng của quỷ Satan!

Posted by moriator on 9th November 2007

Sự phát triển của Ubuntu quả là ngoài sức tưởng tượng, thậm chí cả… quỷ Satan cũng xài :D Nói đùa thế thôi, đây chỉ là 1 chiếc áo mang phong cách Haloween cho anh bạn Ubuntu nhà ta (tiếc là Haloween đã qua rồi :() Chiếc áo có thể mặc cho Ubuntu Gutsy 7.10, Feisty 7.04 và Edgy 6.10, bao gồm cả Gnome (Ubuntu) và KDE (Kubuntu). Thậm chí, nó có thể cài vào… Ubuntu Christian Edition! (Quỷ có khác :D)

Read the rest of this entry »

Posted in Linux, Ubuntu | 8 Comments »

Cách tổ chức file C và C++ (phần 3)

Posted by moriator on 8th November 2007

Khắc phục trường hợp thứ nhất:

May mắn thay, trường hợp này khá đơn giản, và dễ tránh nếu bạn hiểu nó.

Lỗi thứ nhất, khi file nguồn không biên dịch bởi vì một trong số những định nghĩa chưa được khai báo, dễ dàng để sửa. Đơn giản là #include file chứa định nghĩa cần thiết. Nếu file header của bạn được tổ chức hợp lý và đặt tên tốt, điều này sẽ rất dễ dàng. Nếu bạn cần sử dụng cấu trúc Sprite, thì bạn chi cần thêm vào #include “Sprite.h” vào bất cứ file nào có nó. 1 lỗi mà nhiều lập trình viên thường mắc phải là cho rằng 1 file đã được #include đơn giản vì nó đã được #include trong 1 file khác.

Example:
/* Header1.h */
#include “header2.h”
class ClassOne { … };

.

/* Header2.h */
class ClassTwo { … };

.

/* File1.cpp */
#include “Header1.h”
ClassOne myClassOne_instance;
ClassTwo myClassTwo_instance;

Trong trường hợp này, File1.cpp sẽ biên dịch tốt, vì đã include Header1.h và include gián tiếp Header2.h, có nghĩa là File1.cpp có thể truy xuất đến lớp Class2. Nhưng chuyện gì sẽ xảy ra nếu một thời gian sau, ai đó cho rằng Header1.h không cần thiết phải #include Header2.h? Họ có thể xoá dòng #include đó, và đột nhiên File1.cpp sẽ không thể biên dịch được.

Chìa khóa ở đây là, cần phải dứt khoát khi #include bất kì header nào bạn cần cho file nguồn để biên dịch. Bạn không nên dựa vào những file header include gián tiếp các header bổ sung, mà có thể sẽ thay đổi. Những #include bổ sung cũng xử lý như tài liệu, mà các mã trong file phải phụ thuộc vào. Do đó đừng xoá chúng nếu bạn biết bạn cần header đó cần phải include đâu đó.

Khắc phục trường hợp thứ 2:

Sự phụ trường vòng tròn là vấn đề thường gặp trong kĩ thuật phần mềm. Nhiều cấu trúc liên kết lẫn nhau, và tất cả đều phải biết lẫn nhau. Thông thường nó có dạng như thế này:

/* Parent.h */
#include “child.h”
class Parent
{
Child* theChild;
};

.

/* Child.h */
#include “parent.h”
class Child
{
Parent* theParent;
};

Trường hợp này thật sự đơn giản. Cấu trúc Parent thật ra không cần phải biết chi tiết lớp Child, khi nó chỉ chứa 1 con trỏ của lớp Child. Con trỏ không cần biết nó chỉ đến đâu, do đó bạn không cần phải định nghĩa cấn trúc hoặc lớp để chứa con trỏ. Do đó dòng #include ở đây là không cần thiết. Tuy nhiên, lỗi “undeclared identifier” sẽ xuất hiện khi nó gặp từ ‘Child’, nên bạn cần cho trình biên dịch biết rằng Child là 1 lớp mà bạn cần chỉ đến. Sử dụng khai báo trước, đưa ra dạng hoặc định nghĩa lớp mà không có chi tiết bên trong. Ví dụ:

/* Parent.h */
class Child; /* Forward declaration of Child; */
class Parent
{
Child* theChild;
};

Chú ý rằng dòng #include được thay thế bằng một khai báo trước. Điều này cho phép thoát khỏi sự phụ thuộc vòng tròn giữa Parent.h và Child.h. Hơn nữa, tốc độ biên dịch sẽ tăng lên khi bạn có ít file include hơn. Trong trường hợp này, file Child.h cũng phải khai báo trước “class Parent;” Chỉ khi bạn chỉ tham chiếu đến con trỏ mà không phải dạng thật sự, bạn không cần phải #include toàn bộ định nghĩa. Trong 99% trường hợp, điều này có thể áp dụng cho cả 2 phía của vòng tròn và không cần #include 1 header trong file header kia, để loại trừ sự phụ thuộc vòng tròn.

Dĩ nhiên, trong những file parent.c và child.c, bạn cần phải #include cả parent.h và child.h.

Một trường hợp khác làm xuất hiện sự phụ thuộc vòng tròn là những hàm inline định nghĩa bên trong header (để tăng tốc độ). Để cho hàm có thể thực thi, nó cần phải biết chi tiết của lớp. Do đó, file header có chứa hàm inline cần phải #include khi những hàm đó cần được biên dịch. Lời khuyên đầu tiên là bạn chỉ nên tạo 1 hàm inline khi nó thật sự cần thiết. Khi bạn kiểm tra và chắc chắn những hàm cần phải ở dạng inline (và dĩ nhiên là trong file header), cố gắng và đảm bảo rằng trong 2 file header phụ thuộc lẫn nhau chỉ có 1 file là được chứa những hàm inline.

Chú ý rằng bạn việc loại trừ sự phụ thuộc không phải lúc nào cũng thực hiện được. Nhiều cấu trúc và lớp bao gồm nhiều cấu trúc và lớp khác, mà sự phụ thuộc là không thể tránh khỏi. Tuy nhiên, chỉ khi sự phụ thuộc là 1 chiều, nó sẽ được sửa chữa khi biên dịch, và sẽ không có vấn đề gì xảy ra.

Có nhiều phương pháp phức tạp hơn để xử lý sự phụ thuộc vòng tròn, nhưng nó không liên quan đến mục đích của bài viết. Trong 99% trường hợp, sử dụng định nghĩa trước và các hàm thông thường trong file .C/.CPP cũng như không có hàm inline trong file header là đủ.
(còn tiếp)

Nguồn: http://www.gamedev.net/reference/programming/features/orgfiles/page3.asp

Posted in C/C++, Lập trình | No Comments »

Cách tổ chức file C và C++ (phần 2)

Posted by moriator on 7th November 2007

Những bước cơ bản

Bây giờ bạn đã tin chắc rằng có những ưu điểm khi phân chia đề án của bạn thành nhiều file nhỏ hơn. Do đó, làm cách nào để thực hiện điều này? Mặc dù bạn có thể thực hiện bằng nhiều cách tùy ý, nhưng có một vài quy tắc cơ bản mà bạn nên tuân theo để chắc rằng nó hoạt động.

Đầu tiên, nhìn vào cách bạn phân chia các đoạn mã thành nhiều phần. Thông thường nó được phân chia vào trong các hệ thống con riêng biệt, hoặc các ‘module’, như là âm thanh nhạc, đồ hoạ, file điều khiển… Tạo những file mới với những tên có nghĩa sẽ giúp bạn biết loại mã bên trong khi nhìn lướt qua. Sau đó di chuyển toàn bộ mã bên trong theo các module bên trong file đó. Đôi khi bạn không có những module rõ ràng - vài người cho rằng nên có những cảnh báo về chất lượng thiết kế của bạn! Bạn cần có những tiêu chuẩn khác khi phân chia mã nguồn, như là cấu trúc nó theo tác dụng ở trên (thông thường những hàm “mục đích chung” có thể nằm trong chuỗi-điều khiển hoặc số-điều khiển). Và thỉnh thoảng 1 module có thể chia ra thành 2 hay nhiều file, với những lý do hợp lý.

Khi bạn phân chia nó thành nhiều file theo cách này, vấn đề tiếp theo cần được xem xét là những gì sẽ đến trong file header. Rất cơ bản, những mã mà bạn đặt vào đầu file nguồn như như thành phần không thể thiếu sẽ được chuyển vào các file header. Đó có thể là lý do tại sao chúng có tên gọi là file ‘header’.

Những dạng thường nằm trong file header:

  • Định nghĩa lớp hoặc cấu trúc
  • typedef
  • tên hàm
  • biến toàn cục (xem thêm bên dưới)
  • hằng số
  • #define macros
  • #pragma directives

(Hơn nữa, khi sử sụng C++, biểu mẫu <template> và các hàm bên trong thường nằm trong file header. Lý do sẽ được trình bày rõ ở phần sau).

Ví dụ, hãy nhìn vào những thư viện C chuẩn của bất kì trình biên dịch C hoặc C++. Stdlib.h là 1 ví dụ tốt; hãy mở nó ra bằng trình soạn thảo và xem nó. (Hoặc để tiết kiệm thời gian trong LS Visual C++ 6, gõ nó vào trong file nguồn, click chuột phải lên vàc chọn “Open Document “stdlib.h”‘). Bạn sẽ chú ý rằng chúng chỉ có vài hoặc toàn bộ những thành phần như trên, nhưng không có bất kì mã thực nào. Tương tự, bạn có thể thấy rằng bất kì định nghĩa biến toàn cục nào cũng có từ ‘extern’ phía trước. Điều này là quan trọng, ta sẽ biết nhiều hơn ở phần sau.

Nhìn chung bạn cần có 1 file header cho tất cả file nguồn. Có nghĩa là, một file SPRITES.CPP chắc chắn cần file SPRITES.H, file SOUND.CPP cần SOUND.H,… Giữ những cái tên phù hợp để bạn biết ngay những file header nào sẽ đi với file thông thường nào.

Những file header này trở thành phần chung giữa những hệ thống con. Bằng cách #include một header, bạn có thể truy xuất và toàn bộ những định nghĩa cấu trúc, tên hàm, hàng số… cho hệ thống con. Do đó, mỗi file nguồn sử dụng sprites cần phải #include “sprite.h”, mỗi file nguồn sử dụng âm thanh cần phải #include “sound.h”,… Chú ý rằng bạn nên dùng ngoặc kép hơn à dấu <> khi #include những file riêng. Dấu ngoặc kép cho trình biên dịch biết phải tìm kiếm header của bạn trong thư mục chương trình trước, rồi mới đến các header chuẩn của trình biên dịch.

Nên nhớ rằng, đối với trình biên dịch, hoàn toàn không có sự khác nhau giữa file header và file nguồn. (Ngoại trừ một vài trình biên dịch không biên dịch file header trực tiếp). Đơn giản hơn, chúng chỉ là những file văn bản đơn thuần chứa đầy dòng lệnh. Sự phân biệt chỉ là một quan niệm rằng lập trình viên phải dựa vào đó để giữ cấu trúc file hợp lý và đầy đủ. Ý tưởng chính là những header chỉ chứa những cái chung, và file nguồn chứ những thực thi thật sự. Bạn có thể áp dụng chúng ở bất cứ đâu khi làm việc với C hoặc C++, trong lập trình hướng đối tượng hay lập trình cấu trúc. Điều này có nghĩa là 1 file nguồn dùng 1 file nguồn khác thông qua header của file nguồn thứ hai.

Những cạm bẫy tìm ẩn

Trong những trường hợp đơn giản, bạn có thể tạo ra những chương trình làm việc hoàn chỉnh theo những hướng dẫn đó. Tuy nhiên có một vài chi tiết cần để ý, và nó thường là những chi tiết khiến những lập trình viên mới vào nghề khổ sở khi họ lần đầu tiên phân chia mã ra thành file header và file thông thường.

Theo kinh nghiệm của tôi, có 4 lỗi cơ bản mà người ta thường gặp phải:

  1. Những file nguồn không biên dịch nữa khi chúng không tìm thấy hàm hoặc biến cần thiết (Thường xuất hiện dòng lỗi tương tự như: “error C2065: ‘MyStruct’ : undeclared identifier” trong Visual C++)
  1. Phụ thuộc vòng tròn, khi những header xuất hiện khi cần #include lẫn nhau để làm việc một cách có dụng ý. Một Sprite chứa 1 con trỏ đến Creature, và 1 Creature có thể chứa 1 con trỏ đến Sprite. Bất kể bạn làm như thế nào, cả Creature lẫn Sprite đều phải khai báo trước tiên, và hệ quả là nó không làm việc khi dạng khác chưa được khai báo.
  1. Định nghĩa chồng khi 1 lớp hoặc cấu trúc được gọi 2 lần trong 1 file nguồn. Đây là lỗi thời gian biên dịch và thường xuất hiện khi gọi nhiều file header trong 1 file header khác, làm cho header được gọi 2 lần khi bạn biên dịch file nguồn (trong MSVC, lỗi này có dạng như “error CS2011: ‘MyStruct’ : ’struct’ type redefinition).
  1. Trường hợp lặp lại các đối tượng đã được biên dịch tốt. Đây là lỗi liên kết, thường rất khó hiểu. (Trong MSVC, bạn có thể thấy cái gì đó như “”error LNK2005: “int myGlobal” (?myGlobal@@3HA) already defined in myotherfile.obj”).

Làm sao để sửa những trường hợp này?
(còn tiếp)

Nguồn: http://www.gamedev.net/reference/programming/features/orgfiles/page2.asp

Posted in C/C++, Lập trình | No Comments »

Cách tổ chức file C và C++ (phần 1)

Posted by moriator on 6th November 2007

Giới thiệu:

Trong khi nhiều chương trình đơn giản chỉ gói gọn trong 1 file C hoặc CPP duy nhất, thì nhiều đề án lớn cần phải chia nhỏ thành nhiều file nguồn để tiện quản lý. Tuy nhiên, nhiều lập trình viên mới không nhận thấy tầm quan trọng của điều này - ngay cả khi họ cố gắng và chạy chương trình với quá nhiều vấn đề bên trong mà họ cho rằng nó không đáng để nỗ lực. Bài viết này sẽ giải thích tại sao ta cần phải làm như vậy, và làm sao để thực hiện đúng. Khi cần thiết, tôi sẽ đưa ra các giải thích cách làm việc của trình biên dịch và các mối liên kết để bạn hiểu rõ tại sao chúng ta phải làm theo cách đó.

Thuật ngữ:

Trong bài này, tôi sẽ gọi những file C và C++ tiêu chuẩn (thường có tên mở rộng C và CPP) là “file nguồn”. Điều này sẽ phân biệt chúng với những “file header” (thường có tên mở rộng là .H hay .HPP). Những thuật ngữ này cũng được sử dụng trong Visual C++ và hầu hết các sách. Chú ý rằng sự khác biệt hoàn toàn thuộc về quan niệm - chúng chỉ là những file văn bản với mã bên trong. Tuy nhiên, như những vấn đề sẽ được trình bày, sự khác biệt trong việc xử lý file nguồn và file header là rất quan trọng.

Tại sao phải chia nhỏ mã nguồn thành nhiều file?

Câu hỏi đầu tiên mà nhiều lập trình viên mới vào nghề thắc mắc khi họ nhìn thấy 1 thư mục chứa đầy những tập tin là “tại sao không nhét tất cả vào 1 file duy nhất?”. Đối với họ, họ không thấy được tầm quan trọng của việc phân tán mã nguồn.

Việc phân chia đề án đạt được một số thuận lợi, và những điều quan trọng nhất là:

  • Tăng tốc độ biên dịch: hầu hết các trình biên dịch làm việc trên 1 file trong 1 lúc. Do đó nếu bạn có 10000 dòng lệnh trong 1 file, vá bạn thay đổi 1 dòng, bạn phải biên dịch lại 10000 dòng lệnh. Mặt khác, nếu 10000 dòng lệnh của bạn được chia ra thành 10 file, thì sự thanh đổi 1 dòng chỉ yêu cầu 1000 dòng lệnh được biên dịch lại. 9000 dòng lệnh trong 9 file còn lại không cần phải biên dịch lại (Thời gian liên kết không bị ảnh hưởng).
  • Tăng cường sự tổ chức: phân chia code của bạn một cách hợp lý sẽ làm bạn (và bất kì lập trình viên khác trong đề án) dễ dàng hơn để tìm kiếm những hàm, biến, định nghĩa các cấu trúc/lớp, v.v… Thấy chí với khả năng nhảy trực tiếp để đưa ra những định nghĩa được cung cấp trong nhiều môi trường soạn thảo và lập trình (như Microsoft Visual C++), điều này vẫn có ích khi bạn cần xem 1 đoạn mã để tìm kiếm cái gì đó. Không những phân chia mã sẽ làm giảm số lượng mã cần phải biên dịch lại, mà còn giảm số lượng mã bạn cần phải đọc để tìm ra những gì bạn cần. Tưởng tượng rằng bạn cần tìm và sửa 1 lỗi mã âm thanh mà bạn đã làm nhiều tuần trước đây. Nếu bạn có 1 file lớn là GAME.C, thì cần phải tìm kiếm rất nhiều. Nếu bạn có vài file nhỏ GRAPHICS.C, MAINLOOP.C, SOUND.C, và INPUT.C, bạn biết nơi bạn cần tìm, giảm 3/4 số thời gian làm việc.
  • Giảm bớt sự viết lại: Nếu mã của bạn được phân chia cẩn thận thành những đoạn độc lập với nhau, bạn có thể sử dụng chúng trong đề án khác, tiết kiệm thời gian phải viết lại lần sau. Có nhiều thuận lợi khi viết mã có thể dùng lại được hơn là chỉ dùng 1 cách tổ chức file chặt chẽ, nhưng nếu không có sự tổ chức, thì sẽ rất khó khăn để biết được những đoạn mã nào liên quan đến nhau hay không. Do đó, đặt những thành phần chính và các lớp vào 1 file duy nhất hoặc mô tả cẩn thận tập hợp các file sẽ giúp bạn về sau nếu bạn sử dụng lại những mã đó trong đề án khác.
  • Chia sẽ mã giữa các đề án: nguyên tắc này giống như việc giảm bớt sự viết lại. Chia nhỏ 1 cách cẩn thận trong những file chính xác, bạn tạo khả năng cho nhiều đề án cùng sử dụng chung 1 file mà nguồn mà không cần nhân chúng lên. Lợi ích của việc chia sẽ file giữa các đề án so với sử dụng cắt-và-dán là bất cứ lỗi nào được sửa trong 1 hay nhiều file trong 1 đề án sẽ có tác dụng với những đề án khác, và tất cả đề án có thể chắc chắn được cập nhật bản mới nhất.
  • Phân chia trách nhiệm giữa các lập trình viên: trong những đề án lớn thật sự, đây có lẽ là lý do chính để phân chia mã trong nhiều file. Sẽ không thực tế khi nhiều hơn 1 lập trình viên cùng thay đổi 1 file duy nhất bất cứ lúc nào anh ta muốn. Do đó, bạn sẽ phải dùng nhiều file để mỗi lập trình viên có thể làm việc trên từng phần riêng biệt mà không ảnh hưởng đến file mà lập trình viên khác đang chỉnh sửa. Dĩ nhiên, vẫn cần có những sự kiểm tra để 2 lập trình viên không thay đổi trên cùng 1 file; hệ thống quản lý cấu hình và hệ thống điều khiển phiên bản như là CVS hoặc MS SourceSafe sẽ giúp bạn làm điều này.

Tất cả những gì ở trên cho ta thấy hình dáng của modularity, một thành phần quan trọng của cả lập tình cấu trúc và hướng đối tượng.
(còn tiếp)

Nguồn: http://www.gamedev.net/reference/programming/features/orgfiles/default.asp

————
Cảm ơn thầy Đ.B.Tiến đã cung cấp 1 tài liệu hữu ích :-)

Posted in C/C++, Lập trình | No Comments »

Cài đặt bộ gõ xvnkb cho Ubuntu

Posted by moriator on 4th November 2007

Chú ý: xem bài viết Bộ gõ xvnkb 0.3.0 đã fix các lỗi nếu bạn muốn cài xvnkb vào máy.

———————————–

Việc đầu tiên mà người Việt Nam khi sử dụng máy tính là cài đặt 1 bộ gõ Tiếng Việt. Trong Ubuntu có sẵn bộ gõ SCIM, nhưng chỉ hỗ trợ kiểu gõ VIQR, vô cùng bất tiện với những người quen tay với VNI hay TELEX. Theo đánh giá, xvnkb là phần mềm gõ tiếng việt tốt nhất trên Ubuntu hiện nay, dù nó vẫn còn nhiều lỗi :D

Chúng ta bắt đầu cài nhé! Biên dịch từ mã nguồn cho nó pro :)

Bạn vào Applications -> Accessories -> Terminal:

1. Cài đặt trình biên dịch:

$ sudo apt-get install build-essential

$ sudo apt-get install xorg-dev

2. Tải mã nguồn:

$ wget http://xvnkb.sourceforge.net/xvnkb-0.2.9a.tar.bz2

Giải nén:

$ tar -xvf xvnkb-0.2.9a.tar.bz2

Chuyển vào thư mục vừa giải nén và bắt đầu biên dịch:

$ cd xvnkb-0.2.9a/
$ ./autogen.sh
$ ./configure –use-extstroke

Đến đây, bạn phải sửa lại đôi chút trong file config.h. Gõ gedit config.h và bỏ -e ở đầu

3. Cài đặt:

$ make
$ sudo make install

Đôi khi câu lệnh make báo lỗi, là do quá trình tải 2 gói biên dịch ban đầu bị lỗi. Bạn gõ lại 2 lệnh đầu tiên rồi thực hiện tiếp.

Chạy chương trình: gõ xvnkb

Chạy mặc định khi khởi động: nhấn Alt + F2 rồi thêm vào xvnkb –method=telex –charset=utf8 (trong đó method là telex, vni hoặc viqr; charset là utf8, tcvn, viscii, vps hoặc viqr).

Hàng độc: Nếu bạn thường xuyên sử dụng xvnkb mà rất ít khi thay đổi các thiết lập, thì biểu tượng xvnkb ngoài desktop có vẻ không cần thiết nhỉ? Để cho xvnkb chạy ẩn bên trong, bạn soạn tập tin .xvnkbrc trong thư mục Home Folder với nội dung:

top 0
left 0
method 1
enable 1
charset 5
spelling 0
interface 1
docking 1
font helvetica:size=10:style=bold
hotkey Control Shift_L

.xvnkbrc là file lưu trữ các thiết lập, bạn thử vọc và sửa đổi cho phù hợp nhé :D

Cập nhật: cách sửa lỗi automount CD của xvnkb (”xào nấu” từ blog bạn Bửu: http://lambuu.06ctt.net, các bạn đọc xong khen bạn í một câu không bạn í lại buồn :D)

Nguyên nhân:

Do file reload của xvnkb /etc/ld.so.preload chứa 1 dòng duy nhất: ” /usr/local/lib/xvnkb.so.0.2.9a” .Nếu không có dòng này thì xvnkb sẽ không thể hoạt động, ngược lại thì sẽ không automount CD được. Và một cách giải quyết được đưa ra là: xóa nội dung file khi tắt máy và nạp lại nội dung file khi khởi động, khi đó sẽ “yên ổn mọi bề”.

Cách thực hiện:

Đầu tiên bạn sao lưu lại file /etc/ld.so.preload để đề phòng trường hợp bất trắc xảy ra. Để có thể chỉnh sửa nội dung file, bạn gõ lệnh trong Terminal:

$ sudo chmod a+w /etc/ld.so.preload

(chmod là lệnh chỉnh sửa quyền truy cập file, như ví dụ trên, a+w có nghĩa là “allow all people to write in this file”).

Bây giờ ta sẽ tạo ra file .xsession trong thư mục ~ với nội dung:

#!/bin/bash
gnome-session
echo > /etc/ld.so.preload

Save file, click phải chọn Properties -> Permissions -> Allow executing as program. Để chắc chắn file có thể thực thi được bạn gõ trong Terminal:

$ chmod +x .xsession

Bây giờ chúng ta thử xem file đã hoạt động tốt hay chưa. Tiếp tục trong Terminal:

$ echo /usr/local/lib/xvnkb.so.0.2.9a > /etc/ld.so.preload

Sau đó bạn logout và login trở lại, vào Terminal gõ:

$ cat /etc/ld.so.preload

Nếu vẫn còn thấy nội dung file thì bạn thử logout rồi login lần nữa xem. Còn không restart luôn cho chắc :D Khi nào thấy file trống (tức là chẳng hiện lên gì cả) thì thành công.

Bây giờ ta sẽ tạo ra 1 script tự động nạp nội dung file và khởi động xvnkb. Trong thư mục ~ bạn tạo file fix_xvnkb_start.sh (click phải -> Create Document -> Emty file) và gõ vào:

#!/bin/bash
sleep 9 && echo /usr/local/lib/xvnkb.so.0.2.9a > /etc/ld.so.preload;
sleep 1 && xvnkb -m=telex -c=utf8;

Save file, click phải chọn Properties -> Permissions -> Allow executing as program.

Để script này tự chạy khi khởi động, bạn vào System -> Preferences -> Sessions, chọn Add, đặt tên bất kỳ ở mục Name, ở mục Command ấn Browse trỏ đến file fix_xvnkb_start.sh vừa tạo.

Chú ý:

- Nếu bạn sử dụng kiểu gõ vni thì trong file fix_xvnkb_start.sh bạn sửa lại: -m=vni

- Để ẩn file, bạn thêm dấu chấm phía trước tên file (tức là .fix_xvnkb_start.sh). Làm thế này để đỡ choáng chỗ và tránh xóa nhầm.

Chúc các bạn thành công! :D

Posted in Linux, Ubuntu | 14 Comments »

Ubuntu là gì?

Posted by moriator on 3rd November 2007

Ubuntu là một hệ điều hành do cộng đồng phát triển và là tuyệt vời cho các máy tính xách tay, máy tính để bàn và cả máy chủ. Bất kỳ bạn sử dụng nó ở đâu, Ubuntu đều có tất cả các ứng dụng mà bạn luôn cần, từ các ứng dụng soạn thảo văn bản tới thư điện tử, từ phần mềm máy chủ web tới các công cụ lập trình.

Ubuntu là và sẽ luôn là miễn phí (free of charge). Bạn không phải trả bất kỳ phí bản quyền nào. Bạn có thể tải nó về, sử dụng và chia sẻ Ubuntu với bạn bè, gia đình, nhà trường hoặc doanh nghiệp của bạn mà không vì bất cứ thứ gì một cách tuyệt đối.

Ubuntu được bảo trợ bởi công ty Canonical Ltd (sở hữu bởi Mark Shuttleworth). Nó phát hành một phiên bản mới cứ 6 tháng một lần và hỗ trợ 18 tháng sau khi phát hành phiên bản mới đó thông qua các nâng cấp về an ninh. Với phiên bản hỗ trợ lâu dài – LTS (Long Term Support), bạn sẽ có hỗ trợ 3 năm với các máy tính để bàn và 5 năm đối với các máy chủ. Không có bất kỳ phí bổ sung nào đối với phiên bản LTS. Các nâng cấp lên các phiên bản mới của Ubuntu là và vẫn sẽ là miễn phí (free of charge). Bằng cách này Ubuntu nhắm tới mục tiêu cung cấp một hệ điều hành luôn được cập nhật và tương đối ổn định cho người sử dụng thông qua việc sử dụng các phần mềm tự do.

Với Ubuntu, mọi thứ bạn cần đều có trên 1 đĩa CD, nó cung cấp một môi trường làm việc hoàn chỉnh. Các phần mềm bổ sung luôn sẵn sàng trực tuyến trên Internet.

Trình cài đặt bằng đồ hoạ cho phép bạn có mọi thứ chạy nhanh chóng và dễ dàng. Một cài đặt tiêu chuẩn sẽ mất ít hơn 25 phút.

Một khi máy của bạn được cài đặt thì nó sẵn sàng để sử dụng ngay lập tức. Trên các máy tính để bàn bạn sẽ có một tập hợp đầy đủ các công cụ làm việc, Internet, các ứng dụng đồ hoạ và vẽ, trình soạn thảo văn bản, bảng tính và trình diễn, và cả các trò chơi. Trên máy chủ bạn chỉ có những gì cần thiết để có và chạy và sẽ không có những gì bạn không cần.

Ubuntu cam kết gì?

1. Ubuntu sẽ luôn luôn là miễn phí, kể cả các phiên bản cao cấp (enterprise releases) và luôn có các nâng cấp về an ninh.

2. Ubuntu sẽ đi cùng với các hỗ trợ thương mại từ hãng Canonical và hàng trăm công ty khác khắp toàn cầu.

3. Ubuntu bao gồm nền tảng truy cập và dịch thuật tốt nhất mà cộng đồng phần mềm tự do cung cấp cho người sử dụng

4. Các đĩa CD Ubuntu chỉ có các ứng dụng phần mềm tự do; khuyến khích người sử dụng các phần mềm tự do và nguồn mở, cải tiến và phân phối chúng.

Ubuntu có nghĩa gì?

Ubuntu là một từ có nguồn gốc từ châu Phi, có nghĩa là “lòng nhân ái cho mọi người” (Humanity to others). Hệ điều hành Ubuntu mang tinh thần này của Ubuntu tới cho thế giới phần mềm.

Ubuntu đã phát hành những phiên bản nào và khi nào?

Phiên bản Tên mã Ngày phát hành
4.04 Warty Warthog 20/10/2004
5.04 Hoary Hedgehog 08/04/2005
5.10 Breezy Badger 13/10/2005
6.06 LTS Dapper Drake 01/06/2006
6.10 Edgy Eft 26/10/2006
7.04 Feisty Fawn 19/04/2007
7.10 Gusty Gibbon 18/10/2007

Bạn có thể tải về tự do các phiên bản này trên: http://www.ubuntu.com/

Các con số phiên bản là số năm và tháng phát hành các phiên bản đó. Ví dụ, 7.10 nghĩa là phiên bản được phát hành vào tháng 10/2007.

Sơ lược tiểu sử công ty và người bảo trợ cho Ubuntu

Công ty Canonical Ltd., là một công ty phát triển phần mềm có trụ sở tại thủ đô Luân Đôn, nước Anh, do Mark Shuttleworth thành lập ngày 05/03/2004 (trước khi ra đời phiên bản đầu tiên Ubuntu 4.10 hơn 7 tháng).

Ngoài việc bảo trợ cho dự án Ubuntu, Canonical Ltd. còn bảo trợ cho các dự án liên quan khác như Xubuntu, Edubuntu và Kubuntu.

1. Xubuntu là một hệ điều hành dựa trên Ubuntu và là lý tưởng cho các máy tính cũ, cấu hình thấp, các máy tính công nghệ mạng thin-client (mạng được hình thành từ các máy tính trạm cấu hình rất thấp và thường là không cần ổ cứng, được khởi động từ máy chủ) hoặc cho những ai thích có được tốc độ cao nhất đối với phần cứng sẵn có của máy tính.

2. Edubuntu cũng là một hệ điều hành dựa trên Ubuntu, được tuỳ biến để dành riêng cho các trường học. Các phiên bản trong tương lai của Edubuntu còn hướng tới môi trường các trường đại học.

3. Kubuntu cũng là một hệ điều hành dựa trên Ubuntu. Khác biệt lớn nhất so với Ubuntu là ở chỗ Ubuntu dựa trên môi trường máy tính để bàn GNOME, còn Kubuntu thì là môi trường máy tính để bàn K (K Desktop Environment).

Mark Shuttleworth là một tỷ phú người Nam Phi, sinh ngày 17/09/1973. Ngoài việc là người sáng lập Canonical Ltd. và hỗ trợ các dự án phát triển các hệ điều hành tự do và nguồn mở nêu trên, ông còn nổi tiếng và được nhiều người biết tới như vị khách du lịch vũ trụ thứ 2 của thế giới khi được chọn bay trong năm 2001 trên con tàu vũ trụ Soyuz TM-33 và Soyuz TM-34 với thời gian du lịch trên vũ trụ dài 9 ngày 21 giờ 55 phút.

Nguồn: http://blog.360.yahoo.com/blog-LU.CUQA9b6gRyol5jVT.?p=18

Posted in Linux, Ubuntu | No Comments »