Từ 1 tới 9 trên tổng số 9 kết quả

Đề tài: initializing argument 5 of `int search(void*, int, int, int, void*, int (*)(void*, void*))'tìm kiếm nhị phân

  1. #1
    Ngày gia nhập
    01 2012
    Bài viết
    8

    Question initializing argument 5 of `int search(void*, int, int, int, void*, int (*)(void*, void*))'tìm kiếm nhị phân

    Đề bài: Tìm kiếm nhị phân trong 1 mảng cho trước tăng dần có sử dụng hàm tìm kiếm tổng quát(nghĩa là hàm truyền dữ liệu qua địa chỉ và kích cỡ)

    Code:
    #include<stdio.h>
    int int_compare(void *x,void *y)//Hàm so sánh 2 số
    {
    	int m,n;
    	m= *((int *)x);
    	n= *((int *)y);
    	if(m==n)return 0;
    	return m>n?1:-1;
    }
    int search(void *buf,int size,int l,int r,void *item,int (*compare)(void *,void *))//hàm tìm kiếmtổng quát
    {
    	if(r<l)return -1;
    	int i=(l+r)/2;
    	int res=compare(item,(char *)buf+(size*i));
    	if (res==0)return i;
    	else if(res<0)return search(buf,size,l,i-1,item,compare);
    	else return search(buf,size,i+1,r,item,compare);
    }
    int main()
    {
    	int a[]={1,5,7,9,11,15,20},n=7,item=15;
    	int i,res;
    	res= search(a,sizeof(int),0,n-1,item,int_compare);
    	if (res==-1)printf("Khong tim thay\n");
    	else printf("Da tim thay\n");
    	return 0;
    }
    mình sử dụng cfree5.0 để code. Và nó có 2 lỗi như này:

    [Error] C:\Users\dienkun\Documents\C-Free\Temp\Untitled3.cpp:23: error: invalid conversion from `int' to `void*'
    [Error] C:\Users\dienkun\Documents\C-Free\Temp\Untitled3.cpp:23: error: initializing argument 5 of `int search(void*, int, int, int, void*, int (*)(void*, void*))'
    Mong các bạn giúp đỡ

  2. #2
    Ngày gia nhập
    05 2011
    Bài viết
    299

    res= search(a,sizeof(int),0,n-1,item,int_compare);
    biến a ở hàm main kiểu gì?. ở hàm search kiểu gì?
    biến item ở hàm search ngoài hàm main có kiểu gì, trong hàm main kiểu gì?
    Programming tutorials and source code examples

    Trong nhà không vợ không con
    Uống bia gặm thịt sao ngon thế này
    Nhậu nhẹt không bị la rầy
    Một tuần ta cứ bảy ngày " nâng ly "....

  3. #3
    Ngày gia nhập
    01 2012
    Bài viết
    8

    Trích dẫn Nguyên bản được gửi bởi rossoneri Xem bài viết
    res= search(a,sizeof(int),0,n-1,item,int_compare);
    biến a ở hàm main kiểu gì?. ở hàm search kiểu gì?
    biến item ở hàm search ngoài hàm main có kiểu gì, trong hàm main kiểu gì?
    Thầy mình có nói :
    -Lập trình tổng quát là phương pháp tạo ra các đoạn chương trình tổng quát cho phép dễ dàng sử dụng lại trong nhiều bài toán khác nhau.
    -Trong hàm tổng quát , dữ liệu cần truyền theo cách tổng quát (qua địa chỉ và kích cỡ)
    -Hàm tổng quát cần được truyền qua các tham số sau
    + void *buf : địa chỉ các buffer chứa dữ liệu của mảng
    + int size : kích thước 1 phần tử trong mảng
    + int total :số các phần tử của mảng.

    Nên mình sử dụng kiểu void * để có thể nhập được kiểu khác như float .

  4. #4
    Ngày gia nhập
    10 2011
    Bài viết
    552

    1)void * thì mặc void * nhưng biến item ở main kiểu gì ? Định nghĩa hàm tại vị trí tham số đó kiểu gì ??

    2)Hàm int_compare hàm kiểu gì và ở định nghĩa hàm search tham số cuối cùng là hàm kiểu gì
    Um Mani Padme Hum...!!

  5. #5
    Ngày gia nhập
    11 2010
    Bài viết
    589

    Code:
    #include<stdio.h>
    int int_compare(void *x,void *y)//Hàm so sánh 2 số
    {
    	int m,n;
    	m= *((int *)x);
    	n= *((int *)y);
    	if(m==n)return 0;
    	return m>n?1:-1;
    }
    
    int search(void *buf,int size,int l,int r,void *item,int (*compare)(void *,void *))//hàm tìm kiếmtổng quát
    {
    	if(r<l)return -1;
    	int i=(l+r)/2;
    	int res=compare(item,(char *)buf+(size*i));
    	if (res==0)return i;
    	else if(res<0)return search(buf,size,l,i-1,item,compare);
    	else return search(buf,size,i+1,r,item,compare);
    }
    int main()
    {
    	int a[]={1,5,7,9,11,15,20},n=7,item=15;
    	int i,res;
    	res= search(a,sizeof(int),0,n-1,item,int_compare);
    	if (res==-1)printf("Khong tim thay\n");
    	else printf("Da tim thay\n");
    	return 0;
    }
    item trong hàm yêu cầu là void* mà bạn lại đem vào int nên có lỗi.

    Nên sửa lại đoạn này:
    Code:
    search(a,sizeof(int),0,n-1,item,int_compare);
    thành:
    C Code:
    1. search(a,sizeof(int),0,n-1,(void*)&item,int_compare);

    Nhìn cái tên file và cách khai báo biến thì có vẻ bạn đang viết C++ chứ không phải C, vậy tại sao không dùng C++ template + function object trong trường hợp này mà phải dùng void*.

  6. #6
    Ngày gia nhập
    01 2012
    Bài viết
    8

    Mặc định initializing argument 5 of `int search(void*, int, int, int, void*, int (*)(void*, void*))'tìm kiếm nhị phân

    @boss14420 : Không mình đang học lập trình C nâng cao @@, chưa học C++ đâu. Thầy mình cho lý thuyết chỉ như thế kia (mình đã viết ở trên) và 1 ví dụ bị lỗi (là đoạn mã code) . Mình cũng chẳng hiểu tại sao phải làm vậy nữa. Mình đang cố sửa code để có được 1 chương trình lấy làm mẫu. Cảm ơn bạn đã chữa lỗi cho mình.

  7. #7
    Ngày gia nhập
    11 2010
    Bài viết
    589

    Trích dẫn Nguyên bản được gửi bởi dienkun Xem bài viết
    @boss14420 : Không mình đang học lập trình C nâng cao @@, chưa học C++ đâu. Thầy mình cho lý thuyết chỉ như thế kia (mình đã viết ở trên) và 1 ví dụ bị lỗi (là đoạn mã code) . Mình cũng chẳng hiểu tại sao phải làm vậy nữa. Mình đang cố sửa code để có được 1 chương trình lấy làm mẫu. Cảm ơn bạn đã chữa lỗi cho mình.
    C nâng cao mà file mã nguồn lại là .cpp à ?

    Từ sau bạn nên để tên file là .c chứ không nên để .cpp nữa, vì lúc này C-Free sẽ dùng trình dịch của C để dịch mã nguồn thay vì trình dịch C++. Ngôn ngữ C++ và C có rất nhiều điểm không tương thích với nhau, nếu cứ dùng lẫn lộn thế này thì sau này không phân biệt được đâu là C đâu là C++ đâu.
    Điển hình như trong code của bạn có đoạn:
    Code:
    int search(void *buf,int size,int l,int r,void *item,int (*compare)(void *,void *))//hàm tìm kiếmtổng quát
    {
    	if(r<l)return -1;
    	int i=(l+r)/2;
    	int res=compare(item,(char *)buf+(size*i));
    	if (res==0)return i;
    	else if(res<0)return search(buf,size,l,i-1,item,compare);
    	else return search(buf,size,i+1,r,item,compare);
    }
    Ngôn ngữ C (C89) không cho phép khai báo biến tùy ý như thế này mà phải khai báo đầu khối lệnh. C99 thì cho phép nhưng đa số trình dịch hiện nay chưa hỗ trợ đầy đủ C99 nên vẫn dùng C89 là nhiều.

    Về lý do phải sử dụng void*: con trỏ void* là con trỏ có thể chuyển đổi qua lại với mọi kiểu con trỏ khác như (int*), (float*) ... nên khi muốn tạo một hàm có thể dùng được nhiều kiểu dữ liệu thì người ta sử dụng void* làm kiểu dữ liệu trung gian để chuyển về kiểu dữ liệu cần dùng.

    VD: với hàm search, trong code của bạn sử dụng với kiểu int nhưng bây giờ muốn dùng với mảng short thì chỉ cần viết thêm hàm so sánh hai số short:
    C Code:
    1. int short_compare(void *x,void *y)//Hàm so sánh 2 số
    2. {
    3.     short m,n;
    4.     m= *((short *)x);
    5.     n= *((short *)y);
    6.     if(m==n)return 0;
    7.     return m>n?1:-1;
    8. }
    Là có thể tìm kiểm trong mảng short bình thường:
    C Code:
    1. search(a,sizeof(short),0,n-1,(void*)&item,short_compare);

  8. #8
    Ngày gia nhập
    01 2012
    Bài viết
    8

    Hì cảm ơn bạn. Bạn nói làm mình cũng hiểu gần hết rồi . ^^!. Bạn cho mình hỏi thêm đoạn mã
    Code:
    int search(void *buf,int size,int l,int r,void *item,int (*compare)(void *,void *))
    Tại sao lại dùng int (*compare)(void *,void *) .Nếu mình dùng int *compare(void *,void *) liệu có được không?Tại sao?

    Nếu mình dùng int compare(void *,void *) liệu có được không?Tại sao?

    Mình thấy hàm
    Code:
    int  /* Không có dấu *  */ int_compare(void *x,void *y)
    nhưng tại sao khi khai báo sử dụng hàm so sánh
    Code:
    int search(void *buf,int size,int l,int r,void *item,int (*compare)(void *,void *))
    lại có dấu *

  9. #9
    Ngày gia nhập
    11 2010
    Bài viết
    589

    int (*compare)(void *,void *) là khai báo một con trỏ hàm tên là compare trả về int và nhận 2 đối số void* làm tham số một hàm nào đó
    int *compare(void *,void *) là khai báo một hàm trả về int* nhận 2 đối số void*
    2 cái này khác nhau hoàn toàn.
    Ta phải dùng khai báo con trỏ hàm bởi vì kiểu dữ liệu đầu vào lúc định nghĩa hàm search là chưa xác định được, do đó tiêu chí so sánh 2 số cũng chưa thể xác định. Con trỏ hàm compare làm nhiệm vụ đó. Tùy vào dữ liệu đầu vào thuộc kiểu nào mà dùng con trỏ hàm tương ứng.

    Đây là bài khá đầy đủ về con trỏ hàm: http://diendan.congdongcviet.com/showthread.php?t=25204

Các đề tài tương tự

  1. Kỹ thuật C Sự khác nhau giữa khai báo void main(), int main(void) và int main(int argv, char *argc[])?
    Gửi bởi v_huster38 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 21-11-2013, 12:10 PM
  2. [Error] cannot convert 'sanpham' to 'sanpham*' for argument '1' to 'void nhap(sanpham*, int)'
    Gửi bởi baman1234 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 4
    Bài viết cuối: 14-03-2013, 08:04 PM
  3. điểm khác nhau giữa hàm void abc(int a) và void abc (int &a ) là gì?
    Gửi bởi phuongnd trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 7
    Bài viết cuối: 06-04-2011, 10:51 AM
  4. Lỗi error LNK2005: "public: void __thiscall binary::nhap(void)"?
    Gửi bởi withlovei trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 3
    Bài viết cuối: 23-02-2011, 09:13 PM
  5. cannot convert float(*)[] to float* for argument '1' to void
    Gửi bởi vanphamvn trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 10-12-2008, 05:12 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn