Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 15 kết quả

Đề tài: Hỏi về lỗi của VC

  1. #1
    Ngày gia nhập
    02 2008
    Bài viết
    14

    Mặc định Hỏi về lỗi của VC

    Chào mọi người!

    Em vốn có nhiều thắc mắc đã lâu. Hôm nay mới được biết có diễn đàn Cviet nên phải hỏi bằng hết hì hì...
    Đây là mã nguồn bài "Tổng 2 số nguyên lớn"
    PHP Code:
    #include<voidlib.cpp>
    void main()
    {

        
    char *s;
        
    int j=0,i=0len1len2;
        
    int *arr1, *arr2;
        
    int k=0,store,result,max;
        
    int Aresult[90];
        
    printf("Input the first number: ");gets(s);
        
    arr1=_atoArr(s);
        
    len1=i=strlen(s);

        
    printf("Input the second number: ");gets(s);
        
    arr2=_atoArr(s);
        
    len2=j=strlen(s);
        
    max=(i>j)?i:j;
            
    i=i-1;
            
    j=j-1;
            
    Aresult[k]=0;
    for(
    max;max>0;max--)
    {
        if((
    arr1[i]+arr2[j])<10
        {
            
    store=0;
            
    result=arr1[i]+arr2[j];
        }
        else
        {
            
    store=1;
            
    result=arr1[i]+arr2[j]-10;
        }
        
    i=i-1;
    j=j-1;

    if(
    i<0){i=0;arr1[0]=0;}
    if(
    j<0){j=0;arr2[0]=0;}

    Aresult[k++]+=result;
    Aresult[k]=store;
    //printf("%d",result);
    }
    for(
    i=0;i<=k;i++) printf("%d",Aresult[i]);
    getch();

    Bài này em mới đang trong giai đoạn hình thành ý tưởng thôi nên chắc chưa đâu vào đâu cả hì hì.
    Và bây giờ là câu hỏi:

    1. Với mã nguồn trên em dịch bằng VC6 nó ko báo lỗi gì cả. Nhưng nhập số đầu tiên xong nó đòi debug và sổ ra một tràng mã loằng ngoằng , em chả hiểu gì cả. . Cái mã đó là gì vậy ạ?

    2. Cái Aresult của em mặc định khai báo 90 ô nhớ nhưng mà em muốn nó không cố định như thế mà linh động theo kết quả nhập vào và có số ô nhớ là: max+1 thì phải làm thế nào.

    3.Em thử dịch bằng C-Free thì được. Nhưng nếu nhập nhiều số một chút thì lại bị lỗi, xổ ra một tràng số chả biết ở đâu tới.
    ...

    Em mới chỉ được học pascal ở lớp thôi. Hiện em đang tự học C qua quyển "Ngôn ngữ lập trình C" của Quách Tuấn Ngọc nên kiến thức nông cạn lắm. Mong được mọi người giúp đỡ

  2. #2
    Ngày gia nhập
    11 2007
    Bài viết
    153

    Bạn làm kiểu này mình không hiểu lắm, bạn có thể vui lòng giải thích cho mình 1 chút về đoạn bên dưới này được không?
    Code:
    #include<voidlib.cpp>// thư viện này hình như chưa thấy dùng bao giờ thì fải:-?
    void main()
    {
    
        char *s;
        int j=0,i=0, len1, len2;
        int *arr1, *arr2;
        int k=0,store,result,max;
        int Aresult[90];
        printf("Input the first number: ");gets(s);//tính tổng 2 số nguyên lớn hay độ dài của dãy ký tự vừa nhập vào?vì bạn dùng hàm gets??
        arr1=_atoArr(s);//_atoArr là hàm gì vậy?
        len1=i=strlen(s);
    
        printf("Input the second number: ");gets(s);
        arr2=_atoArr(s);
        len2=j=strlen(s);
        max=(i>j)?i:j;
            i=i-1;
            j=j-1;
            Aresult[k]=0;// k ở đây là =0 qua thực hiện các lệnh không có gì thay đổi nên không cần tạo biến k làm gì sẽ gây tốn bộ nhớ 1 cách không đáng có.
    for(max;max>0;max--)
    {
        if((arr1[i]+arr2[j])<10) 
        {
            store=0;
            result=arr1[i]+arr2[j];
        }
        else
        {
            store=1;
            result=arr1[i]+arr2[j]-10;
        }
        
    i=i-1;
    j=j-1;
    
    if(i<0){i=0;arr1[0]=0;}
    if(j<0){j=0;arr2[0]=0;}
    
    Aresult[k++]+=result;
    Aresult[k]=store;
    //printf("%d",result);
    }
    for(i=0;i<=k;i++) printf("%d",Aresult[i]);// ở đây không cần thư viện stdio cho hàm printf à?
    getch();// sử dụng hàm này mà không có thư viện conio à?
    }
    Mình xin góp chút ý kiến về câu hỏi của bạn:
    1. Bạn hãy post mã lên thì bọn mình mới biết được nó là cái gì chứ??
    2. Muốn khai báo theo kiểu max+1 thì ta sử dụng cấp phát bộ nhớ động.
    3. Bạn khai báo là con trỏ ký tự thì lỗi có lẽ sẽ phải xảy ra .

    Đây là chút ý kiến của mình về vấn đề này hy vọng giúp được bạn phần nào, nếu bạn ở HN mà cần giúp đỡ về lập trình C thì cứ liên hệ trực tiếp với mình qua việc gặp mặt, mình sẽ giúp bạn trong khả năng của mình.Thế nhé chúc bạn học tốt.Thân!!
    ttecak ?

  3. #3
    Ngày gia nhập
    02 2008
    Bài viết
    14

    Chết thật, em sơ xuất quá . Trong cái voidlib.cpp của em có mấy hàm em hay xài nên code tạm để đó. Em include hết rồi nên khỏi include lại nữa . Còn code của cái _atoArr():

    Code:
    int *_atoArr( char *s)
    {
         int *tmp,i;
         while(s[i])
               tmp[i]=s[i++]-48;
    return tmp;
    }
    2. Muốn khai báo theo kiểu max+1 thì ta sử dụng cấp phát bộ nhớ động.
    Là thế nào vậy anh? Anh chỉ rõ hộ em với. cho em một VD vậy nhé.

    Bài này ông anh họ em bảo làm. Ý tưởng của em là lấy số nhập vào dưới dạng chuỗi, sau đó chuyển thành mảng rồi tiến hành cộng.

    3. Bạn khai báo là con trỏ ký tự thì lỗi có lẽ sẽ phải xảy ra .
    Vậy phải làm sao ạ?

  4. #4
    Ngày gia nhập
    11 2007
    Bài viết
    153

    Muốn cấp phát bộ nhớ động cho nó bạn sử dụng điều kiện kiểm tra:
    Code:
    #include <malloc.h>// muốn cấp phát bộ nhớ phải include thư viện này
    float *pointer;
    pointer=(float*)malloc(n*sizeof(float));//n ở đây là số bộ nhớ cần cấp phát ban đầu.
    if(...........)
    {
    pointer=(float*)realloc(pointer,x);// ở đây x là số ô nhớ cần cấp thêm.
    }
    Code bên trên chỉ là demo ý tưởng là bạn thực hiện vòng lặp for hoặc gì thì tuỳ bạn ,ở đây mình ví dụ biến đếm của vòng for là i thì với i tăng lên bao nhiêu thì ta làm biến đếm rồi tăng theo và từ đó cấp phát thêm bộ nhớ cho biến con trỏ khi cần.Hàm realloc dùng để cấp phát lại bộ nhớ cho con trỏ.

    Làm sao bạn có thể chuyển kiểu của chuỗi về để nhận thành kiểu số được cơ chứ, ngôn ngữ C cấu trúc chặt chẽ không cho phép chuyển kiểu từ ký tự về số đâu.Nó chỉ có thể làm được trong JS mà thôi.Bạn hãy khai báo thay vì char s thì khai là int hoặc float, như vậy tính sẽ dễ hơn.
    Code:
    #include <stdio.h>
    #include <conio.h>
    
    void main()
    {
    float num1,num2;
    float mul;
    printf("\n please enter first number: ");
    scanf("%f",&num1);
    printf("\n please enter second number: ");
    scanf("%f",&num2);
    mul=num1+num2;
    printf("\n The sum of 2 float= %f",mul);
    getch();
    }
    Mình chỉ demo code cho bạn thôi còn làm kỹ lưỡng thì bạn tự phát triển thêm nhé.
    ttecak ?

  5. #5
    Ngày gia nhập
    02 2008
    Bài viết
    14

    Làm sao bạn có thể chuyển kiểu của chuỗi về để nhận thành kiểu số được cơ chứ, ngôn ngữ C cấu trúc chặt chẽ không cho phép chuyển kiểu từ ký tự về số đâu.Nó chỉ có thể làm được trong JS mà thôi.Bạn hãy khai báo thay vì char s thì khai là int hoặc float, như vậy tính sẽ dễ hơn.
    Nhưng mà anh ơi, bài này là làm việc với số lớn mà. Chwngf vài chục chữ số thì sao mà int với float chứa hết.

    Hơn nữa với hàm _atoArr() trên của em vẫn chuyển một số ( dạng string) về mảng được mà ( chưa check Isdigit nhưng em sẽ bổ xung sau)..
    Chỉ có thể biết nhiều hay ít, khó có thể biết cho đủ...

  6. #6
    Ngày gia nhập
    11 2007
    Bài viết
    153

    Mặc định Hỏi về lỗi của VC

    Bạn định tính với số lớn cỡ nào??? nếu cần thì khi long double là ok rồi, đó là kiểu có chứa số lớn nhất đó.Còn về việc chuyển chuỗi về số thì mình chưa thấy ai làm bao giờ??Bạn có chạy thử đi xem thế nào.Nếu có lỗi post lên đây mình xem.
    ttecak ?

  7. #7
    Ngày gia nhập
    02 2008
    Bài viết
    14

    Bạn định tính với số lớn cỡ nào???
    cỡ vài trăm số luôn. Hì hì hì..
    Tại ông anh em bảo "làm thế để kiểm tra tư duy lập trình của mày tới cỡ nào"...hix..

    nếu cần thì khi long double là ok rồi, đó là kiểu có chứa số lớn nhất đó
    Em cần làm một bài tổng quát cơ anh ạ. Càng nhiều chữ số càng tốt chứ không phải đơn thuần là làm một chương trình cộng 2 số. Cái này thì đâu cần phải nghĩ ạ.

    Còn về việc chuyển chuỗi về số thì mình chưa thấy ai làm bao giờ??Bạn có chạy thử đi xem thế nào.
    Anh đùa em à? hay là tại em gà quá không hỉu nổi Đôi khi, khi làm bài cũng cần phải chuyển "12312673"(string) về "12312673"(array) để cho tiện tính toán chứ ạ? hàm _atoArr trên của em để làm việc đó. Em test thử thì hàm đó thì nó làm việc tốt.

    Nếu em diễn đạt ngu quá anh ko hiểu thì anh làm ơn hướng dẫn em giải thuật của bài cộng 2 số nguyên lớn với ạ....
    Chỉ có thể biết nhiều hay ít, khó có thể biết cho đủ...

  8. #8
    Ngày gia nhập
    12 2007
    Bài viết
    224

    Mình cũng ko có rành lắm về giải thuật tìm tổng của 2 số nguyên lớn . Mình chỉ có chút ý tưởng sau :

    1/ nhập 2 số đó theo kiểu chuỗi .
    2/ Trước khi tiến hành phép cộng ấy , nên " chuẩn hoá " 2 chuỗi ấy lại sao cho đồng chiều dài : ví dụ nếu nhập 123 và 456 thì thôi , còn nếu nhập 123 và 4567 thì nên biến thành 0123 và 4567 .
    3/ tiến hành phép cộng như phép cộng tay đối với từng cặp phần tử tương ứng của 2 chuỗi ấy ( từ phải sang trái ) , kết quả thu được cho vào 1 chuỗi mới . Gọi 2 số hạng là a[] , b[] , kết quả là c[] . Chú ý ghi nhớ số dư bằng cách thế này :xét kết quả của phép cộng của 2 phần tử tương ứng , nếu kết quả <9 thì thôi , ngược lại ta phải lấy số ở hàng đơn vị của kết quả và lưu số hàng chục vào biến dư để cộng cho lượt sau . Thêm 1 chú ý nữa là có khả năng 2 phần tử trái nhất của 2 chuỗi khi cộng lại có khi cho ra kết quả > 9 , khi đó ta ko có lưu số dư gì nữa cả vì đã hết cái để cộng rồi , mà ta ghi cả kết quả thu được luôn , do đó chú ý rằng phép cộng a[i]+b[i] nên cho bằng c[i+1] .

    Vài gợi ý nhỏ , bạn ráng tự code . Chúc thành công ^^ .

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

    Lang thang mãi mới tìm được cái code này nhưng mỗi tội là chả hiểu gì cả _ __! , bạn coi thử đi mình chưa có thời gian nghiên cứu giải thuật của việc tính tổng mà dùng chuỗi hoặc danh sách liên kết:
    Code:
    #include <stdio.h>
    
    #include "LongInt.h"
    
    int InitializeFromFile(char* fileName, VeryLongInt* &x, LongInt* &y);
    //void ShowScreen();
    
    int main(int argc, char* argv[]){
    char* inputFile;
    char* outputFile;
    if (argc < 2){
    printf("Usage: LongIntDataType.exe [InputFile] [OutputFile]\n");
    printf("Using default configuration: LongIntDataType.exe input.txt output.txt\n\n");
    inputFile = "input.txt";
    outputFile = "output.txt"; // "output/output.txt"
    } else {
    inputFile = argv[1];
    if (argc == 2)
    outputFile = "output.txt";
    else
    outputFile = argv[2];
    }
    
    LongInt *x, *y, *z;
    int succ = InitializeFromFile(inputFile, x, y);
    if (!succ) return 0;
    
    z = LongInt::Add(x, y);
    z->SaveToFile(outputFile, 0);
    delete z;
    
    z = LongInt::Subtract(x, y);
    z->SaveToFile(outputFile, 1);
    delete z;
    
    z = LongInt::Multiply(x, y);
    z->SaveToFile(outputFile, 1);
    delete z;
    
    z = LongInt::Div(x, y);
    if (z != NULL){
    z->SaveToFile(outputFile, 1);
    delete z;
    } // else FW: write NULL to file for checking students' result
    
    z = VeryLongInt::Mod(x, y);
    if (z != NULL) {
    z->SaveToFile(outputFile, 1);
    delete z;
    } // else FW: write NULL to file for checking students' result
    
    // Calculate x^10
    z = VeryLongInt::Power(x, 10);
    z->SaveToFile(outputFile, 1);
    delete z;
    
    delete x;
    delete y;
    
    // ShowScreen();
    
    return 1;
    }
    
    // Note: I have not optimized this function yet. Anyways, it works
    // It's easier to use fgets function but it's not efficient for memory.
    int InitializeFromFile(char* fileName, VeryLongInt* &x, VeryLongInt* &y){
    FILE *fptr;
    char* buffer;
    char c;
    fopen_s(&fptr, fileName, "r");
    if (fptr == NULL){
    printf("Can't open file [%s]", fileName);
    return 0;
    }
    // Read the first number
    int count = 0;
    int ok = 1;
    while (!feof(fptr) && ok){
    c = fgetc(fptr);
    if (c != '\n')
    count++;
    else ok = 0;
    }
    fseek(fptr,0, 0);
    buffer = new char[count+1];// +1 for NULL character
    buffer[count] = '\0';
    count = 0;
    ok = 1;
    while (!feof(fptr) && ok){
    c = fgetc(fptr);
    if (c != '\n'){
    buffer[count] = c;
    count++;
    } else ok = 0;
    }
    x = LongInt::Parse(buffer);
    delete buffer;
    
    // Read the second number
    int secondCount = 0;
    ok = 1;
    while (!feof(fptr) && ok){
    c = fgetc(fptr);
    if (c != '\n'){
    secondCount++;
    } else ok = 0;
    }
    buffer = new char[secondCount+1];// +1 for NULL character
    buffer[secondCount] = '\0';
    
    fseek(fptr, count+2, 0);
    secondCount = 0;
    ok = 1;
    while (!feof(fptr) && ok){
    c = fgetc(fptr);
    if (c != '\n'){
    buffer[secondCount] = c;
    secondCount++;
    } else ok = 0;
    }
    y = LongInt::Parse(buffer);
    delete buffer;
    fclose(fptr);
    return 1;
    }
    
    /*
    void ShowScreen(){
    LongInt *x = new VeryLongInt(998);
    LongInt *y = new VeryLongInt(9);
    LongInt *z;
    
    printf("Simulation of operators between 2 very long integers\n");
    printf("Sum:\t\t");
    z = VeryLongInt::Add(x, y);
    x->Print(); printf(" + "); y->Print();
    printf(" = "); z->Print(); printf("\n");
    delete z;
    
    printf("Subtract:\t");
    z = LongInt::Subtract(x, y);
    x->Print(); printf(" - "); y->Print();
    printf(" = "); z->Print(); printf("\n");
    delete z;
    
    printf("Multiply:\t");
    x->Print(); printf(" * "); y->Print();
    z = LongInt::Multiply(x, y);
    printf(" = "); z->Print(); printf("\n");
    delete z;
    
    printf("DIV:\t\t");
    x->Print(); printf(" / "); y->Print();
    z = LongInt::Div(x, y);
    printf(" = "); z->Print(); printf("\n");
    delete z;
    
    printf("MOD:\t\t");
    z = LongInt::Mod(x, y);
    x->Print(); printf(" %% "); y->Print();
    printf(" = "); z->Print(); printf("\n");
    delete z;
    
    delete x;
    delete y;
    
    x = LongInt::Parse("-23234");
    y = LongInt::Parse("256");
    
    if (LongInt::Compare(x, y) == -1){
    printf("First number is less than second number.\n");
    } else 
    printf("First number isnot less than second number.\n");
    
    z = LongInt::Add(x, y);
    printf("Sum:\t\t");
    x->Print(); printf(" + "); y->Print(); printf(" = "); z->Print();
    printf("\n");
    delete z;
    printf("Subtract:\t");
    z = LongInt::Subtract(x, y);
    x->Print(); printf(" - "); y->Print(); printf(" = "); z->Print();
    printf("\n");
    delete z;
    
    x->Print(); printf("^10 = ");
    z = LongInt::Power(x, 10);
    char *temp = z->ToString();
    printf("%s\n", temp);
    delete temp;
    
    delete z;
    
    delete x;
    delete y;
    }
    */
    Còn đây là cái thư viện LongInt.h:
    Code:
    class LongInt{
    public:
    LongInt();
    LongInt(int val); // convert an integer into LongInt object
    ~LongInt(); 
    
    LongInt* Clone(); // return another copy of current object (replicate the current object)
    int GetSign(); // return sign of current number
    void ToggleSign(); // toggle sign of current number
    char* ToString(); // convert current object into string
    void Print(); // output current number to console by using printf() function
    int SaveToFile(char* fileName, int appendFlag);// output to file. appendFlag: +1: append, 0: overwrite
    
    static LongInt* Add(VeryLongInt *x, LongInt *y); // x + y
    static LongInt* Subtract(VeryLongInt *x, LongInt *y); // x - y
    static LongInt* Multiply(VeryLongInt *x, LongInt *y); // x * y
    static LongInt* Div(VeryLongInt *x, LongInt *y); // x div y
    static LongInt* Mod(VeryLongInt *x, LongInt *y); // x % y
    static LongInt* Power(VeryLongInt *x, int n); // x^n
    static int EqualTo(VeryLongInt *x, LongInt *y); // x == y?
    static int Compare(VeryLongInt *x, LongInt *y); // return +1 if x > y; 0 if x = y; -1 if x < y
    static LongInt* Parse(char *str); // convert a string into a long integer
    // Add your neccessary methods here ...
    };
    ttecak ?

  10. #10
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    2 số nguyên lớn thì dùng chuỗi, hơi lớn nữa thì dùng quá tải toán tử, cực lớn thì dùng danh sách liên kết, T_T, có giải thuật gì đâu cứ thao tác y chang trên danh sách, do xử lý con trỏ nên nhìn rườm rà 1 tí thôi mà.
    Em mới chỉ được học pascal ở lớp thôi. Hiện em đang tự học C qua quyển "Ngôn ngữ lập trình C" của Quách Tuấn Ngọc nên kiến thức nông cạn lắm. Mong được mọi người giúp đỡ
    Học pascal cũng tốt, do code trong sáng viết giải thuật thì có lẽ khoẻ hơn C. Mới học thì cố gắng xài mãng cũng được.
    cỡ vài trăm số luôn. Hì hì hì..
    Tại ông anh em bảo "làm thế để kiểm tra tư duy lập trình của mày tới cỡ nào"...hix..
    Học danh sách liên kết đi rồi 100 số, chạy cho lắm trượt té rồi la lên "Đau Quá !"
    ps : anh bạn ác quá haha !
    Đã được chỉnh sửa lần cuối bởi rox_rook : 16-02-2008 lúc 11:04 AM.

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