cuốn sách gpt4 ai đã làm

C - ký tự*' khác nhau về mức độ gián tiếp từ ' ký tự(*)[200]

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 07:56:02 28 4
mua khóa gpt4 Nike

Đối với bài tập lập trình C, tôi đang cố gắng viết một vài tệp tiêu đề để kiểm tra cú pháp của cái gọi là "ngôn ngữ lập trình X". Tôi mới bắt đầu gần đây và đang viết tệp tiêu đề đầu tiên của mình. Đây là mã tôi đã viết:

#ifndef _DeclarationsChecker_h_
#define _DeclarationsChecker_h_



#include
#include
#include
#include

#xác định LINE_LENGTH_LIMIT 200
#xác định CODE_LINE_LIMIT 1000


void checkDeclarations(char **code, int num_lines) {


char *currentLine;

for (int currentLineNum = 0; currentLineNum < num_lines; currentLineNum++) {

if (code[currentLineNum] != NULL) {

currentLine = code[currentLineNum];

char (**tokenized)[LINE_LENGTH_LIMIT];

for (int i = 0; i < strlen(currentLine); i++) {

tokenized[i] = strtok(currentLine, " ");

if (mã thông báo [i] == NULL)
phá vỡ;
}

char *currentToken;

cho (int i = 0; i < LINE_LENGTH_LIMIT; i++) {

currentToken = tokenized[i];

if (strcmp("***", currentToken))
phá vỡ;

char (*nextToken) = tokenized[i + 1];

if (strcmp("global", currentToken)) {

if (!strcmp("character", nextToken) && !strcmp("integer", nextToken) && !strcmp("double", nextToken) && !strcmp("string", nextToken)) {
printf("Khai báo: kiểu dữ liệu không xác định %s tại dòng %d", nextToken, currentLineNum);
}

}

if (strcmp("character", currentToken) || strcmp("integer", currentToken) || strcmp("double", currentToken) || strcmp("string", currentToken)) {

char *functionName = strtok(nextToken, '(');

if (strcmp("character", functionName) || strcmp("integer", functionName) || strcmp("double", functionName) || strcmp("string", functionName) || strcmp("while", functionName) || strcmp("if", functionName) || strcmp("bằng", functionName) ||

printf("Khai báo: vi phạm đặt tên %s tại dòng %d", functionName, currentLineNum);
}

for (int i = 0; i < strlen(functionName); i++) {

if (!isalnum(functionName[i]) && (functionName[i] != '_') && (functionName[i] != '?')) {

printf("Khai báo: vi phạm đặt tên %s tại dòng %d", functionName, currentLineNum);

}
}

}
}

}
}
}

#endif

Tôi nhận được một số cảnh báo biên dịch, tôi đã thêm cảnh báo vào cuối và khi tôi cố gắng khởi động chương trình, nó lập tức báo lỗi "Chương trình bị lỗi", nhưng tôi nghĩ có lẽ đó là do tệp tiêu đề chưa được viết. Tôi có thể làm gì để thoát khỏi lỗi tôi đang gặp phải? Cảm ơn câu trả lời của bạn, bất kỳ trợ giúp sẽ được đánh giá cao. (Xin lưu ý rằng tôi chưa quen với C và tôi không hiểu rõ khái niệm về khả năng thay thế lẫn nhau giữa mảng và con trỏ và con trỏ kép (ví dụ: **ptr))

...\declarationschecker.h(30): cảnh báo C4018: '<': không khớp có chữ ký/không dấu
...\declarationschecker.h(32): cảnh báo C4047: '=': 'char (*)[200]' khác về mức độ gián tiếp so với 'char *'
...\declarationschecker.h(42): cảnh báo C4047: '=': 'char *' khác với mức độ gián tiếp từ 'char (*)[200]'
...\declarationschecker.h(59): cảnh báo C4047: 'function': 'const char *' khác về mức độ gián tiếp so với 'int'
...\declarationschecker.h(59): cảnh báo C4024: 'strtok': các loại khác nhau cho tham số chính thức và thực tế 2
...\declarationschecker.h(66): cảnh báo C4018: '<': không khớp có chữ ký/không dấu
...\declarationschecker.h(47): cảnh báo C4047: 'khởi tạo': 'char *' khác với mức độ gián tiếp từ 'char (*)[200]'

Các tệp c chính yêu cầu tệp tiêu đề được dán bên dưới:

#include "CodeReader.h"
#include "BracketsChecker.h"
#include "Tuyên bốChecker.h"
#include "StatementsChecker.h"
#include "SSAChecker.h"

int main(int argc, char * argv[]) {
nếu (argc < 2) {
printf("Xin vui lòng cung cấp tên file mã X\n");
exit(1);
}

char **code = readCode(argv[1]);
int num_lines = getCodeNumLines();

checkBrackets(code, num_lines);
checkDeclarations(code, num_lines);
checkProgramStatements(code, num_lines);
checkSSA(mã, num_lines);

cleanMemory(mã);

int terminalHung; scanf("%d", &terminalHung);
return 0;
}

câu trả lời hay nhất

Trước hết, nếu không có quyền truy cập vào phần còn lại của dự án (tôi cho rằng có một số tệp khác chứa một số chức năng mà bạn đã tham chiếu trong bài đăng của mình), sẽ không có cách nào để biết bạn đã tạo mã như thế nàomáy phát điện, hạn chế lời khuyên cho các vấn đề cú pháp.

Lời giải thích cho lỗi sau trong bài đăng của bạn nằm trong các nhận xét bên dưới và nội tuyến trong mã ở phía dưới: nhập mô tả hình ảnh ở đây

Đầu tiên ở phần bạn sửa mình không thấy chức năng mã đọc() Biến là gì vì bạn không đưa nó vào nhưng nếu nó không tạo bộ nhớ mã số Không thể sử dụng được.

trong tuyên bố char (**tokenized)[LINE_LENGTH_LIMIT]; Sau đó bạn thử sử dụng char ** phần tử mảng thứ 0 mà không tạo bộ nhớ trước. Trường hợp tốt nhất là chương trình của bạn sẽ gặp sự cố khi đang chạy, tệ hơn là chương trình có thể hoạt động tốt. Đây được gọi là Không xác định hoặc Hành vi không xác định . (Đọc cách sử dụng malloc ). Bởi vì bạn đang chuẩn bị lưu trữ cho một tập hợp các chuỗi nên bạn chỉ cần hai chiều chứ không phải ba chiều. ký tự*[] hoặc char ** Mọi chuyện sẽ ổn thôi. Trong cả hai trường hợp, chúng phải được khởi tạo và tạo bộ nhớ trước khi sử dụng. Tuy nhiên, vì bạn đã biết số dòng tối đa và độ dài dòng tối đa nên chỉ cần khai báo và sử dụng:char được mã hóa[CODE_LINE_LIMIT][LINE_LENGTH_LIMIT];.

Hơn nữa, tuyên bố char *mã thông báo = 0; để sử dụng với strtok. (Xem bình luận để biết lý do)

Ngoài ra, hãy khai báo các biến được sử dụng nhiều lần (ví dụ:Tôi. Xem bình luận để biết lý do)

Đối với phần còn lại, hãy xem lại các nhận xét nội tuyến để xem các lỗi/cảnh báo trước đó đã được giải quyết như thế nào trong mã của bạn:

kiểm tra void tĩnhDeclarations(char **code, int num_lines) 
{

char *token = 0;//sử dụng với strtok
char *currentLine;
char được mã hóa[CODE_LINE_LIMIT][LINE_LENGTH_LIMIT] = {{0}};
int i, len; // khai báo nhân các biến được sử dụng một lần

for (int currentLineNum = 0; currentLineNum < num_lines; currentLineNum++) {

if (code[currentLineNum] != NULL) {

currentLine = code[currentLineNum];

//char (*tokenized)[LINE_LENGTH_LIMIT] = {0};
len = strlen(currentLine);
for( i = 0; i< len; i++ ) // đã sửa
//for (int i = 0; i < strlen(currentLine); i++) // không thực hiện so sánh chuỗi trong một vòng lặp
{ // và tránh so sánh các loại khác nhau
// trả về của strlen() là một int không dấu
mã thông báo = strtok(currentLine, " ");

if (mã thông báo == NULL) bị hỏng;
else strcpy(tokenized[i], token);
}

char *currentToken;

//for (int i = 0; i < LINE_LENGTH_LIMIT; i++) { // khai báo bóng của biến được khai báo trước đó
cho ( i = 0; i < LINE_LENGTH_LIMIT; i++) { // đã sửa

currentToken = tokenized[i];

if (strcmp("***", currentToken))
phá vỡ;

char (*nextToken) = tokenized[i + 1];

if (strcmp("global", currentToken)) {

if (!strcmp("character", nextToken) && !strcmp("integer", nextToken) && !strcmp("double", nextToken) && !strcmp("string", nextToken)) {
printf("Khai báo: kiểu dữ liệu không xác định %s tại dòng %d", nextToken, currentLineNum);
}

}

if (strcmp("character", currentToken) || strcmp("integer", currentToken) || strcmp("double", currentToken) || strcmp("string", currentToken)) {

//char *functionName = strtok(nextToken, '('); // strtok Đối số thứ 2 yêu cầu một chuỗi, không phải số nguyên
char *functionName = strtok(nextToken, "("); // đã sửa
// lưu ý: gọi cái này trong một vòng lặp sẽ là một vấn đề.
// hoặc sử dụng 'token', đã được khai báo

if (strcmp("character", functionName) || strcmp("integer", functionName) || strcmp("double", functionName) || strcmp("string", functionName) || strcmp("while", functionName) || strcmp("if", functionName) || strcmp("bằng", functionName) ||

printf("Khai báo: vi phạm đặt tên %s tại dòng %d", functionName, currentLineNum);
}

//for (int i = 0; i < strlen(functionName); i++) { // "i" đã được khai báo ở trên
for ( i = 0; i < len; i++) { // đã sửa

if (!isalnum(functionName[i]) && (functionName[i] != '_') && (functionName[i] != '?')) {

printf("Khai báo: vi phạm đặt tên %s tại dòng %d", functionName, currentLineNum);

}
}

}
}

}
}
}

Đã chỉnh sửa để giải quyết các vấn đề trong nhận xét...
Có thể bạn đã biết những điều sau đây, nhưng bài đăng của bạn không đưa ra bất kỳ hướng dẫn nào, vì vậy tôi sẽ cung cấp những thông tin sau để đề phòng:

Sau khi gán chuỗi cho char*str trước (ví dụ, bằng cách sử dụng strcpy hoặc strcat v.v.), bạn phải tạo bộ nhớ:

int mong muốnStrLen = 80;
char *str = calloc(desiredStrLen + 1, 1);
if(str)// kiểm tra việc trả lại calloc trước khi tin tưởng nó hoạt động
{
// sử dụng str
...
free(str); // luôn luôn, khi hoàn thành với bất kỳ bộ nhớ được cấp phát động nào, hãy giải phóng nó.

Đối với các tập hợp các chuỗi (cần thiết để đọc các dòng tệp chẳng hạn), bạn có thể tạo bộ nhớ cho một tập hợp các chuỗi. Khi bạn xác định được số dòng và dòng dài nhất trong tệp, bạn có thể tạo đủ bộ nhớ để sao chép từng dòng đọc từ tệp thành một chuỗi:

char **currentLine = Create2DStr(numLines,longestLine);
nếu (chuỗi)
{
/// sử dụng currentLine (trong vòng lặp của bạn)
...
strcpy(currentLine[i], code[currentLineNum]);
...
// khi hoàn thành việc thu thập chuỗi, hãy giải phóng nó.
free2DStr(&strings, numLines);

Chức năng tôi sử dụng ở trên có thể được triển khai theo một số cách. Tôi sử dụng như sau:

char ** Create2DStr(ssize_t numStrings, ssize_t maxStrLen)
{
int i;
char **str = {0};
str = calloc(numStrings, sizeof(char *));
for(i=0;i
{
str[i] = calloc(maxStrLen + 1, 1);
}
trả về str;
}

void free2DStr(char *** str, ssize_t numStrings)
{
int i;
if(!(*str)) trả về;
for(i=0;i
{
free((*str)[i]);
(*str)[i] = NULL;
}
miễn phí((*str));
(*str) = NULL;
}

Về C - ký tự *' khác nhau về mức độ gián tiếp so với ký tự ' (*)[200], chúng tôi tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/50077501/

28 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress