Bài Con trỏ (tiếp) Mục tiêu: Luyện tập sử dụng trỏ địa biến Sử dụng trỏ thao tác với mảng Giới hạn: không dùng C++String thư viện stl (chẳng hạn vector, algorithm) Yêu cầu nộp : Toàn phần A1-3 C1-2 Bài đánh giá theo cố gắng làm việc Bạn cần làm đủ yêu cầu đề Nếu bạn làm A4 với đầy đủ chi tiết, bạn bù điểm cho tập trước Viết vào readme.txt có nhu cầu (chú ý đặt tên file xác) Lưu ý: chép cho chép dẫn đến trượt môn học! A Thực hành Nếu bạn chưa thạo trỏ, bạn dùng phương pháp để tự lần bước đoạn code ngắn mà khơng cần máy tính, qua nắm vững thao tác trỏ nhớ Vẽ bảng biểu diễn vùng nhớ sử dụng đoạn chương trình đó, chẳng hạn: Giả sử có kích thước 32 bit, nghĩa biến int trỏ, tự bịa địa cho ô nhớ dùng địa đánh nhãn cho chúng Chẳng hạn: 0x1000 0x1004 0x1008 0x100c Với biến đoạn code, đặt vào ô nhớ Chẳng hạn, char* s địa 0x1004 int i địa 0x1008: 0x1000 0x1004 Giá trị s 0x1008 Giá trị i 0x100c Giả sử ta có lệnh gán s = “Hi Amy!”; nghĩa s trỏ tới chuỗi kí tự có nội dung “Hi Ann!” nhớ, giả sử trình biên dịch đặt chuỗi vùng nhớ địa 0x100c, nghĩa vùng nhớ 0x1004 s có giá trị 0x100c Giả sử ta có lệnh gán i = 20; có nghĩa vùng nhớ 0x1008 i giữ giá trị 20 Ta có sơ đồ nhớ: 0x1000 0x1004 Giá trị s: 0x100c 0x1008 Giá trị i: 20 0x100c Hi A 0x1010 my!\0 Có thể đọc từ sơ đồ nhớ thông tin sau: Biểu thức i Mô tả Giá trị biến int i Giá trị ví dụ 20 &i Địa biến i 0x1008 s Giá trị biến trỏ s 0x100c &s Địa s 0x1004 *s Kí tự mà s trỏ tới, nghĩa giá trị kiểu char vùng nhớ có địa giá trị s ‘H’ s[3] Kí tự mà (s+3) trỏ tới, nghĩa kí tự thứ đứng sau vị trí s trỏ tới ‘A’ s+4 Địa thu cộng vào s 0x1010 *(s+4) Kí tự địa mà (s+4) trỏ tới - địa 0x1010 ‘m’ Giả sử ta có lệnh gán char** p = &s; có nghĩa p trỏ tới trỏ kiểu char p trỏ tới địa biến s Giả sử địa p 0x1000, Ta có sơ đồ nhớ: 0x1000 Giá trị p: 0x1004 0x1004 Giá trị s: 0x100c 0x1008 Giá trị i: 20 0x100c Hi A 0x1010 my!\0 Và ta đọc tiếp từ sơ đồ nhớ thông tin sau: Biểu thức Mô tả Giá trị ví dụ p Giá trị biến p 0x1004 &p Địa biến p 0x1000 *p Giá trị ô nhớ mà p trỏ tới (ô nhớ địa 0x1004) Ở p trỏ tới char*, nên nhớ có kiểu trỏ - địa nhớ 0x100c **p Kí tự địa (*p) ‘H’ Hãy điền thêm vào chương trình Để in địa biến x hàm f() biến y hàm g() Bạn có nhận xét địa hai biến đó, thử giải thích Gợi ý (bơi đen để nhìn thấy): : vị trí stack frame cho hàm f chạy trùng với vị trí hàm g gọi (đều bắt đầu đỉnh stack hàm main), hai hàm f g có tham số kiểu int, kiểu trả về, x y biến địa phương hàm, khả lớn trình biên dịch xếp x y địa void f(int xval) { int x; x = xval; // in địa x } void g(int yval) { int y; // in địa y } int main() { f(7); g(11); return 0; } Tính kích thước biến Chương trình sử dụng phép tốn trỏ để tính kích thước biến kiểu char Con trỏ cp trỏ tới biến thuộc liệu kiểu, cộng thêm vào cp, ta có trỏ trỏ tới phần tử thuộc kiểu liệu Do đó, biết giá trị hai trỏ cp (cp+1), ta tính kích thước kiểu liệu Trong chương trình đây, ta dùng cp trỏ tới kiểu char Vì kích thước liệu kiểu char 1, chênh lệch giá trị hai trỏ a Hãy thử dịch chạy để quan sát hoạt động chương trình b Sửa chương trình để xem output tính kích thước kiểu int c Sửa chương trình để xem output tính kích thước kiểu double d Chuyện xảy thay cp++ cp+=2 ? Hãy tính trước kết thử lại chương trình (làm cho kết câu c) int main( ) { char a[4] = "abc"; for (char *cp = a; (*cp) != '\0'; cp++) { cout