PRF192Chưa đoKỳ 1Cơ sở ngành Cập nhật 2 ngày trước

PRF192 - Cơ sở lập trình

PRF192 - Cơ sở lập trình (Programming Fundamentals) là môn học 3 tín chỉ của Đại học FPT, dạy cách giải quyết bài toán thực tế bằng máy tính thông qua ngôn ngữ C, với trọng tâm là thiết kế chương trình hướng hàm, mô-đun hoá, kiểm thử và kỷ luật lập trình. Nội dung môn học bao quát trọn bộ chương trình 60 buổi theo chín chuẩn đầu ra CLO1 đến CLO9. Nội dung gồm: máy tính và phần mềm (khái niệm cơ bản về hệ thống máy tính, các bước phát triển phần mềm, quy trình mã nguồn - biên dịch - liên kết - thực thi, cấu trúc một chương trình C với chỉ thị tiền xử lý #include, hàm main, dấu chấm phẩy kết thúc câu lệnh, chú thích, trình biên dịch và môi trường DevC++); biến, kiểu dữ liệu và biểu thức (khai báo biến và hằng, quy tắc đặt tên định danh, const và #define, các kiểu int, float, double, char và unsigned cùng miền giá trị, nhập xuất bằng scanf và printf với các đặc tả %d %f %c %s, toán tử số học, phép chia nguyên và phép chia lấy dư, toán tử quan hệ, toán tử logic, toán tử trên bit, toán tử gán rút gọn, tăng giảm một đơn vị, trộn kiểu dữ liệu, ép kiểu tường minh và ngầm định, độ ưu tiên và tính kết hợp); cấu trúc điều khiển (rẽ nhánh if, if-else, if lồng nhau, thang else-if, switch-case với break và default; vòng lặp for, while, do-while, break và continue, vòng lặp lồng nhau; phong cách lập trình với thụt lề, đặt tên có nghĩa và chú thích); mô-đun hoá và hàm (mô-đun là gì và vì sao phải mô-đun hoá, tính kết dính cao và ghép nối lỏng, nguyên tắc định nghĩa mô-đun, định nghĩa hàm với kiểu trả về và danh sách tham số, nguyên mẫu hàm, lời gọi hàm, truyền tham số theo giá trị, phân biệt hàm thư viện với hàm tự viết, phạm vi và thời gian sống của biến cục bộ - toàn cục - static, chương trình dạng menu gọi hàm); con trỏ (khái niệm và công dụng, khai báo con trỏ, toán tử lấy địa chỉ và toán tử truy xuất giá trị, số học con trỏ, con trỏ NULL, truyền tham số theo tham chiếu, quan hệ giữa con trỏ và mảng, cấp phát động bằng malloc, calloc, realloc và free, rò rỉ bộ nhớ); thư viện chuẩn C (stdlib.h, time.h, math.h, ctype.h và vào ra có định dạng); mảng và cấu trúc (mảng một chiều, chỉ số bắt đầu từ 0, mảng hai chiều và ma trận, tìm kiếm tuyến tính, sắp xếp chọn, kiểu struct, truy cập thành viên, mảng struct, typedef); chuỗi ký tự (chuỗi là mảng char kết thúc bằng ký tự null, nhập xuất chuỗi, các hàm trong string.h như strlen, strcpy, strcat, strcmp, mảng chuỗi); và tệp tin (tệp văn bản và tệp nhị phân, con trỏ FILE, fopen với các chế độ mở, fclose, truy cập tuần tự và ngẫu nhiên, fprintf, fscanf, fgets, fputs, fread, fwrite, fseek, ftell, feof).

266Câu hỏi
7Bộ đề
9Chủ đề

Câu hỏi của môn

84/266 câuCòn 182
65Assume we have the following codes:4 lựa chọncó code
Đề bài
double d=9;
double *p = &d;

Suppose that a double occupies the memory block of 8 bytes, and the address of d is 1200. What is the result of the following expression: p + 8?

A1264
B1200
C1208
D1209
Lời giải
Đáp án đúng: "1264". Phép cộng trên con trỏ trong C được tính theo đơn vị phần tử, không theo byte: p có kiểu con trỏ tới double nên p cộng 8 nghĩa là nhảy qua 8 ô double, tức là dịch 8 nhân 8 bằng 64 byte kể từ địa chỉ 1200, cho ra 1264. Nhờ đúng quy ước này mà cách viết p cộng i luôn trỏ tới phần tử thứ i mà người viết không phải nhân tay với kích thước kiểu. Ý "1200" sai vì đó là giá trị của chính p khi chưa cộng gì. Ý "1208" sai vì 1208 là kết quả của p cộng 1, nhảy đúng một ô double. Ý "1209" sai vì nó coi con trỏ như một số nguyên thường rồi cộng thẳng 9 vào, vừa nhầm bước nhảy vừa nhầm cả số hạng; địa chỉ đó còn rơi vào giữa một ô double nên không phải chỗ bắt đầu của phần tử nào.
Mở trang câu hỏi này →
Aabs()
Blabs()
Cllabs()
Dfabs()
Lời giải
Đáp án đúng: "abs()". Thư viện chuẩn chia hàm lấy trị tuyệt đối theo từng kiểu để tránh chuyển đổi ngầm gây mất mát: abs nhận int và trả về int, nên đó là hàm dành riêng cho kiểu int. Ý "labs()" sai vì nó dành cho long, đem dùng cho int thì vẫn chạy nhờ phép nâng kiểu nhưng đó không phải hàm đặc trưng cho int. Ý "llabs()" sai vì nó dành cho long long, một kiểu nguyên rộng hơn và được bổ sung muộn hơn vào chuẩn. Ý "fabs()" sai vì nó nhận và trả về double, tức là dành cho số thực; truyền một int vào fabs thì giá trị bị đổi sang double, kết quả cũng là double, muốn gán về int lại phải cắt phần thập phân nên vừa sai kiểu vừa thừa hai bước chuyển đổi.
Mở trang câu hỏi này →
67What does the following program display?4 lựa chọncó code
Đề bài
#include <stdio.h>

int main()
{
    int a[5] = {1, 2, 3};
    printf("%d", a[0]);
    return 0;
}
A3
B2
C1
DAn error will be raised.
Lời giải
Đáp án đúng: "1". Khi danh sách khởi tạo có ít giá trị hơn số phần tử, C lấp lần lượt từ đầu mảng rồi tự đặt 0 cho những phần tử còn lại, nên a giữ các giá trị 1, 2, 3, 0, 0. Chỉ số trong C đếm từ 0, vì vậy a[0] là phần tử đầu tiên và bằng 1, đúng cái mà printf in ra. Ý "3" sai vì 3 nằm ở a[2], tức là phần tử thứ ba của mảng. Ý "2" sai vì 2 nằm ở a[1]; nhầm lẫn này bắt nguồn từ việc tưởng chỉ số bắt đầu từ 1. Ý "An error will be raised." sai vì khởi tạo thiếu giá trị là hợp lệ và được chuẩn quy định rõ ràng; trình biên dịch không báo lỗi, cũng không để các phần tử còn lại mang giá trị rác.
Mở trang câu hỏi này →
68What does the following program print?4 lựa chọncó code
Đề bài
#include <stdio.h>

int main() {
    int a = 4, *b = &a;
    a--;
    *b=*b-1;
    printf("%d %d", a, *b);
    return 0;
}
A2 2
B2 1
C3 1
D3 3
Lời giải
Đáp án đúng: "2 2". Con trỏ b được gán địa chỉ của a nên từ đó a và *b là hai tên gọi của cùng một ô nhớ. Lệnh a-- hạ ô đó từ 4 xuống 3, rồi *b = *b - 1 đọc chính ô đó được 3, trừ đi 1 và ghi lại 2; khi printf chạy, cả a lẫn *b đều lấy từ ô duy nhất ấy nên hai số in ra buộc phải giống nhau. Ý "3 1" sai vì nó coi a và *b là hai biến riêng, mỗi biến bị giảm đúng một lần; đây cũng là khuyết điểm phải công bố của câu này, bộ khoá đi kèm đề ghi đúng cặp số ấy trong khi mã nguồn không thể sinh ra hai giá trị khác nhau. Ý "2 1" sai vì nó cộng cả hai lần giảm vào a nhưng chỉ tính một lần cho *b, điều không thể xảy ra với hai tên của cùng một ô nhớ. Ý "3 3" sai vì nó bỏ quên một trong hai lệnh giảm, chỉ hạ giá trị từ 4 xuống 3.
Mở trang câu hỏi này →
A=
B||
C==
D!=
Lời giải
Đáp án đúng: "=". Dấu bằng đơn là phép gán: nó ghi giá trị của biểu thức bên phải vào ô nhớ bên trái rồi trả về chính giá trị vừa ghi, nên nó thuộc nhóm toán tử gán chứ không so sánh cũng không tổ hợp điều kiện. Đây là cái bẫy kinh điển của C, bởi viết if với một dấu bằng vẫn dịch được mà ý nghĩa đã khác hẳn phép so sánh bằng. Ý "||" sai vì đó là phép hoặc luận lý, nhận hai điều kiện và cho 1 khi có ít nhất một điều kiện đúng. Ý "==" sai vì đó là phép so sánh bằng, trả về 1 hoặc 0 tuỳ hai toán hạng có bằng nhau hay không. Ý "!=" sai vì đó cũng là một phép so sánh, nó kiểm tra hai toán hạng khác nhau và trả về 1 hoặc 0.
Mở trang câu hỏi này →
Đề bài
#include<stdio.h>
int main()
{
    int a=10,b=20,c=30;
    while(a>1)
    {
        if(b%2!=0)
            a/=10;
        b--;
        c*=2;
    }
    printf("%d ; %d ; %d",a,b,c);
    return 0;
}
A1 ; 18 ; 120
B10 ; 19 ; 60
C1 ; 20 ; 60
D10 ; 19 ; 120
Lời giải
Đáp án đúng: "1 ; 18 ; 120". Điểm then chốt là phạm vi khối do ngoặc nhọn quyết định, không do thụt lề: lệnh if trong vòng while không có cặp ngoặc nhọn nên nó chỉ ôm đúng một lệnh a/=10, còn b-- và c*=2 nằm ngoài if và chạy ở mọi lượt dù được thụt vào trông như thuộc nhánh đó. Lượt thứ nhất b bằng 20 chia hết cho 2 nên a giữ nguyên 10, b về 19, c lên 60. Lượt thứ hai b bằng 19 là số lẻ nên a/=10 đưa a về 1, b về 18, c lên 120. Kiểm tra lần ba, a bằng 1 không còn lớn hơn 1 nên vòng lặp dừng. Ý "10 ; 19 ; 60" sai vì nó dừng lại sau một lượt, trong khi điều kiện a>1 vẫn đúng nên vòng lặp phải chạy tiếp. Ý "1 ; 20 ; 60" sai vì b-- chạy mỗi lượt nên b không thể giữ nguyên 20. Ý "10 ; 19 ; 120" sai vì c đã nhân đôi hai lần thì vòng lặp đã đi hai lượt, mà cách duy nhất để vòng lặp kết thúc là a bị chia về 1.
Mở trang câu hỏi này →
AChecking the return value of fopen()
BUsing ferror()
CUsing feof()
DUsing fprintf()
Lời giải
Đáp án đúng: "Checking the return value of fopen()". Trong C, fopen là chỗ duy nhất cho biết việc mở tệp có thành công hay không: thành công thì nó trả về một con trỏ FILE hợp lệ, thất bại thì trả về NULL, chẳng hạn khi đường dẫn sai hoặc tiến trình không có quyền ghi. Vì mọi hàm làm việc với tệp về sau đều cần con trỏ ấy, bắt buộc phải so nó với NULL ngay sau khi gọi, trước khi đem ra dùng. Ý "Using ferror()" sai vì ferror chỉ tra cờ lỗi của một dòng tệp đã mở được, muốn gọi nó thì trong tay phải có sẵn con trỏ FILE hợp lệ, nghĩa là việc mở đã thành công rồi. Ý "Using feof()" sai vì feof cho biết đã đọc tới cuối tệp, chuyện đó không liên quan gì tới việc mở tệp để ghi. Ý "Using fprintf()" sai vì fprintf là hàm ghi dữ liệu; nếu con trỏ truyền vào là NULL thì chương trình rơi vào hành vi không xác định chứ không nhận được thông báo lỗi nào.
Mở trang câu hỏi này →
72What does the following program display?4 lựa chọncó code
Đề bài
#include <stdio.h>

int main()
{
    int x = 1, y = 2, z = 3;

    x = x - --y;
    z = z + ++y;

    printf("%d %d %d", x, y, z);

    return 0;
}
A-1 5 3
B0 2 5
C1 2 4
D1 5 3
Lời giải
Đáp án đúng: "0 2 5". Phép giảm trước --y hạ y từ 2 xuống 1 rồi mới nộp giá trị mới là 1 cho biểu thức, nên x bằng 1 trừ 1 là 0. Ngay sau đó phép tăng trước ++y nâng y từ 1 lên 2 và nộp giá trị 2, nên z bằng 3 cộng 2 là 5, còn y dừng lại ở 2; ba số in ra là 0, 2 và 5. Ý "1 5 3" sai vì y chỉ dao động giữa 1 và 2 nên không thể thành 5, mà x cũng không thể giữ nguyên 1 khi vế phải bị trừ đi một lượng khác 0; đây là khuyết điểm phải công bố của câu này, bộ khoá đi kèm đề chốt đúng bộ số không thể xảy ra ấy. Ý "-1 5 3" sai vì z chắc chắn bị ghi lại ở lệnh thứ hai nên không còn là 3, và giá trị 5 của y vẫn vô căn cứ. Ý "1 2 4" sai vì nó đọc --y và ++y như thể là giảm sau và tăng sau, dùng giá trị cũ của y, trong khi dạng tiền tố luôn thay đổi y trước rồi mới trả giá trị mới.
Mở trang câu hỏi này →
Aptr = realloc( ptr, 5 * sizeof(int) );
Brealloc( ptr, 5 * sizeof(int) );
Cptr += malloc( 5 * sizeof( int ) );
Drealloc( ptr, 20);
Eptr = realloc( ptr, 20);
Lời giải
Đáp án đúng: "ptr += malloc( 5 * sizeof( int ) );". Lệnh này sai ngay từ lúc dịch vì phép cộng trên con trỏ chỉ chấp nhận một bên là con trỏ và bên kia là số nguyên; ở đây cả hai bên đều là con trỏ, malloc trả về một con trỏ void, nên biểu thức không có nghĩa và trình biên dịch báo toán hạng không hợp lệ. Ý tưởng ấy còn sai về bản chất: muốn nới một vùng nhớ đã cấp thì phải gọi realloc, chứ không phải dịch con trỏ đi đâu đó. Ý "ptr = realloc( ptr, 5 * sizeof(int) );" là cách viết đúng chuẩn, dịch được và chạy đúng. Ý "realloc( ptr, 5 * sizeof(int) );" vẫn dịch được, chỉ bỏ mất con trỏ mới trả về nên tiềm ẩn rò rỉ và con trỏ treo, nhưng đề hỏi lệnh gây lỗi nên nó không phải lựa chọn. Ý "realloc( ptr, 20);" cũng dịch được, chỉ là ghi cứng số byte. Ý "ptr = realloc( ptr, 20);" dịch được và chạy đúng khi int chiếm 4 byte.
Mở trang câu hỏi này →
Acondition ? expression1 : expression2
Bcondition ? expression1, expression2
Ccondition : expression1 ? expression2
Dexpression1 : condition ? expression2
Lời giải
Đáp án đúng: "condition ? expression1 : expression2". Toán tử điều kiện là toán tử ba toán hạng duy nhất của C: phần trước dấu hỏi là điều kiện, dấu hỏi mở ra nhánh giá trị dùng khi điều kiện đúng, dấu hai chấm tách sang nhánh giá trị dùng khi điều kiện sai. Cả cụm là một biểu thức có giá trị nên đặt được ngay trong phép gán hay trong đối số của printf, và chỉ đúng một trong hai nhánh được tính. Ý "condition ? expression1, expression2" sai vì thiếu dấu hai chấm, dấu phẩy ở đó lại là toán tử phẩy nên cụm sau dấu hỏi gộp thành một biểu thức duy nhất và không còn nhánh cho trường hợp sai. Ý "condition : expression1 ? expression2" sai vì đảo chỗ hai dấu, dấu hai chấm không được phép đứng ngay sau điều kiện. Ý "expression1 : condition ? expression2" sai vì điều kiện bị đẩy vào giữa, trong khi cú pháp buộc điều kiện phải đứng trước dấu hỏi.
Mở trang câu hỏi này →
ACompilation involves converting source code to machine code, while interpretation involves executing code line by line.
BCompilation and interpretation are two terms that are used interchangeably.
CAlgorithm is another term for interpretation in programming languages.
DIDE tools are responsible for both compilation and interpretation processes.
Lời giải
Đáp án đúng: "Compilation involves converting source code to machine code, while interpretation involves executing code line by line.". Khác biệt cốt lõi nằm ở thời điểm dịch: trình biên dịch đọc trọn mã nguồn, kiểm tra rồi sinh ra mã máy thành tệp thực thi, sau đó máy chạy trực tiếp tệp ấy mà không cần mã nguồn nữa; bộ thông dịch thì vừa đọc vừa thực hiện từng câu lệnh ở mỗi lần chạy. Ngôn ngữ C thuộc nhóm biên dịch, đó là lý do tệp nguồn phải dịch xong mới có chương trình để chạy. Ý "Compilation and interpretation are two terms that are used interchangeably." sai vì hai cơ chế khác nhau cả về sản phẩm trung gian lẫn cách báo lỗi. Ý "Algorithm is another term for interpretation in programming languages." sai vì thuật toán là trình tự các bước giải một bài toán, không phải một cách thực thi mã. Ý "IDE tools are responsible for both compilation and interpretation processes." sai vì môi trường phát triển chỉ gọi tới trình biên dịch, bản thân nó không làm việc dịch.
Mở trang câu hỏi này →
Amath.h
Bstdio.h
Cconio.h
Dmemory.h
Lời giải
Đáp án đúng: "math.h". Tệp tiêu đề này chứa nguyên mẫu của các hàm toán học trên số thực như sqrt, pow, sin, cos, fabs, ceil, floor, cùng các macro như HUGE_VAL. Có nguyên mẫu thì trình biên dịch mới biết hàm trả về double và mới kiểm được kiểu đối số; thiếu nó, lời gọi dễ bị hiểu sai kiểu trả về và cho ra kết quả lệch. Ý "stdio.h" sai vì nơi đó khai báo những thứ thuộc vào ra như printf, scanf, fopen và kiểu FILE. Ý "conio.h" sai vì đó không phải tệp tiêu đề chuẩn, nó chỉ có trên một số trình biên dịch để làm thao tác bàn phím và màn hình kiểu getch. Ý "memory.h" sai vì đó cũng là tệp ngoài chuẩn, gom vài hàm xử lý khối nhớ mà chuẩn C đặt trong string.h, chẳng hạn memcpy và memset.
Mở trang câu hỏi này →
AA compiler
BA text editor
CA file
DA program
Lời giải
Đáp án đúng: "A compiler". Máy chỉ hiểu được mã máy, còn tệp nguồn là văn bản viết theo quy tắc của ngôn ngữ, nên cần một chương trình chuyên trách đọc văn bản ấy, kiểm tra cú pháp và kiểu, rồi sinh ra các chỉ thị máy; chương trình chuyên trách đó là trình biên dịch. Ý "A text editor" sai vì bộ soạn thảo chỉ giúp gõ và lưu văn bản mã nguồn, nó không hiểu ngữ nghĩa của ngôn ngữ và không sinh ra mã máy. Ý "A file" sai vì tệp là nơi chứa dữ liệu, bản thân nó không thực hiện việc dịch nào. Ý "A program" sai vì nói chung chung như thế thì không phân biệt được gì: trình biên dịch đúng là một chương trình, nhưng đề hỏi cái gì đảm nhiệm việc dịch nên câu trả lời phải nêu đúng loại chương trình làm việc đó.
Mở trang câu hỏi này →
78What will the following code output?4 lựa chọncó code
Đề bài
#include <stdio.h>
int main() {
    int a = 7;
    printf("%d", (a << 2) | 1);
    return 0;
}
A28
B29
C15
D30
Lời giải
Đáp án đúng: "29". Biến a bằng 7 có dạng bit là 111. Phép dịch trái hai nhịp đẩy cả ba bit đó sang trái và lấp hai bit 0 vào cuối, thành 11100, tức là 28; đây cũng là lý do dịch trái n nhịp tương đương nhân với 2 lũy thừa n. Tiếp đó phép hoặc trên bit với 1 chỉ chạm vào bit thấp nhất, bit này đang là 0 nên nó được bật lên, cho 11101 là 29. Ý "28" sai vì nó dừng ở kết quả dịch trái, bỏ quên phép hoặc bit đứng sau. Ý "15" sai vì nó ứng với việc chỉ dịch trái một nhịp, ra 14 rồi bật bit thấp nhất thành 15. Ý "30" sai vì muốn ra 30 thì phải bật bit thứ hai tính từ phải, nghĩa là hoặc với 2, còn mặt nạ trong mã là 1; cũng cần nhớ đây là phép hoặc bit chứ không phải phép cộng, nên 28 không tự cộng thêm 2.
Mở trang câu hỏi này →
79What is the output of this reverse loop?4 lựa chọncó code
Đề bài
#define SIZE 5
int nums[SIZE] = {5, 10, 2, -45, 6};
for (int i = SIZE - 1; i >= 0; i--)
    printf("%d ", nums[i]);
A5 10 2 -45 6
B6 -45 2 10 5
C-45 2 10 5 6
DError
Lời giải
Đáp án đúng: "6 -45 2 10 5". Vòng for đặt i bắt đầu ở SIZE trừ 1 là 4, chạy tiếp khi i còn lớn hơn hoặc bằng 0 và giảm một đơn vị mỗi lượt, nên các chỉ số được thăm theo thứ tự 4, 3, 2, 1, 0. Đọc mảng theo thứ tự đó cho ra 6, -45, 2, 10, 5, mỗi số kèm một dấu cách vì chuỗi định dạng có dấu cách ở cuối. Ở đây vòng for không có cặp ngoặc nhọn nên nó chỉ ôm đúng một lệnh printf, vừa khớp ý định của mã. Ý "5 10 2 -45 6" sai vì đó là thứ tự xuôi, ứng với vòng lặp đi từ 0 lên. Ý "-45 2 10 5 6" sai vì nó bắt đầu từ chỉ số 3 rồi vòng lại phần tử cuối, không có phép lặp nào trong mã sinh ra trật tự ấy. Ý "Error" sai vì khai báo biến đếm ngay trong câu for là hợp lệ từ chuẩn C99, và chỉ số 4 vẫn nằm trong mảng 5 phần tử.
Mở trang câu hỏi này →
Afgets()
Bfputs()
Cftell()
Dfopen()
Lời giải
Đáp án đúng: "fgets()". Hàm này đọc từ một dòng tệp cho tới khi gặp ký tự xuống dòng hoặc khi đã lấy đủ số ký tự mà ta giới hạn, rồi tự thêm ký tự kết thúc chuỗi vào cuối vùng đệm. Chỗ giới hạn kích thước chính là lý do fgets được dùng thay cho gets, vì nó không cho dữ liệu vào tràn khỏi mảng đích. Ý "fputs()" sai vì nó làm việc ngược lại, ghi một chuỗi ra tệp. Ý "ftell()" sai vì nó chỉ cho biết vị trí hiện tại của con trỏ đọc ghi trong tệp, không chuyển một byte dữ liệu nào. Ý "fopen()" sai vì nó chỉ mở tệp và trả về con trỏ FILE cho các hàm khác dùng; mở xong vẫn chưa có ký tự nào được đọc vào bộ nhớ.
Mở trang câu hỏi này →
81What is the output of the following code snippet?4 lựa chọncó code
Đề bài
void main(){
    int x = 4;
    int *p = &x;
    int *k = p++;
    int r = p - k;
    printf("%d", r);
}
A1
B4
C5
D0
Lời giải
Đáp án đúng: "1". Phép tăng sau p++ nộp cho k giá trị cũ của p rồi mới đẩy p sang ô int kế tiếp, nên k trỏ vào x còn p trỏ vào ô liền sau. Hiệu hai con trỏ cùng kiểu trong C được tính theo số phần tử chứ không theo byte: trình biên dịch lấy khoảng cách byte rồi chia cho kích thước kiểu, vì vậy p trừ k bằng 1. Ý "4" sai vì 4 chính là khoảng cách tính bằng byte khi int chiếm 4 byte, tức là bỏ qua bước chia cho kích thước kiểu; nó lại trùng với giá trị của x nên càng dễ nhầm. Ý "5" sai vì không có phép tính nào cộng thêm 1 vào giá trị của x. Ý "0" sai vì nó cho rằng p++ chưa kịp có tác dụng hoặc k mãi mãi đi theo p; cần công bố rằng đây là khuyết điểm của đề, bộ khoá đi kèm ghi đúng giá trị 0 trong khi ngữ nghĩa của phép tăng sau buộc p và k phải lệch nhau đúng một phần tử.
Mở trang câu hỏi này →
Astrcat()
Bstrcomb()
Cstrmerge()
Dstrconnect()
Lời giải
Đáp án đúng: "strcat()". Thư viện chuỗi của C khai báo strcat trong string.h: nó tìm ký tự kết thúc của chuỗi đích, ghi tiếp chuỗi nguồn từ đúng chỗ đó rồi đặt lại ký tự kết thúc, nên người dùng phải tự bảo đảm mảng đích còn đủ chỗ cho cả phần cộng thêm và một byte kết thúc. Ý "strcomb()" sai vì không có hàm nào tên như vậy trong thư viện chuẩn, gọi nó sẽ gây lỗi lúc liên kết. Ý "strmerge()" sai vì đó cũng là một cái tên tự nghĩ ra, chuẩn C không định nghĩa. Ý "strconnect()" sai vì nó cũng không tồn tại; cần nhớ rằng tên các hàm chuỗi trong C đều rất ngắn và cố định, như strcpy để sao chép, strlen để đo độ dài, strcmp để so sánh và strcat để nối.
Mở trang câu hỏi này →
Adouble result = sqrt(9);
Bint result = sqrt(9);
Cfloat result = sqrt(9);
Dresult = power(9, 0.5);
Lời giải
Đáp án đúng: "double result = sqrt(9);". Hàm sqrt được khai báo trong math.h với kiểu trả về double, nên hứng kết quả bằng một biến double là cách duy nhất giữ trọn giá trị mà hàm trả về, không có phép chuyển đổi thu hẹp nào xảy ra. Ý "int result = sqrt(9);" sai vì gán double cho int buộc phải cắt phần thập phân, ở đây tình cờ ra đúng 3 nhưng với căn của 2 hay của 10 thì mất hết phần lẻ. Ý "float result = sqrt(9);" sai vì float hẹp hơn double nên giá trị bị làm tròn khi gán, một lần nữa chỉ vô tình đúng với số chính phương. Ý "result = power(9, 0.5);" sai vì thư viện chuẩn không có hàm nào tên là power, hàm luỹ thừa tên là pow; thêm nữa biến result ở đó còn chưa được khai báo kiểu.
Mở trang câu hỏi này →
84What will be the output of the following C code?4 lựa chọncó code
Đề bài
#include <stdio.h>
void main()
{
    int k = 5;
    int *p = &k;
    int **m  = &p;
    **m = 6;
    printf("%d\n", k);
}
A5
BRun time error
C6
DJunk
Lời giải
Đáp án đúng: "6". Con trỏ p giữ địa chỉ của k, còn m giữ địa chỉ của p. Khi viết **m, lần lấy nội dung thứ nhất đi từ m sang p, lần thứ hai đi từ p sang chính ô nhớ của k, nên **m = 6 ghi số 6 thẳng vào ô của k. Vì k và **m là hai con đường tới cùng một ô, printf đọc ra 6. Đây là bản chất của con trỏ nhiều cấp: chúng không sao chép giá trị mà chỉ nối thêm một chặng đường tới ô nhớ gốc. Ý "5" sai vì 5 chỉ là giá trị ban đầu, nó đã bị ghi đè trước lúc in. Ý "Run time error" sai vì cả hai con trỏ đều trỏ vào biến còn sống trong hàm, không có địa chỉ nào không hợp lệ. Ý "Junk" sai vì k đã được khởi tạo rồi sau đó còn được gán tường minh, không còn chỗ nào để giá trị rác xen vào.
Mở trang câu hỏi này →