Hỏi cách truyền tham trị cho mảng 2 chiều

Em mới vừa xóa nhưng nó báo lỗi ?

D:\C\SPOJ\NKPALIN\main.c|9|error: array type has incomplete element type|

Cho anh xem toàn bộ code lại xem nào?

Đây ạ

#include <stdio.h>
#include <stdlib.h>

#define MAXARR 2001
#define fi "NKPALIN.INP"
#define fo "NKPALIN.OUT"

void input(char *s);
void output(int l[MAXARR][MAXARR], int i, int j, char s[MAXARR]);
int max(int a, int b);

int main()
{
    char s[MAXARR] = {};
    int l[MAXARR][MAXARR] = {};
    int i,j;
    input(s);
    for (i = 0; i < sizeof (s) / sizeof (s[0]); i++ )
        for (j = 0; j< sizeof (s) / sizeof (s[0]); j++) {
            if (s[i] == s[j]) {
                l[i][j] = l[i-1][j-1] + 1;
            }
            else {
                l[i][j] = max(l[i-1][j], l[i][j-1]);
            }
        }
    i = sizeof (s) / sizeof (s[0]);
    j = sizeof (s) / sizeof (s[0]);
    output(l[MAXARR][MAXARR], i, j, s[MAXARR]);
    return 0;
}

void input(char* s)
{
    FILE *f = fopen(fi,"rt");
    fscanf(f,"%s", s);
    fclose(f);
}

void output(int l[MAXARR][MAXARR], int i, int j, char s[MAXARR])
{
    FILE *f = fopen(fo,"wt");
    while (i>0 && j>0) {
        if (s[i] == s[j]) {
            fprintf(f,"%c",s[i]);
        }
        else {
            if (l[i][j] == l[i-1][j]) {
                i--;
            }
            else j--;
        }
    }
    fclose(f);
}

int max(int a, int b)
{
    if (a > b) return(a);
    else return(b);
}

Ai chà, anh già rồi, nhầm lẫn. Em không cần phải truyền tham số đầu, nhưng phải truyền cái sau. Anh sửa lại

#include <stdio.h>
#include <stdlib.h>

#define MAXARR 2001
#define fi "NKPALIN.INP"
#define fo "NKPALIN.OUT"

void input(char *s);
void output(int l[][MAXARR], int i, int j, char s[MAXARR]);
int max(int a, int b);

int main()
{
    char s[MAXARR] = {};
    int l[MAXARR][MAXARR] = {};
    int i,j;
    input(s);
    for (i = 0; i < sizeof (s) / sizeof (s[0]); i++ )
        for (j = 0; j< sizeof (s) / sizeof (s[0]); j++) {
            if (s[i] == s[j]) {
                l[i][j] = l[i-1][j-1] + 1;
            }
            else {
                l[i][j] = max(l[i-1][j], l[i][j-1]);
            }
        }
    i = sizeof (s) / sizeof (s[0]);
    j = sizeof (s) / sizeof (s[0]);
    output(l, i, j, s);
    return 0;
}

void input(char* s)
{
    FILE *f = fopen(fi,"rt");
    fscanf(f,"%s", s);
    fclose(f);
}

void output(int l[][MAXARR], int i, int j, char s[MAXARR])
{
    FILE *f = fopen(fo,"wt");
    while (i>0 && j>0) {
        if (s[i] == s[j]) {
            fprintf(f,"%c",s[i]);
        }
        else {
            if (l[i][j] == l[i-1][j]) {
                i--;
            }
            else j--;
        }
    }
    fclose(f);
}

int max(int a, int b)
{
    if (a > b) return(a);
    else return(b);
}

Em chú ý cách truyền vào như thế này là sai nhé

output(l[MAXARR][MAXARR], i, j, s[MAXARR]);

Chỉ cần truyền tên mảng thôi

output(l, i, j, s);

Và quan trọng hơn hết là đừng đặt biến một ký tự nữa :frowning:

Nhìn code em anh hại não quá, i, j đã đủ lại thêm l với f, sao nó có 1 nét thẳng thẳng không vại trời =))

 output(l[MAXARR][MAXARR], i, j, s[MAXARR]);

ôn lại một tý về cách gọi hàm nhé

Trong code em đã khai báo một hàm void với tên output, nhận vào các tham số là mảng 2 chiều l, 2 biến interger i, j, một mảng char[] (hay gọi là string).

Trong lý thuyết cách gọi hàm, ta không gọi cả dòng họ gia phả nhà biến ra, vì nếu như đã là biến cục bộ hay biến toàn cục thì nó chỉ có duy nhất 1 tên (i , j chẳng hạn), vì thế khi ta gọi hàm thì ta chỉ cần gọi tên của nó ra thôi

 output(l, i, j, s);

Nhớ lưu ý rằng gọi hàm và truyền tham số khác với khai báo hàm và khai báo tham số. Em đang nhầm lẫn giữa 2 cái này :smile:

1 Like

I moved 5 posts to a new topic: Cách truyền mảng 3 chiều vào hàm

Cho em hỏi luôn, cách lấy độ dài của dãy s thế đã đúng chưa ?

Đoạn lấy độ dài nào vậy @Byn? Ý anh là dòng code nào :smile:

chắc là đúng rồi :)) thay vì s[0], dùng sizeof(char) cũng dc

1 Like

Ý em là nhập vào một mảng char s[] nhưng không biết độ dài bao nhiêu, lấy độ dài bằng dòng này được không ?

sizeof (s) / sizeof (s[0])

Bạn chạy thử sẽ biết ngay.
nếu s = “Byn”
Thì kế quả trả về là 4.
Tại sao lại là 4? VÌ mỗi chuỗi đều có thêm 1 ký tự kết thúc ‘\n’ mà ta không nhìn thấy.

1 Like

Nếu là mảng thì em dùng hàm strlen ấy.

/* strlen example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char szInput[256];
  printf ("Enter a sentence: ");
  gets (szInput);
  printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));
  return 0;
}

@ltd vì sao phải ép kiểu (unsigned)strlen(szInput)

Chương trình của em thế này vì sao nó không chạy được, khi built chương trình thì nó hiện ra màn hình console rồi hiện ra cửa sổ chương trình has stop working :’(

#include <stdio.h>
#include <stdlib.h>

#define MAXARR 2001
#define fi "NKPALIN.INP"
#define fo "NKPALIN.OUT"

void input(char *s);
void output(int l[][MAXARR], int i, int j, char s[MAXARR]);
int max(int a, int b);

int main()
{
    char s[MAXARR] = {};
    int l[MAXARR][MAXARR] = {};
    int i,j;
    input(s);
    for (i = 0; i < sizeof (s) / sizeof (s[0]); i++ )
        for (j = 0; j< sizeof (s) / sizeof (s[0]); j++) {
            if (s[i] == s[j]) {
                l[i][j] = l[i-1][j-1] + 1;
            }
            else {
                l[i][j] = max(l[i-1][j], l[i][j-1]);
            }
        }
    i = sizeof (s) / sizeof (s[0]);
    j = sizeof (s) / sizeof (s[0]);
    //output(l, i, j, s);
    return 0;
}

void input(char* s)
{
    FILE *f = fopen(fi,"rt");
    fscanf(f,"%s", s);
    fclose(f);
}

void output(int l[][MAXARR], int i, int j, char s[MAXARR])
{
    FILE *f = fopen(fo,"wt");
    while (i>0 && j>0) {
        if (s[i] == s[j]) {
            fprintf(f,"%c",s[i]);
        }
        else {
            if (l[i][j] == l[i-1][j]) {
                i--;
            }
            else j--;
        }
    }
    fclose(f);
}

int max(int a, int b)
{
    if (a > b) return(a);
    else return(b);
}

Anh copy từ trang [cplusplus][1] thôi. Thực tế không cần ép kiểu. strlen trả về size_t, tương đương với unsigned rồi.

size_t
Unsigned integral type

Kiêm tra lại mấy cái chỗ mở file, coi thử có mở file được hay không rồi mới xử lý tiếp.

FILE *f = fopen(fi,"rt");

Mấy cái lỗi dạng này là do truy xuất vùng nhớ tầm bậy.
[1]: http://www.cplusplus.com/reference/cstring/strlen/

Không thể debug được, thế làm sao để kiểm tra lỗi vậy ?

Khi bạn dùng mảng cố định thì cái nay = MAXARR, cái này nên thay là lens hay 1 biến nào đó thể hiện chiều dài chuỗi thay vì lặp lại.

Mảng lớn 4.000.000 phần tử trong 1 chương trình con mà lại sử dụng mảng cố định là không nên

Trong C hình như không có tham số “t” trong fopen

Has stop working là do bạn truy cập mảng với chỉ số âm

Theo mình có thể bạn đang làm việc với thuật toán chuỗi con chung:

  1. Khi khởi tạo l[i][j] i==0 hoặc j==0 bạn đặt l[i][j] =0 để không bị lỗi. Sau đó chạy i,j từ 1->lens
  2. Thay

bằng chiều dài của chuỗi

1 Like

Anh cũng chưa xài cái “t” bao giờ, nhưng hôm trước anh đọc về fopen trên cplusplus thì thấy “t” là optional, dùng để chỉ mình đang đọc text file.

If additional characters follow the sequence, the behavior depends on
the library implementation: some implementations may ignore additional
characters so that for example an additional “t” (sometimes used to explicitly state a text file) is accepted.

1 Like

Tại sao lại là chỉ số âm ?

Has stop working là do bạn truy cập mảng với chỉ số âm.

Trong vòng for mình quote ấy. I, j bắt đầu từ 0, bạn trừ 1 nữa thành -1 là chỉ số âm.
để tránh lỗi này bạn thêm đk:

if(i==0 || j==0) l[i][j]=0;
else{
    ... Câu lệnh trong 2 vòng for của bạn
}

Mình đã thử đổi để nó không truy cập số âm nhưng vẫn không được ??? tạo sao vậy nhỉ ?

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?