Thực Nghiệm Lập Trình C: Xử Lý Mảng, Chuỗi và Con Trỏ

Thực Nghiệm 1

1.1

 1 #include <stdio.h>
 2 #define SO_LUONG 5
 3 
 4 void nhap_mang(int du_lieu[], int kich_thuoc);
 5 void xuat_mang(int du_lieu[], int kich_thuoc);
 6 tim_gia_tri_trung_binh(int du_lieu[], int kich_thuoc, int *nho_nhat, int *lon_nhat);
 7 
 8 int main() {
 9     int mang[SO_LUONG];
10     int min, max;
11 
12     printf("Nhập %d số nguyên:\n", SO_LUONG);
13     nhap_mang(mang, SO_LUONG);
14 
15     printf("Các số đã nhập: \n");
16     xuat_mang(mang, SO_LUONG);
17 
18     printf("Đang xử lý dữ liệu...\n");
19     tim_gia_tri_trung_binh(mang, SO_LUONG, &min, &max);
20 
21     printf("Kết quả:\n");
22     printf("Giá trị nhỏ nhất = %d, Giá trị lớn nhất = %d\n", min, max);
23 
24     return 0;
25 }
26 
27 void nhap_mang(int du_lieu[], int kich_thuoc) {
28     int i;
29 
30     for(i = 0; i < kich_thuoc; ++i)
31         scanf("%d", &du_lieu[i]);
32 }
33 
34 void xuat_mang(int du_lieu[], int kich_thuoc) {
35     int i;
36     
37     for(i = 0; i < kich_thuoc; ++i)
38         printf("%d ", du_lieu[i]);
39     printf("\n");
40 }
41 
42 tim_gia_tri_trung_binh(int du_lieu[], int kich_thuoc, int *nho_nhat, int *lon_nhat) {
43     int i;
44     
45     *nho_nhat = *lon_nhat = du_lieu[0];
46 
47     for(i = 0; i < kich_thuoc; ++i)
48         if(du_lieu[i] < *nho_nhat)
49             *nho_nhat = du_lieu[i];
50         else if(du_lieu[i] > *lon_nhat)
51             *lon_nhat = du_lieu[i];
52 }

1.11. Hàm tim_gia_tri_trung_binh có chức năng: tìm giá trị nhỏ nhất và lớn nhất trong mảng du_lieu, và lưu địa chỉ của chúng vào nho_nhat và lon_nhat.

  1. Cả hai con trỏ đều trỏ đến địa chỉ của phần tử đầu tiên du_lieu[0].

1.2

 1 #include <stdio.h>
 2 #define SO_LUONG 5
 3 
 4 void nhap_mang(int du_lieu[], int kich_thuoc);
 5 void xuat_mang(int du_lieu[], int kich_thuoc);
 6 int *tim_max(int du_lieu[], int kich_thuoc);
 7 
 8 int main() {
 9     int mang[SO_LUONG];
10     int *chi_so_max;
11 
12     printf("Nhập %d số nguyên:\n", SO_LUONG);
13     nhap_mang(mang, SO_LUONG);
14 
15     printf("Các số đã nhập: \n");
16     xuat_mang(mang, SO_LUONG);
17 
18     printf("Đang xử lý dữ liệu...\n");
19     chi_so_max = tim_max(mang, SO_LUONG);
20 
21     printf("Kết quả:\n");
22     printf("Giá trị lớn nhất = %d\n", *chi_so_max);
23 
24     return 0;
25 }
26 
27 void nhap_mang(int du_lieu[], int kich_thuoc) {
28     int i;
29 
30     for(i = 0; i < kich_thuoc; ++i)
31         scanf("%d", &du_lieu[i]);
32 }
33 
34 void xuat_mang(int du_lieu[], int kich_thuoc) {
35     int i;
36     
37     for(i = 0; i < kich_thuoc; ++i)
38         printf("%d ", du_lieu[i]);
39     printf("\n");
40 }
41 
42 int *tim_max(int du_lieu[], int kich_thuoc) {
43     int vi_tri_max = 0;
44     int i;
45 
46     for(i = 0; i < kich_thuoc; ++i)
47         if(du_lieu[i] > du_lieu[vi_tri_max])
48             vi_tri_max = i;
49     
50     return &du_lieu[vi_tri_max];
51 }

1.21. Hàm tim_max có chức năng: tìm phần tử có giá trị lớn nhất trong mảng du_lieu và trả về địa chỉ của phần tử đó cho biến con trỏ chi_so_max trong hàm main.

  1. Có thể. Hàm có thể trả về địa chỉ của phần tử lớn nhất trong mảng.

Thực Nghiệm 2

2.1

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define KICH_THUOC 80
 4 
 5 int main() {
 6     char chuoi1[KICH_THUOC] = "Học tập khiến tôi vui vẻ";
 7     char chuoi2[KICH_THUOC] = "Học tập khiến tôi buồn ngủ";
 8     char tam[KICH_THUOC];
 9 
10     printf("Kích thước chuoi1 vs. độ dài chuoi1: \n");
11     printf("sizeof(chuoi1) = %d\n", sizeof(chuoi1));
12     printf("strlen(chuoi1) = %d\n", strlen(chuoi1));
13 
14     printf("\nTrước khi hoán đổi: \n");
15     printf("Chuoi1: %s\n", chuoi1);
16     printf("Chuoi2: %s\n", chuoi2);
17 
18     printf("\nĐang hoán đổi...\n");
19     strcpy(tam, chuoi1);
20     strcpy(chuoi1, chuoi2);
21     strcpy(chuoi2, tam);
22 
23     printf("\nSau khi hoán đổi: \n");
24     printf("Chuoi1: %s\n", chuoi1);
25     printf("Chuoi2: %s\n", chuoi2);
26 
27     return 0;
28 }

2.1Câu hỏi 1: Mảng chuoi1 có 24 ký tự, kích thước tổng byte là 80. sizeof(chuoi1) tính tổng số byte chiếm bởi mảng chuoi1, strlen(chuoi1) tính độ dài chuoi1 không bao gồm ký tự '\0'.

Câu hỏi 2: Không thể. Mảng ký tự không thể gán trực tiếp bằng toán tử gán (=), tên mảng là một hằng số địa chỉ.

Câu hỏi 3: Đúng.

2.2

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define KICH_THUOC 80
 4 
 5 int main() {
 6     char *chuoi1 = "Học tập khiến tôi vui vẻ";
 7     char *chuoi2 = "Học tập khiến tôi buồn ngủ";
 8     char *tam;
 9 
10     printf("Kích thước chuoi1 vs. độ dài chuoi1: \n");
11     printf("sizeof(chuoi1) = %d\n", sizeof(chuoi1));
12     printf("strlen(chuoi1) = %d\n", strlen(chuoi1));
13 
14     printf("\nTrước khi hoán đổi: \n");
15     printf("Chuoi1: %s\n", chuoi1);
16     printf("Chuoi2: %s\n", chuoi2);
17 
18     printf("\nĐang hoán đổi...\n");
19     tam = chuoi1;
20     chuoi1 = chuoi2;
21     chuoi2 = tam;
22 
23     printf("\nSau khi hoán đổi: \n");
24     printf("Chuoi1: %s\n", chuoi1);
25     printf("Chuoi2: %s\n", chuoi2);
26 
27     return 0;
28 }

1.2Câu hỏi 1: chuoi1 lưu địa chỉ bắt đầu của chuỗi hằng "Học tập khiến tôi vui vẻ" trong bộ nhớ. sizeof(chuoi1) tính kích thước của biến con trỏ chuoi1. strlen(chuoi1) tính số ký tự trong chuỗi không bao gồm ký tự '\0'.

Câu hỏi 2: Có thể. Trong 2.1, chúng ta gán chuỗi hằng cho tên mảng, trong khi 2.2 chúng ta gán địa chỉ khởi tạo của chuỗi cho con trỏ chuoi1.

Câu hỏi 3: Chúng ta hoán đổi địa chỉ của hai chuỗi hằng. Nội dung chuỗi không thực sự bị hoán đổi.

Thực Nghiệm 3

3ptr1 được khởi tạo là &x[0][0], truy cập tuần tự các phần tử trong mảng x.

ptr2 được khởi tạo là địa chỉ bắt đầu của hàng 0, *(*ptr2+j) là cách truy cập phần tử thứ j của mỗi hàng.

Thực Nghiệm 4

 1 #include <stdio.h>
 2 #define KICH_THUOC 80
 3 
 4 void thay_ky_tu(char *chuoi, char ky_tu_cu, char ky_tu_moi); // Khai báo hàm
 5 
 6 int main() {
 7     char van_ban[KICH_THUOC] = "Lập trình có khó hay không, đó là một câu hỏi.";
 8 
 9     printf("Văn bản gốc: \n");
10     printf("%s\n", van_ban);
11 
12     thay_ky_tu(van_ban, 'i', '*'); // Gọi hàm, chú ý cách viết tham số ký tự, không thể thiếu dấu nháy đơn
13 
14     printf("Văn bản sau khi xử lý: \n");
15     printf("%s\n", van_ban);
16 
17     return 0;
18 }
19 
20 // Định nghĩa hàm
21 void thay_ky_tu(char *chuoi, char ky_tu_cu, char ky_tu_moi) {
22     int i;
23 
24     while(*chuoi) {
25         if(*chuoi == ky_tu_cu)
26             *chuoi = ky_tu_moi;
27         chuoi++;
28     }
29 }

4Câu hỏi 1: Thay thế tất cả các ký tự cũ trong chuỗi bằng ký tự mới.

Câu hỏi 2: Có thể.

Thực Nghiệm 5

 1 #include <stdio.h>
 2 #define KICH_THUOC 80
 3 
 4 char *cat_chuoi(char *chuoi, char x);
 5 
 6 int main() {
 7     char chuoi[KICH_THUOC];
 8     char ky_tu;
 9 
10     while(printf("Nhập chuỗi: "), gets(chuoi) != NULL) {
11         printf("Nhập một ký tự: ");
12         ky_tu = getchar();
13 
14         printf("Đang cắt chuỗi...\n");
15         cat_chuoi(chuoi, ky_tu);         
16 
17         printf("Chuỗi sau khi cắt: %s\n\n", chuoi);
18         getchar();
19     }
20 
21     return 0;
22 }
23 
24 char *cat_chuoi(char *chuoi, char x){
25     while(*chuoi){
26         if ( *chuoi == x)
27             *chuoi='\0';
28         chuoi++;
29     }
30     return chuoi; 
31 }

Thực Nghiệm 5Dòng 18 nhận ký tự xuống dòng để đảm bảo vòng lặp tiếp theo có thể nhập chuỗi đúng cách.

Thực Nghiệm 6

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define SO_LUONG 5
 4 
 5 int kiem_tra_so_cmnd(char *str);
 6 
 7 int main()
 8 {
 9     char *cmnd[SO_LUONG] = {"31010120000721656X",
10                     "3301061996X0203301",
11                     "53010220051126571",
12                     "510104199211197977",
13                     "53010220051126133Y"};
14     int i;
15 
16     for (i = 0; i < SO_LUONG; ++i)
17         if (kiem_tra_so_cmnd(cmnd[i]))
18             printf("%s\tHợp lệ\n", cmnd[i]);
19         else
20             printf("%s\tKhông hợp lệ\n", cmnd[i]);
21 
22     return 0;
23 }
24 
25 int kiem_tra_so_cmnd(char *str) {
26     if(strlen(str) != 18)
27         return 0;
28     for (int j=0;j<17;++j){
29         if(str[j]<'0'||str[j]>'9')
30             return 0;
31     }
32     if (!(str[17]>='0'&&str[17]<='9')&&(str[17] !='X'))
33         return 0;
34     
35     return 1;
36 }

Thực Nghiệm 6Thực Nghiệm 7

 1 #include <stdio.h>
 2 #define KICH_THUOC 80
 3 void ma_hoa(char *str, int n); // Khai báo hàm
 4 void gia_ma(char *str, int n); // Khai báo hàm
 5 
 6 int main() {
 7     char van_ban[KICH_THUOC];
 8     int n;
 9 
10     printf("Nhập văn bản tiếng Anh: ");
11     gets(van_ban);
12 
13     printf("Nhập n: ");
14     scanf("%d", &n);
15 
16     printf("Văn bản sau khi mã hóa: ");
17     ma_hoa(van_ban, n);      // Gọi hàm
18     printf("%s\n", van_ban);
19 
20     printf("Giải mã văn bản đã mã hóa: ");
21     gia_ma(van_ban, n); // Gọi hàm
22     printf("%s\n", van_ban);
23 
24     return 0;
25 }
26 
27 /*Định nghĩa hàm
28 Chức năng: mã hóa chuỗi trỏ bởi str
29 Quy tắc mã hóa:
30 Đối với ký tự từ a~z hoặc A~Z, thay bằng ký tự đứng sau nó n vị trí; các ký tự không phải chữ cái, giữ nguyên
31 */
32 void ma_hoa(char *str, int n) {
33     n=n%26;
34     if(n<0)
35         n+=26;
36     while(*str){
37         if((*str>='a'&&*str<='z')||(*str>='A'&&*str<='Z')){
38             if(*str>='a'&&*str<='z'){
39                 *str='a'+(*str-'a'+n)%26;
40             }
41             else
42                 *str='A'+(*str-'A'+n)%26;
43         }
44         str++;
45     }
46     
47 }
48 
49 /*Định nghĩa hàm
50 Chức năng: giải mã chuỗi trỏ bởi str
51 Quy tắc giải mã:
52 Đối với ký tự từ a~z hoặc A~Z, thay bằng ký tự đứng trước nó n vị trí; các ký tự không phải chữ cái, giữ nguyên
53 */
54 void gia_ma(char *str, int n) {
55     n=n%26;
56     if(n<0)
57         n+=26;
58     while(*str){
59         if((*str>='a'&&*str<='z')||(*str>='A'&&*str<='Z')){
60             if(*str>='a'&&*str<='z'){
61                 *str='a'+(*str-'a'-n+26)%26;
62             }
63             else
64                 *str='A'+(*str-'A'-n+26)%26;
65         }
66         str++;
67     }
68 }

Thực Nghiệm 7Thực Nghiệm 8

 1 #include <stdio.h>
 2 #include <string.h>
 3  
 4 int main(int argc, char *argv[]) {
 5     int i, j;
 6     char *temp;
 7      
 8     for (i = 1; i < argc - 1; ++i) {
 9         for (j = 1; j < argc - i; ++j) {
10             if (strcmp(argv[j], argv[j+1]) > 0) {
11                 temp = argv[j];
12                 argv[j] = argv[j+1];
13                 argv[j+1] = temp;
14             }
15         }
16     }
17     for (i = 1; i < argc; ++i) {
18         printf("chào, %s\n", argv[i]);
19     }
20     return 0;
21 }

Mã đã chỉnh sửa

Thẻ: C lập trình con trỏ mạng chuỗi

Đăng vào ngày 17 tháng 6 lúc 02:20