Nov
25
2010

Thảo luận về bài tập 4

Người nộp bài sớm nhất là bạn Nguyễn Võ Cao Minh, và bạn làm bài khá tốt. Bắt đầu từ bài này, tôi sẽ comment theo cách sau: lấy bài giải của người gửi về sớm nhất và comment vào đó một cách chi tiết. Sau đó đăng lên cho các bạn coi đáp án và so sánh với bài giải của mỗi người. Bên cạnh đó, tôi vẫn comment nếu trong bài giải của bạn nào đó có chi tiết mà tôi thấy thú vị, cần trích dẫn vào trong bài giải.

***

Có một bạn vô Yahoo! Hỏi tôi thế này “có vẻ như anh Mèo Mun ra các bài tập thiên về kiểm tra tính kiên nhẫn của các bạn hơn là ra các bài tập khó (về kiến thức) phải không?”.

Như trong bài đầu tiên tôi có nói, tôi đã từng tự học và tôi biết với đặc thù của việc học online trên mạng thì điều gì là quan trọng nhất ở mỗi thời điểm. Với giai đoạn đầu tiên này, tôi mong các bạn rèn luyện được tính kiên nhẫn, cẩn thận và chịu khó đặt câu hỏi. “Trăm hay không bằng tay quen”, các bạn có thông minh đến đâu chăng nữa nhưng nếu không chịu khó làm bài tập thì sẽ không thể có “tay quen” được (nhưng trong trường hợp này là “quen mắt” thì đúng hơn).

Hoàn thành các bài tập sau bài học, các bạn sẽ “quen mắt” với việc đọc code, việc này rất có ích cho bạn khi học các bài sau: “trộn lẫn” mã PHP với HTML, JS, CSS… Tôi nhấn mạnh vào chữ hoàn thành. Bạn chỉ cần “hoàn thành” bài chứ không cần “làm đúng”. Đúng/sai, đúng đến đâu, sai đến đâu… còn phụ thuộc vào năng lực của mỗi người nhưng “hoàn thành” thì tôi nghĩ là ai cũng có thể làm được cả.

***

Bài 4 – Biến và kiểu dữ liệu

Bài 4.1:

Có thể chỉ dùng chữ cái (a,b,c…) để đặt tên biến hay không? (Có)

Bình luận của tôi: Các bạn cần chú ý đến chữ “chỉ” trong các câuhỏi này. “Chỉ dùng chữ cái” có nghĩa là nếu tên biến $a1, $a2… là các tên biến không được đề cập tới trong bài này. Bạn Minh đặt tên biến là $abc, sau đó chạy thử và PHP không báo lỗi (đồng thời hiển thị giá trị biến), nhờ đó bạn kết luận rằng có thể chỉ dùng chữ cái abcd… để đặt tên biến. Đây là một câu trả lời đúng nhưng không nên là kết luận.

Có thể chỉ dùng chữ số (0,1,2,3…) để đặt tên biến hay không? (Không)

Bình luận của tôi: Để kết luận vấn đề là đúng, cần thử nhiều trường hợp. Còn để kết luận vấn đề đó sai, chỉ cần tìm ra 1 trường hợp sai là đủ. Với câu hỏi này, bạn đã làm đúng.

Có thể dùng kết hợp chữ cái và chữ số để đặt tên biến hay không? (Tuỳ)

– Có với điều kiện số không được đứng đầu biến

– Không khi có chữ số đứng đầu tên biến

Bình luận của tôi: Bạn trả lời đúng.

Có thể dùng các ký tự + – * / để đặt tên biến hay không? (Không)

Bình luận của tôi: Bạn trả lời đúng. Nhưng tôi chưa thấy bạn thử với trường hợp – * / , mà chỉ thử với dấu + mà thôi.

Tên biến có phân biệt chữ hoa và chữ thường không? (Ví dụ, biến $abc với biến $Abc là khác nhau hay giống nhau) (Có khác nhau)

Ta thấy, trình biên dịch không hiểu $Abc là biến gì, và không in ra kết quả

Bình luận của tôi: Bạn trả lời đúng. Tuy nhiên, theo tôi, bạn có thể gán biến $abc là minh và $Abc là một giá trị khác và thử hiển thị cả 2 biến ra màn hình. Như thế sẽ có cơ sở kết luận vững chắc hơn so với cách mà bạn đang làm.

Tên biến có thể bắt đầu bằng một chữ số hay không? (Ví dụ $1abc, $2cdh, $3kkklm…) (Không)

Như ví dụ ở câu 3 em đã đề cập tới

Bình luận của tôi: Bạn trả lời đúng.

Tên biến có thể bắt đầu bằng dấu gạch dưới _ hay không? (Ví dụ $_1c, $_2c, $_3m…) (Được)

Bình luận của tôi: Bạn trả lời đúng.

Có được đặt 1 biến tên là $php hay không? (Được)

Bình luận của tôi: Bạn trả lời đúng.

Có được đặt 1 biến tên là $echo hay không? (Được)

Bình luận của tôi: Bạn trả lời đúng. Tôi cũng nói thêm, sở dĩ tôi đặt câu hỏi tên biến là $php và $echo vì đó là những tên biến “đặc biệt”, do nó trùng với từ khoá trong PHP. Và như các bạn đã thấy, khác với Pascal, tên biến trong PHP được đặt trùng với từ khoá. Các bạn hãy trả lời vào ô comment của bài này: theo các bạn tại sao PHP cho phép chúng ta làm điều đó mà Pascal thì không?

Bài 4.2:

=> Gán biến với giá trị như sau :

$int=12;

$fl=1.2;

$str=’abc’;

ñ  int + int tạo ra dữ liệu kiểu gì? (INT)

echo var_dump($int+$int);

ñ  int + float tạo ra dữ liệu kiểu gì? (FLOAT)

echo var_dump($int+$fl);

ñ  float + int tạo ra dữ liệu kiểu gì? (FLOAT)

echo var_dump($fl+$int);

ñ  int + string tạo ra dữ liệu kiểu gì? (INT)

echo var_dump($int+$str);

ñ  string + float tạo ra dữ liệu kiểu gì? (FLOAT)

echo var_dump($str+$float);

ñ  Int . int tạo ra dữ liệu kiểu gì? (STRING)

echo var_dump($int.$int);

ñ  Float . float tạo ra dữ liệu kiểu gì? (STRING)

echo var_dump($fl.$fl);

ñ  String . float tạo ra dữ liệu kiểu gì? (STRING)

echo var_dump($str.$fl);

ñ  Int + float . string tạo ra dữ liệu kiểu gì? (STRING)

echo var_dump($int+$fl.$str);

ñ  int * int tạo ra dữ liệu kiểu gì? (INT)

echo var_dump($int*$int);

ñ  int / float tạo ra dữ liệu kiểu gì? (FLOAT)

echo var_dump($int/$fl);

ñ  float / int tạo ra dữ liệu kiểu gì? (FLOAT)

echo var_dump($fl/$int);

ñ  int / string tạo ra dữ liệu kiểu gì? (ERROR)

echo var_dump($int/$str);

ñ  string * float tạo ra dữ liệu kiểu gì? (FLOAT(0))

echo var_dump($str*$fl);

ñ  Int / int tạo ra dữ liệu kiểu gì? (Tuỳ vào kết quả, nếu ra số thập phân thì là FLOAT, còn nếu ra số nguyên thì là INT)

echo var_dump($int/$int);

ñ  Float / float tạo ra dữ liệu kiểu gì? (FLOAT)

echo var_dump($fl/$fl);

ñ  float * string tạo ra dữ liệu kiểu gì? (FLOAT(0))

echo var_dump($fl*$str);

ñ  Int / float + string tạo ra dữ liệu kiểu gì? (FLOAT)

echo var_dump($int*$fl+$str);

ñ  Int % float tạo ra dữ liệu kiểu gì? (INT)

echo var_dump($int%$fl);

ñ  int % int tạo ra dữ liệu kiểu gì? (INT)

echo var_dump($int%$int);

Bình luận của tôi: Tương tự như comment ở phần bài tập 1. Bạn cần có nhiều phép thử trước khi đưa ra kết luận. Với bài tập này, tôi không đưa ra kết luận là câu trả lời của các bạn đúng hay sai. Tôi chỉ đang hướng dẫn các bạn cách tự học thôi. Các bạn cũng không cần “học thuộc lòng” xem int/int ra kết quả giá trị gì; string+float ra kết quả giá trị gì… Nhưng các bạn cần nhớ cách mà chúng ta sử dụng var_dump để thử và có kết luận trong những trường hợp cần tới.

Bạn Minh nói int / string tạo ra dữ liệu kiểu… ERROR là do bạn đang chỉ kiểm nghiệm với một trường hợp chuỗi string của bạn là abc. Giá trị abc thực sự rất… string! Nhưng hãy thử với $str = ‘123’ chẳng hạn xem kết quả có khác đi không nhé.

Bài 4.3:

$a = $a . ”;

Bình luận của tôi: Bài này yêu cầu bạn đổi từ kiểu nguyên qua kiểu chuỗi. Bạn đã làm đúng rồi. Bạn cũng có thể làm như thế này cũng được:

Tôi chưa có điều kiện để kiểm tra xem cách làm nào lẹ hơn. Ở các bài sau, tôi sẽ hướng dẫn các bạn cách đo lường tốc độ thực thi của chương trình, khi ấy chúng ta sẽ cùng đo lường xem cách nào tối ưu hơn nhé.

Bài 4.4:

$a = $a * 1;

Bình luận của tôi: Bài này yêu cầu bạn đổi từ kiểu chuỗi qua kiểu nguyên. Bạn đã làm ra kết quả đúng nhưng sử dụng phép tính nhân – theo tôi dự đoán – sẽ không tối ưu bằng việc dùng tính cộng như ví dụ dưới đây.

Nhắc lại, đây là dự đoán của tôi, nhưng tôi tin 99% là dự đoán này chính xác. Chúng ta sẽ quay lại và đo lường sau nhé.

Bài 4.5:

$a = $a + 0.0;

Bình luận của tôi: Bài này yêu cầu bạn đổi từ kiểu nguyên qua kiểu thực. Bạn đã thực hiện phép + với 0.0 là đúng và tối ưu (thậm chí còn đúng với cách làm mà tôi mong muốn nữa). Tại vì, ngoài cách + 0.0, các bạn cũng có thể nhân với 1.0 để cho ra kết quả số thực như cách làm dưới đây.

Nhưng tôi khuyến khích làm như trong bài giải của bạn Minh vì phép cộng sẽ thực thi nhanh hơn phép nhân các bạn nhé.

Bài 4.6:

Kiểu String: Theo em đoán thì nó không giới hạn độ dài. Vì theo em biết kiểu dữ liệu LONG TEXT trong SQL có kích thước lên tới 16GB, mà PHP lấy dữ liệu từ DB ra và xử lý được, nên có th ở PHP ểkhông có giới hạn về độ dài String.

Kiểu int: không tìm ra

Kiểu float: không tìm ra

Bình luận của tôi: Bạn phân tích… hay quá 😀 Nhưng bạn dùng những kiến thức cao siêu chưa học tới nên tôi không khuyến khích. Khi tôi ra bài tập này, tôi chỉ muốn các bạn mở notepad ra, khai báo một biến kiểu chuỗi bất kì, rồi copy / paste giá trị để nó … dài thoòng ra. Rồi chạy thử coi PHP có báo lỗi hay không, như ví dụ dưới đây.

Chú ý ở ví dụ này tôi không cần echo, không làm gì hết, tôi chỉ khai báo biến và coi có bị báo lỗi hay không. Nhìn vô thanh cuốn của notepad, chắc các bạn cũng hình dung ra biến này nó là một chuỗi rất dài đúng không? Còn cụ thể hơn, mở Window Explorer coi thông tin file bai1.php, hiện dung lượng nó là 4.47MB tương đương với 4,577 Kilobytes, tương đương với 4,687,134 Bytes.

File bai1.php là file text nên mỗi ký tự trong file sẽ chiếm 1 byte. Nên 4 triệu bytes tương ứng với 4 triệu ký tự. Chúng ta có biến $a với độ dài 4 triệu ký tự mà chưa thấy báo lỗi gì nên tạm kết luận rằng biến kiểu string trong PHP không bị giới hạn độ dài.

Bài 4.7:

echo ‘E:\\PHP>php manguon\\input.txt

Xin chao, toi la Long “/\\/\\e`o /\\/\\un”

Toi co rat nhieu $… am phu

Nen /\\/guoi ta goi toi la Ty Phu Khong /\\/ha`

E:\\PHP>’;

Bình luận của tôi: Bài này tôi đã nói các bạn phải đọc kỹ vì tôi đố mẹo. Và bạn Minh đã bị mắc bẫy của tôi rồi. Bạn có một lời giải rất… sách vở. Cứ ở đâu có dấu \ thì bạn thay bằng \\; thực ra thì ở bài này, các bạn chỉ cần copy đúng đoạn text trong bài, sau đó bao nó bởi cặp dấu nháy đơn ‘ là xong; không cần “xiệc xiệc” gì ở đây hết. Tất nhiên, cách làm của bạn không sai, khi chạy chương trình vẫn có kết quả hiển thị đúng.

Bài 4.8:

echo ‘<?php

echo \’this is a simple string\’;

echo \’You can also have embedded newlines in

strings this way as it is

okay to do\’;

// Outputs: Arnold once said: “I\’ll be back”

echo \’Arnold once said: “I\’ll be back”\’;

// Outputs: You deleted C:\*.*?

echo \’You deleted C:\\\\*.*?\’;

// Outputs: You deleted C:\\*.*?

echo \’You deleted C:\\*.*?\’;

// Outputs: This will not expand: \\n a newline

echo \’This will not expand: \\n a newline\’;

// Outputs: Variables do not $expand $either

echo \’Variables do not $expand $either\’;

?>’;

Bình luận của tôi: Bài này bạn làm ra kết quả đúng. Tôi không biết bạn làm thế nào, nhưng tôi chia sẻ một kinh nghiệm khi “xiệc xiệc” thế này. Tôi sẽ copy đoạn text này, paste nó vô notepad (hoặc các trình biên tập khác mà các bạn xài). Sau đó bôi đen nó, chọn tính năng tìm kiếm và thay thế. Tôi nhờ trình biên tập thay tất cả các dấu \ thành \\; sau đó biến hết dấu nháy đơn ‘ thành “xiệc nháy đơn” \’ . Cuối cùng tôi thêm hai dấu nháy đơn vào đầu và cuối chuỗi. Thế là xong.

Các bạn nhớ thứ tự thay thế phải là thay thế \ thành \\ trước, rồi mới ‘ thành \’ sau (nếu đảo thứ tự sẽ có lỗi, tại sao thế?)

Hiện chúng ta đang học những vấn đề rất basic. Mọi thứ phải làm “bằng tay”. Tôi không khuyến khích các bạn dùng tools. Chúng ta tập thói quen code “bằng tay” là để hiểu và nắm được vấn đề. Sau khi thật quen và thành thục, chúng ta mới dùng tools để nâng cao hiệu suất và tận dụng những ưu điểm của nó. Chúng ta chỉ dùng tools khi có thể làm chủ nó, vì nếu không, nó sẽ làm chủ chúng ta.

3 Comments + Add Comment

  • Theo mình PHP cho phép chúng ta đặt tên biến trùng với từ khóa mà Pascal thì không vì PHP xem một biến phải có kí tự $ đằng trước khi đó $echo khác hoàn toàn với echo. Còn PASCAL không bắt buộc 1 biến phải bắt đầu bằng kí tự $ nên nó không thể phân biệt được đâu là từ khóa, đâu là tên biến nếu như đặt trùng tên

  • ví dụ:
    $int = 12;
    $fl = 1.2;
    $str = ‘abc’;
    var_dump($int + $fl.$str); // string(7) “13.2abc”
    var_dump($fl.$str +$int); // float(13.2)

    Kết luật: php không ưu tiên phép nào cả mà cứ tính từ trái sang phải thôi?

  • Phép + cộng với phép . nối chuỗi có độ ưu tiên ngang nhau nên tính từ trái qua phải á

Leave a comment