1. Trang chủ
  2. » Công Nghệ Thông Tin

Đề thi Kỹ thuật lập trình có lời giải

49 8,8K 27
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Đề Thi Kỹ Thuật Lập Trình Có Lời Giải
Trường học Trường Đại Học
Chuyên ngành Kỹ Thuật Lập Trình
Thể loại đề thi
Định dạng
Số trang 49
Dung lượng 9,04 MB

Nội dung

Tổng hợp các đề thi cuối kỳ môn Kỹ thuật lập trình thầy Vũ Đức Vượng Đại học Bách Khoa Hà Nội. Tài liệu có đáp án và giải thích chi tiết giúp cho người đọc nắm vững các kiến thức về kỹ thuật lập trình C

Trang 1

Đề thi số 1

Môn: Kỹ thuật lập trình (IT3040)

Thời gian: 90 phút

SV được phép sử dụng tài liệu, nhưng không được trao đổi tài liệu, máy tính, điện thoại dđ

Câu 1 (0.75đ): Tinh chỉnh đoạn mã sau và giải thích:

int letter_count(const char *buf, int size){

int count, i;

count = 0;

for (i = 0; i < size; i++) {

if ((buf[i] >= 'A' && buf[i] <= 'Z') ||

(buf[i] <= 'z' && buf[i] >= 'a'))

count++;

}

return count;

}

Câu 2 (1đ): Cho biết giá trị các phần tử của mảng B sau

khi thực hiện đoạn lệnh dưới đây:

int B[] = {2,4,7,8,9,15};

int c,*p=&B[1];

*p+=1; c=*p ;

p+=3; *p+=c;

Câu 3 (0.75đ): Phân tích đoạn mã lệnh sau, tìm các lỗi

sai (nếu có) rồi sửa lại:

Câu 4 (2.5đ): Viết hàm đệ quy void chuyenCoSo(int

base, int number) để chuyển đổi một số nguyên

number từ hệ cơ số 10 sang hệ cơ số bất kì base (từ 2

đến 16) Sau đó viết lại hàm dưới dạng không đệ quy

Câu 5 (1đ): Xây dựng cấu trúc phân số gồm tử số và

mẫu số là các số nguyên Thực hiện đa năng hoá toán tử

~ có chức năng giản ước phân số

Ví dụ: ~(10/6) = 5/3

Câu 6 (1đ): Tối ưu đoạn code sau:

int i,m,n,p;

float c,*a,*b,*c,*d;

/* Gán giá trị các biến cần thiết */

for(int i=0; i<4*n; i++){

a[i]=b[i]+c[i]+d[i]+47-5*sin(c)+3*tan(c); m=16*n + 512*p – 17*sin(c);

Câu 8 (1đ): Đoạn mã sau thực hiện việc copy xâu từ

xâu nguồn src sang xâu đích dest Phân tích, tìm và sửa

các lỗi sai (nếu có):

void strcpy(char *dest, char *src) {

int i;

for (i = 0; src[i] != '\O'; i++) dest[i] = src[i];

}

Trang 2

Tương tự với biểu thức logic chứa AND: (E1 AND E2) Nếu E1 có giá trị FALSE thì cả biểu thức là FALSE Do đó ta đưa biểu thức

có xác suất FALSE lớn nhất lên đầu

Từ những lập luận trên, ta có đoạn code tối ưu như sau:

int letter_count(const char *buf, int size)

{

int count, i;

count = 0;

for (i = 0; i < size; i++) {

if ((buf[i] >= 'a' && buf[i] <= 'z') ||

(buf[i] >= 'A' && buf[i] <= 'Z'))

count++;

}

return count;

}

Trong 1 đoạn văn bản thì xác suất gặp chữ thường là nhiều hơn cả, do đó đặt biểu thức kiểm tra chữ thường lên đầu Chưa hết, trong

1 text file thì thường các ký tự có giá trị nhỏ hơn bằng 'z' Và khi đó, rõ ràng biểu thức (buf[i] <= 'z' && buf[i] >= 'a') không tối ưu bằng (buf[i] >= 'a' && buf[i] <= 'z')

Câu 2 (1đ): Bài này đơn giản, để gỡ điểm

Ở đây ban đầu p trỏ tới B[1] *p+=1 ~ B[1]+=1 => B[1] = 4+1=5

c=*p ~ c=*p và p => c=B[1]=5, p trỏ tới B[0]

p+=3 => p trỏ tới B[3]

*p+=c => B[3]+=5 => B[3] = 13

Vậy giá trị các phần tử mảng sau khi thực hiện đoạn lệnh là B[] = {2,5,7,13,9,15}

Câu 3 (0.75đ): Đoạn code này thực hiện việc in từng phần tử của chuỗi thành từng dòng Ở đây sử dụng vòng lặp do-while Do đó

sẽ gặp lỗi nếu xâu s là xâu rỗng

Sửa lại như sau bằng cách đổi sang vòng lặp for:

for (i = 0; s[i] != '\0'; i++){

putchar(s[i]);

putchar('\n');

}

Phát hiện lỗi: 0.5đ, sửa lỗi: 0.25đ

Câu 4 (2.5đ): Hàm đệ quy 1.25đ, hàm không đệ quy 1.25đ

//HÀM ĐỆ QUY

Trang 3

void chuyenCoSo(int base, int number)

{

char digits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; if(number<=0)

Xây dựng cấu trúc phân số (0.25đ):

typedef struct PhanSo{

Trang 4

int TuSo, MauSo;

+ Nhìn vào vòng lặp for ta thấy cận trên và bước nhảy là 4*n, i++, tức là phải thực hiện 4*n lần lặp Có thể tối ưu bằng cách giảm bớt

số lần lặp xuống còn n lần như sau: (kĩ thuật này còn gọi là kĩ thuật Loop Unrolling, các bạn có thể tìm hiểu thêm trên Google) (0.5đ) for(i=0; i<4*n; i+=4){

Câu 7 (2đ): Đề yêu cầu đưa ra phần tử lẻ nhỏ nhất của danh sách Sử dụng ý tưởng sau:

+ Duyệt toàn bộ danh sách và đếm số phần tử lẻ trong danh sách Nếu không có phần tử lẻ thì trả về 0 ngay

+ Nếu có phần tử lẻ thì lưu các phần tử lẻ này vào 1 mảng cấp phát động với kích thước = số phần tử lẻ (cho tiết kiệm bộ nhớ) + Duyệt mảng này và tìm phần tử nhỏ nhất Cái này thì quá đơn giản và quen thuộc

//Hàm đếm số phần tử lẻ trong danh sách

int demSoPtLe(node *head){

int k=0;

Trang 5

Chép chuỗi được trỏ bởi con trỏ src vào một mảng được trỏ bởi con trỏ dest, bao gồm cả kí tự NULL (kí tự kết thúc xâu, \0)

Để tránh tràn thì kích thước của mảng được trỏ bởi con trỏ dest phải đủ lớn để chứa xâu trỏ bởi con trỏ src bao gồm cả kí tự NULL

và không được chồng lên vùng nhớ được trỏ bởi src

Do đó ta sửa lại như sau bằng cách chỉnh lại điều kiện trong vòng lặp (có thể dùng kiểu void và không trả về giá trị dest như đoạn code ban đầu cũng được):

char* strcpy(char * dest, const char *src);

Trang 6

Đề thi số 2

Môn: Kỹ thuật lập trình (IT3040)

Thời gian: 90 phút

SV được phép sử dụng tài liệu, nhưng không được trao đổi tài liệu, máy tính, điện thoại dđ

Câu 1 (0.75đ): Tinh chỉnh đoạn mã sau và giải thích:

int calc(int subkey, int bitoff){

subkey = subkey >>

(bitoff - ((bitoff >> 5) << 5));

return subkey;

}

Câu 2 (1đ): Cho biết giá trị các phần tử của mảng A sau

khi thực hiện đoạn lệnh dưới đây:

Câu 3 (2.5đ): Viết hàm đệ quy void chuyenCoSo (int

base, int number) để chuyển đổi một số nguyên

number từ hệ cơ số 10 sang hệ cơ số bất kì base (từ 2

đến 16) Sau đó viết lại hàm dưới dạng không đệ quy

Câu 4 (1đ): Xây dựng cấu trúc số phức gồm phần thực

và phần ảo là các số thực Thực hiện đa năng hoá toán

tử ~ có chức năng đưa ra số phức liên hợp của số phức

/* Gán giá trị cho các biến cần thiết */

for(i=0; i<3*n; i++){

Câu 7 (2đ): Cho một danh sách liên kết đơn với các nút

được khai báo như sau:

typedef struct node{

void factorial(int n){

int fac=1;

while (n ) fac *= n;

return fac;

}

b Đoạn mã sau thực hiện việc tính trung bình cộng các phần tử trong mảng a[] Phân tích, tìm các lỗi sai và sửa lại (0.5đ):

double avg(double a[], int n){

Trang 7

ĐÁP ÁN ĐỀ THI SỐ 2

Câu 1 (0.75đ): Ta có thể thấy ngay đoạn code này chẳng có gì ngoài việc trả về giá trị của subkey Do đó việc tinh chỉnh

chỉ đơn giản là tinh chỉnh các biểu thức toán học sao cho máy có thể thực hiện nhanh hơn Dễ dàng nhận thấy như sau:

Ở đây, giá trị bitoff đầu tiên dịch phải 5bit, sau đó lại được dịch trái 5bit Như vậy biểu thức (bitoff>>3)<<3 sẽ chuyển 5bit cuối của bitoff thành 00000 Giả sử bitoff = **** **abcde (abcde là các bit)

Do đó, bitoff - ((bitoff >> 5) << 5)) = **** **abcde - **** **00000 = 0000 00abcde

= bitoff & 0000 0011111 = bitoff & 0x1F

Vì vậy ta có đoạn code tối ưu như sau:

int calc(int subkey, int bitoff){

subkey >>= bitoff & 0x1F;

return subkey;

}

Câu 2 (1đ): Bài này khá đơn giản và quen thuộc:

Ở đây ban đầu p trỏ tới A[2]

b=*p++ ~ b=*p và p++ => b=A[2]=19, p trỏ tới A[3]

*p+=2*b => A[3]+=2*19 => A[3] = 39

p++ => p trỏ tới A[4]

*p+=1 => A[4] +=1 => A[4] = 3

Vậy giá trị các phần tử mảng sau khi thực hiện đoạn lệnh là A[] = {5,7,19,39,3,6}

Câu 3 (2.5đ): Hàm đệ quy 1.25đ, hàm không đệ quy 1.25đ

//HÀM ĐỆ QUY

void chuyenCoSo(int base, int number)

{

char digits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; if(number<=0)

Trang 8

Câu 4 (1đ): Xây dựng cấu trúc số phức như sau: (0.5đ)

typedef struct SoPhuc{

float Thuc, Ao;

for(i=0; i<3*n; i+=3){

Trang 9

Câu 6 (1đ): Thoạt nhìn đây có vẻ là một câu khá ‘hiểm’ và khó phát hiện ra lỗi Tuy nhiên, nếu tinh ý thì câu này quá

đơn giản Ở đây ta nhận thấy biến p cấp phát động sai do hàm strlen không tính kí tự kết thúc xâu (‘\0’) Do đó ta sửa lại

đoạn code như sau:

Câu 7 (2đ): Đề yêu cầu đưa ra phần tử chẵn lớn nhất của danh sách Sử dụng ý tưởng sau:

+ Duyệt toàn bộ danh sách và đếm số phần tử chẵn trong danh sách Nếu không có phần tử chẵn thì trả về 0 ngay + Nếu có phần tử chẵn thì lưu các phần tử chẵn này vào 1 mảng cấp phát động với kích thước = số phần tử chẵn (tiết kiệm bộ nhớ)

+ Duyệt mảng này và tìm phần chẵn lớn nhất Cái này thì quá đơn giản và quen thuộc

int *a=new int [m];

int i=0, max;

for(tmp=head; tmp!=NULL; tmp=tmp->next){

if((tmp->data)%2==0)

Trang 10

a[i++]=tmp->data; //nếu gặp phần tử chẵn thì lưu vào mảng a

Trang 42

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 1

Đoạn lệnh dưới đây dùng để loại bỏ kí tự cuối cùng của một xâu str[ ]

Hãy tiến hành kiểm thử và hiệu chỉnh đoạn code để đoạn lệnh sau sẽ luôn đúng trong mọi trường hợp

Với a là một biến int, dòng lệnh : scanf( “%d”, a) ; gây ra lỗi buid_time

hay Run_time, giải thích tại sao ?

Câu 4 : (0,75 đ) Tính giá trị của các phần tử của mảng A sau khi thực hiện

đoạn lệnh dưới đây :

Trang 43

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 1

2

Câu 5 : (1,0 đ)

Hãy tinh ch ỉnh đoạn mã lệnh sau bằng mọi kỹ thuật và tạo mọi vị trí có

th ể và giải thích lý do ( Biết rằng n > 20, x,y,z là các số nguyên và các

hàm trong đoạn lệnh đã tối ưu)

for ( int i = 0 ; i < n ; i++ ) {

ra điểm gây lỗi

/*

* a_list là bi ến tổng thể

Trang 44

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 1

Y = [y1, y2, … , ym]

Sử dụng ngôn ngữ lập trình C/C++ để viết hàm … DiffSym(…) với :

Đầu vào : danh sách X và danh sách Y (và các tham số khác nếu cần …) Đầu ra : con trỏ đến danh sách Z; danh sách này bao gồm :

- Tất cả các số thuộc X và không thuộc Y

- Tất cả các số thuộc Y và không thuộc X

Bên cạnh đó, thông qua tham số truyền, gửi ra số phần tử của mảng kết quả Z Yêu cầu : phong cách lập trình thống nhất, chú thích đầy đủ, áp dụng các

k ĩ thuật viết mã nguồn hiểu quả, bẫy lỗi và lập trình phòng ngừa

Li ệt kê các kỹ thuật viết mã nguồn hiểu quả, bẫy lỗi và lập trình phòng ngừa đã áp dụng

Trang 45

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 1

Hãy xây dựng hàm (hoặc phương thức) Sort để sắp xếp danh sách theo thứ

tự tăng dần của info

Trang 46

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 2

“Khong bang nhau”

Quan sát đoạn lệnh dưới đây và chỉ ra tất cả các trường hợp in ra thông báo

Sửa lại đoạn lệnh cho đúng với yêu cầu đặt ra

Cho một số nguyên được biểu diễn dưới dạng nhị phân, cần viết một hàm

để tính số cặp bit liền kề (bit chẵn và lẻ) có giá trị khác nhau Ví dụ:

D ạng nhị phân của số 52 là “00 11 01 00”  hàm trả về giá trị 1 (chỉ có cặp bit 01 là cặp bit liền kề có giá trị khác nhau)

Dạng nhị phân của số 102 là “01 10 01 10”  hàm trả về giá trị 4 (có 4 cặp bit liền kề có giá trị khác nhau) Hãy chỉ ra các trường hợp hàm

oddeven() được định nghĩa dưới đây trả về kết quả sai ?

Trang 47

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 2

Hàm CompareFloats() dưới đây dùng để so sánh hai số thực x và y : Hàm

tr ả về giá trị dương nếu x > y, trả về giá trị 0 nếu x = y, trả về giá trị âm nếu

x < y Hãy ch ỉ ra các trường hợp sai sót của hàm và chỉnh sửa để hàm thực hiện đúng trong mọi trường hợp và cho kết quả hợp lý hơn

int CompareFloats(void *p1, void *p2) {

Trang 48

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 2

3

Câu 5 : (1 đ)

Hãy tinh ch ỉnh đoạn mã lệnh sau bằng mọi kỹ thuật và tạo mọi vị trí có

th ể và giải thích lý do (Biết rằng n > 20, x,y,z là các số nguyên và các

hàm trong đoạn lệnh đã tối ưu)

for ( int i = 0 ; i < n ; i++ ) {

Một lập trình viên chuyên nghiệp tiến hành tinh chỉnh chương trình

bằng cách sửa các đoạn khai báo : char MaTran [80][60]; thành

Cho a và b là hai mảng được cấp phát động với kích thước bằng đúng số

phần tử của mảng và chứa hai dãy các số thực A = [a1, a2, … , an] và

B = [b1, b2, … , bm]

Sử dụng ngôn ngữ lập trình C/C++ để viết hàm … DiffElem(…) với :

Đầu vào : danh sách A và danh sách B (và các tham số khác nếu cần …)

Trang 49

Đề thi môn Kĩ thuật lập trình – CNTT K52 (thày Vũ Đức Vượng) – Đề số 2

4

Đầu ra : con trỏ đến danh sách C; danh sách này bao gồm :

- Tất cả các số thuộc A và không thuộc B

- Tất cả các số thuộc B và không thuộc A

Bên cạnh đó, thông qua tham số truyền, gửi ra số phần tử của mảng kết quả C Yêu c ầu : phong cách lập trình thống nhất, chú thích đầy đủ, áp dụng các

k ĩ thuật viết mã nguồn hiểu quả, bẫy lỗi và lập trình phòng ngừa đã áp dụng Liệt kê các kỹ thuật viết mã nguồn hiểu quả, bẫy lỗi và lập trình phòng ngừa đã áp dụng

Hãy xây dựng hàm (hoặc phương thức) Sort để sắp xếp danh sách theo thứ

tự giảm dần của info

Ngày đăng: 08/01/2016, 17:27

TỪ KHÓA LIÊN QUAN

w