Xem mẫu
- Topics
cấu trúc, cấp phát động
Các
Các phép toán File trên bộ nhớ
tưởng tượng.
Bài tập
- Cấp phát động
Một mảng các biến đã được ấn định kích thước,
dùng để lưu trữ 1 lượng biến đã xác định (tại thời
điểm biên dịch).
Kích thước này sẽ không thể thay đổi sau khi
biên dịch.
Tuy nhiên chúng ta thường không biết trước
được số lượng không gian cần thiết cho mảng .
Vì vậy nên có thể sử dụng cấp phát bộ nhớ động
để khắc phục nhược điểm trên của mảng, tránh
lãng phí không gian nhớ.
- Hàm malloc
void * malloc(unsigned int nbytes);
Hàm malloc được sử dụng để cấp phát
động nbytes trong bộ nhớ.
malloc trả về con trỏ tới vùng nhớ
được cấp phát nếu thành công, trả về
con trỏ NULL nếu thất bại.
Nên kiểm tra xem có cấp phát thành
công hay không.
Phải #include
- Ví dụ - Đảo ngược mảng động
int main(void)
{
int i, n, *p;
printf(“Bạn muốn nhập bao nhiêu số ?\n");
scanf("%d", &n);
/* Cấp phát 1 mảng int với kích thước thích hợp */
p = (int *)malloc(n * sizeof(int));
if (p == NULL)
{
printf("Memory allocation failed!\n");
return 1;
}
- Ví dụ - Đảo ngược mảng động
int main(void)
{
...
/* Nhận các số từ bàn phím */
printf("Please enter numbers now:\n");
for (i = 0; i < n; i++)
scanf("%d", &p[i]);
/* Đưa ra theo thứ tự ngược lại*/
printf("The numbers in reverse order are \n");
for (i = n - 1; i >= 0; --i)
printf("%d ",p[i]);
printf("\n");
/* Giải phóng bộ nhớ */
free(p);
return 0;
}
- Tại sao phải ép kiểu
Việc ép kiểu:
p = (int *)malloc(n*sizeof(int));
Là cần thiết vì hàm malloc trả về kiểu void*:
void * malloc(unsigned int nbytes);
Kiểu void* chỉ 1 kiểu con trỏ chung, có thể
ép tới bất kì kiểu con trỏ nào.
- Giải phóng bộ nhớ đã được cấp phát
void free(void *ptr);
Ta sử dụng hàm free(p) để giải phóng
bộ nhớ đã được cấp phát được chỉ
đến bởi con trỏ p.
Nếu p không trỏ đến 1 vùng nhớ đã
được cấp phát bởi malloc, sẽ xảy ra
lỗi thi hành.
Luôn luôn phải nhớ giải phóng bộ nhớ
nếu không cần đến chúng nữa.
- Exercise 2.1
Tạo hàm my_strcat():
- Đầu vào: 2 xâu s1,s2
- Đầu ra: trả về con trỏ trỏ tới xâu nối của 2
xâu s1,s2 (được cấp phát động).
- Ví dụ: xâu nối của “hello_” and “world!” là:
“hello_world!”
• Test hàm của bạn.
- Solution my_strcat()
char *my_strcat(char *str1, char *str2)
{
int len1, len2;
char *result;
len1 = strlen(str1);
len2 = strlen(str2);
result = (char*)malloc((len1 + len2 + 1) *
sizeof(char));
if (result == NULL) {
printf(“cấp phát thất bại! Kiểm tra lại bộ nhớ!\n");
return NULL;
}
strcpy(result, str1);
strcpy(result + len1, str2);
return result;
}
- Solution main()
int main(void)
{
char str1[MAX_LEN + 1], str2[MAX_LEN + 1];
char *cat_str;
printf("Please enter two strings\n");
scanf("%100s", str1);
scanf("%100s", str2);
cat_str = my_strcat(str1, str2);
if (cat_str == NULL)
{
printf(“Xẩy ra lỗi trong quá trình cấp phát bộ nhớ!n");
return 1;
}
printf("The concatenation of %s and %s is %s\n", str1, str2, cat_str);
free(cat_str);
return 0;
}
- Các cấu trúc - kiểu được định nghĩa bởi
người dùng
1 tập các biến dưới cùng 1 tên đơn
Là
Là 1 cách thuận lợi để nhóm các thông tin
có liên quan tới nhau.
Các biến trong struct(cấu trúc) được gọi la
member (thành viên) hoặc field (trường)
- ĐỊnh nghĩa 1 cấu trúc
struct struct-name
{
field-type1 field-name1;
field-type2 field-name2;
field-type3 field-name3;
…
};
- Ví dụ - số phức
struct complex {
int real;//phần thực
int img;//phần ảo
};
struct complex num1,num2,num3;
- Typedef
có thể phối hợp typedef với định nghĩa
Ta
cấu trúc để định nghĩa 1 kiểu mới:
typedef struct complex {
int real;
int img;
} complex_t;
complex_t num1, num2;
- Exercise 2.2
Cho 2 cấu trúc sau:
typedef struct point //điểm trong mặt phẳng (2 toạ độ)
{
double x;
double y;
} point_t;
typedef struct circle //đường tròn
{
point_t center; //tâm
double radius; //bán kính
} circle_t;
Viết 1 hàm trả về giá trị 1 nếu điểm p nằm trong đường tròn c.
Test hàm bằng 1 chương trình.
- Solution
int is_in_circle(point_t *p, circle_t *c)
{
double x_dist, y_dist;
x_dist = p->x - c->center.x;
y_dist = p->y - c->center.y;
return (x_dist * x_dist + y_dist * y_dist
radius * c->radius);
}
- Solution
int main(void)
{
point_t p;
circle_t c;
printf(“Nhập toạ độ điểm\n");
scanf("%lf%lf", &p.x, &p.y);
printf(“nhập toạ độ tâm đường tròn \n");
scanf("%lf%lf", &c.center.x, &c.center.y);
printf(“Nhập bán kính \n");
scanf("%lf", &c.radius);
if (is_in_circle(&p, &c))
printf(“điểm nằm trong\n");
else
printf(“điểm nằm ngoài\n");
return 0;
}
- Con trỏ trong cấu trúc
Nếu 1 trường của cấu trúc là con trỏ, nó
có thể là con trỏ trỏ tới chính bản sao của
nó.
- Chế độ cho Binary file (file nhị fân)
chế độ Mô tả
Mở 1 file binary đã có để đọc
"rb"
Tạo 1 file binary để ghi
“wb”
Mở 1 file đã có để thêm dữ liệu vào cuối
“ab”
Mở 1 file binary đã có để đọc hoặc ghi
“r+b”
Tạo 1 file binary để đọc hoặc ghi
"w+b“
Tạo mới hoặc mở 1 file đã có để thêm dữ
"a+b"
liệu vào cuối
- Quản lí file: làm việc với 1 khối dữ liệu
hàm vào/ra là fread() và fwrite() có thể
2
dùng để thực hiện các thao tác với khối
dữ liệu.
Như các hàm quản lí file khác, chúng làm
việc với con trỏ file.
nguon tai.lieu . vn