Mong nhận được giải đáp - Nhập môn lập trình

Trong đề thi cuối kì NMLT 2014-2015 em có thấy câu hỏi này
**Đề bài: Cho biết kết quả chương trình sau và giải thích tại sao lại có kết quả như vậy? **

void hamf(int *a)
{
for(int i=0;i<5;i++)
a*=i+1;
}
void main()
{
int a[]={5,4,3,2,1};
hamf(a);
printf("Gia tri a[0]=%d",a[0]);
}

Anh chị nào biết trả lời có thể giúp em được không ạ :unhappy: Em cảm ơn anh (chị) nhiều ạ!

Giải thích trên này hơn khó.
Em xem video này nha.
https://www.youtube.com/watch?v=ASVB8KAFypk
Hi vọng có thể giúp được em.
Em có thể tìm hiểu thêm về con trỏ qua những video giải thích trực quan như vậy.
Chúc em học tốt.
p/s: ngày xưa năm 2 anh mới được học con trỏ, còn mơ hồ cái này lắm, giờ thì quên hết rồi =)) xem xong giải thích lại cho anh với nhé :slight_smile:

Vì hamf có đối số là một kiểu tham chiếu, nghĩa là nó sẽ thao tác trên địa chỉ của đối số mà nó được truyền vào. Nếu không có gì bí ẩn ở đây thì anh nghĩ chương trình sẽ in ra: Gia tri a[0]=1

Mà chốt lại thì sau khi thực hiện hamf thì a = {1, 2, 3, 4, 5};

Nếu có gì sai thì bỏ qua cho anh, lâu rồi không đụng tới C nữa nên cũng không chắc lắm.

trong cái ví dụ của chú thì cái mảng a nó đẩy qua cái hàm, mà cái hàm đó đối số là 1 con trỏ kiểu int (giống như mảng a), thì lúc đó chú mày truy cập các phần tử của cái mảng đó thông qua index của mảng hay con trỏ đều đc. Cái mảng đó nó sẽ đc gán giá trị mới là i+1 với i chạy từ 0 -> 4 => mảng sẽ là 1 -> 5.
để giải thích thêm 1 ví dụ nho nhỏ cho chú mày dễ hình dung

#include <iostream>
using std::cout;
int main()
{
int a[] = {3, 2, 1}; // khai bao mang a co 3 phan tu 1,2,3
int *p = a; // khai bao con tro p kieu int tro den mang a
for (int i = 0; i < 3; i++)
cout << a* << " ";
cout << "
";
for (int i = 0; i < 3; i++)
cout << p* << " ";
cout << "
";
for (int i = 0; i < 3; i++)
cout << *(a + i) << " ";
cout << "
";
for (int i = 0; i < 3; i++)
cout << *(p + i) << " ";
return 0; //ngam dinh chuong trinh chay thanh cong
}

như ví dụ trên, khi trỏ con trỏ p đến mảng a như trên thì chú muốn xuất các phần tử của nó theo index hay offset đằng sau cũng đều ok.
4 dòng cout trên sẽ cho ra cùng kết quả
//má tính post bài mới mà bấm nhầm edit đè bài cũ mất =))

[QUOTE=12520034;362608]Giải thích trên này hơn khó.
Em xem video này nha.
https://www.youtube.com/watch?v=ASVB8KAFypk
Hi vọng có thể giúp được em.
Em có thể tìm hiểu thêm về con trỏ qua những video giải thích trực quan như vậy.
Chúc em học tốt.
p/s: ngày xưa năm 2 anh mới được học con trỏ, còn mơ hồ cái này lắm, giờ thì quên hết rồi =)) xem xong giải thích lại cho anh với nhé :)[/QUOTE]
Em cảm ơn anh nhiều ạ! <3

[QUOTE=11520537;362610]Vì hamf có đối số là một kiểu tham chiếu, nghĩa là nó sẽ thao tác trên địa chỉ của đối số mà nó được truyền vào. Nếu không có gì bí ẩn ở đây thì anh nghĩ chương trình sẽ in ra: Gia tri a[0]=1

Mà chốt lại thì sau khi thực hiện hamf thì a = {1, 2, 3, 4, 5};

Nếu có gì sai thì bỏ qua cho anh, lâu rồi không đụng tới C nữa nên cũng không chắc lắm.[/QUOTE]
Dạ em cảm ơn! <3

[QUOTE=11520201;362611]trong cái ví dụ của chú thì cái mảng a nó đẩy qua cái hàm, mà cái hàm đó đối số là 1 con trỏ kiểu int (giống như mảng a), thì lúc đó chú mày truy cập các phần tử của cái mảng đó thông qua index của mảng hay con trỏ đều đc. Cái mảng đó nó sẽ đc gán giá trị mới là i+1 với i chạy từ 0 -> 4 => mảng sẽ là 1 -> 5.
để giải thích thêm 1 ví dụ nho nhỏ cho chú mày dễ hình dung

#include <iostream>
using std::cout;
int main()
{
int a[] = {3, 2, 1}; // khai bao mang a co 3 phan tu 1,2,3
int *p = a; // khai bao con tro p kieu int tro den mang a
for (int i = 0; i < 3; i++)
cout << a* << " ";
cout << "
";
for (int i = 0; i < 3; i++)
cout << p* << " ";
cout << "
";
for (int i = 0; i < 3; i++)
cout << *(a + i) << " ";
cout << "
";
for (int i = 0; i < 3; i++)
cout << *(p + i) << " ";
return 0; //ngam dinh chuong trinh chay thanh cong
}

như ví dụ trên, khi trỏ con trỏ p đến mảng a như trên thì chú muốn xuất các phần tử của nó theo index hay offset đằng sau cũng đều ok.
4 dòng cout trên sẽ cho ra cùng kết quả
//má tính post bài mới mà bấm nhầm edit đè bài cũ mất =))[/QUOTE]
Em cảm ơn tiền bối nhiều nhiều ạ! :v <3

[QUOTE=11520537;362610]Vì hamf có đối số là một kiểu tham chiếu, nghĩa là nó sẽ thao tác trên địa chỉ của đối số mà nó được truyền vào. Nếu không có gì bí ẩn ở đây thì anh nghĩ chương trình sẽ in ra: Gia tri a[0]=1
Mà chốt lại thì sau khi thực hiện hamf thì a = {1, 2, 3, 4, 5};
Nếu có gì sai thì bỏ qua cho anh, lâu rồi không đụng tới C nữa nên cũng không chắc lắm.[/QUOTE]
Hàm f có đối số là kiểu con trỏ, chứ ko phải kiểu tham chiếu nha bạn, đừng nhầm lẫn 2 cái đó. Kiểu con trỏ là làm việc thông qua trung gian là vùng nhớ của biến truyền vào. Con trỏ chỉ có chức năng lưu giữ địa chỉ vùng nhớ.
Còn kiểu tham chiếu là làm việc trực tiếp trên vùng nhớ của biến số truyền vào.
2 kiểu mang 2 ý nghĩa khác nhau mặc dù ở chức năng của hàm trên thì cho ra cùng 1 kết quả. Tuy nhiên ở 1 số hàm khác thì nó ko giống nhau đâu nhé.
[QUOTE=16520259;362606]Trong đề thi cuối kì NMLT 2014-2015 em có thấy câu hỏi này
**Đề bài: Cho biết kết quả chương trình sau và giải thích tại sao lại có kết quả như vậy? **

void hamf(int *a)
{
for(int i=0;i<5;i++)
a*=i+1;
}
void main()
{
int a[]={5,4,3,2,1};
hamf(a);
printf("Gia tri a[0]=%d",a[0]);
}

Anh chị nào biết trả lời có thể giúp em được không ạ :unhappy: Em cảm ơn anh (chị) nhiều ạ![/QUOTE]
Ở đây đề thi thử khả năng hiểu biết của bạn về con trỏ (pointer). Mảng là 1 biến đặc biệt (con trỏ hằng - là 1 dạng con trỏ nhưng chỉ lưu trữ 1 vùng nhớ cố định) nên muốn thao tác nó trong hàm khác thì một là truyền thẳng tên mảng đó vào trong hàm (nó là con trỏ hằng nên đương nhiên nó có tính năng của con trỏ) hoặc hai là dùng con trỏ bình thường lưu địa chỉ của mảng đó khi truyền vào.
Nếu sử dụng cách thứ nhất thì khi khai báo đối số của hàm bạn phải khai báo biến truyền vào là kiểu mảng. Và tại nơi bạn gọi hàm đó ra thì tham số truyền vào là tên mảng đó.
Nếu sử dụng cách thứ hai thì khi khai báo đối số của hàm bạn phải khai báo biến truyền vào là kiểu con trỏ. Và tại nơi bạn gọi hàm đó ra thì tham số truyền vào là địa chỉ của mảng đó (vì là mảng nên địa chỉ của mảng cũng là tên của mảng đó luôn).

Anh [MENTION=20699]12520971[/MENTION] đẹp trai quá.
Em cảm ơn anh ạ :beauty:

[QUOTE=12520332;362625]Anh [MENTION=20699]12520971[/MENTION] đẹp trai quá.
Em cảm ơn anh ạ :beauty:[/QUOTE]
sodesuka?
douitashimashite.