語言:C/C++
關鍵字:詞法分析,哈希表,鏈表法處理哈希沖突
總述:嘗試開發(fā)一個簡單的編譯器。編譯一個程序的步驟:詞法分析,語法分析,語義分析,中間代碼生成,目標代碼生成。
語言:C/C++
關鍵字:詞法分析,哈希表,鏈表法處理哈希沖突
摘要:開發(fā)一個簡單的編譯器。編譯一個程序的步驟:詞法分析,語法分析,語義分析,中間代碼生成,目標代碼生成。本文目的是實現(xiàn)詞法分析。
1 項目需求描述
分析一個C語言程序的內(nèi)容。將函數(shù)的變量名設置為灰色,將關鍵字設置為綠色,將整型常量、浮點型常量、字符常量、字符串常量等設置為褐色,將運算符設置為紅色。
2 設計思路
2.1 預處理
2.1.1 定義存儲字符串的結構體。
![]()
/*存儲字符串的結構體定義*/
typedef struct TKWord {
int tkcode;
string spelling;
struct TKWord* next;
}TKWord, *pTKWord;
定義存儲字符串的結構體
2.1.2 通過枚舉對預置的字符串進行編號。
![]()
/*通過枚舉對預置的字符串進行編號*/
enum e_TokenCode
{
/* 運算符及分隔符 */
TK_PLUS, // + 加號
TK_MINUS, // - 減號
TK_STAR, // * 星號
TK_DIVIDE, // / 除號
TK_MOD, // % 求余運算符
TK_EQ, // == 等于號
TK_NEQ, // != 不等于號
TK_LT, // < 小于號
TK_LEQ, // <= 小于等于號
TK_GT, // > 大于號
TK_GEQ, // >= 大于等于號
TK_ASSIGN, // = 賦值運算符
TK_POINTSTO, // -> 指向結構體成員運算符
TK_DOT, // . 結構體成員運算符
TK_AND, // & 地址與運算符
TK_OPENPA, // ( 左圓括號
TK_CLOSEPA, // ) 右圓括號
TK_OPENBR, // [ 左中括號
TK_CLOSEBR, // ] 右中括號
TK_BEGIN, // { 左大括號
TK_END, // } 右大括號
TK_SEMICOLON, // ; 分號
TK_COMMA, // , 逗號
TK_ELLIPSIS, // ... 省略號
TK_EOF, // 文件結束符
/* 常量 */
TK_CINT, // 整型常量
TK_CFLOAT, // 浮點型常量
TK_CCHAR, // 字符常量
TK_CSTR, // 字符串常量
/* 關鍵字 */
KW_CHAR, // char關鍵字
KW_SHORT, // short關鍵字
KW_INT, // int關鍵字
KW_VOID, // void關鍵字
KW_STRUCT, // struct關鍵字
KW_IF, // if關鍵字
KW_ELSE, // else關鍵字
KW_FOR, // for關鍵字
KW_CONTINUE, // continue關鍵字
KW_BREAK, // break關鍵字
KW_RETURN, // return關鍵字
/* 標識符 */
TK_IDENT // 函數(shù)名或變量名
};
typedef enum e_TokenCode tokencode;
對預置的字符串進行編號
2.1.3 定義一個靜態(tài)結構數(shù)組,其中存放各種預置的字符串及其token。然后將他們分別通過哈希公式映射并添加到哈希表中。
![]()
/*定義一個靜態(tài)結構數(shù)組*/
static TKWord keywords[] = {
{TK_PLUS,"+",NULL},
{TK_MINUS,"-",NULL},
{TK_STAR,"*",NULL},
{TK_DIVIDE,"/",NULL},
{TK_MOD,"%",NULL},
{TK_EQ,"==",NULL},
{TK_NEQ,"!=",NULL},
{TK_LT,"<",NULL},
{TK_LEQ,"<=",NULL},
{TK_GT,">",NULL},
{TK_GEQ,">=",NULL},
{TK_ASSIGN,"=",NULL},
{TK_POINTSTO,"->",NULL},
{TK_DOT,".",NULL},
{TK_AND,"&",NULL},
{TK_OPENPA,"(",NULL},
{TK_CLOSEPA,")",NULL},
{TK_OPENBR,"[",NULL},
{TK_CLOSEBR,"]",NULL},
{TK_BEGIN,"{",NULL},
{TK_END,"}",NULL},
{TK_SEMICOLON,";",NULL},
{TK_COMMA,",",NULL},
{TK_ELLIPSIS,"...",NULL},
{TK_EOF,"End Of File",NULL},
{TK_CINT,"整形常量",NULL},
{TK_CFLOAT,"浮點型常量",NULL},
{TK_CCHAR,"字符常量",NULL},
{TK_CSTR,"字符串常量",NULL},
{KW_CHAR,"char",NULL},
{KW_SHORT,"short",NULL},
{KW_INT,"int",NULL},
{KW_VOID,"void",NULL},
{KW_STRUCT,"struct",NULL},
{KW_IF,"if",NULL},
{KW_ELSE,"else",NULL},
{KW_FOR,"for",NULL},
{KW_CONTINUE,"continue",NULL},
{KW_BREAK,"break",NULL},
{KW_RETURN,"return",NULL},
{40}
};
定義靜態(tài)結構數(shù)組keywords
![]()
/*定義哈希函數(shù)*/
int elf_hash(string key) {
int h = 0, g, i = 0;
while (key[i]) {
h = (h << 4) + key[i++];
g = h & 0xf0000000;
if (g)
h ^= g >> 24;
h &= ~g;
}
return h % MAXKEY;
}
哈希函數(shù)elf_hash
![]()
/*定義哈希表*/
TKWord* tk_Hashtable[MAXKEY] = { 0 };
定義哈希表
![]()
/*定義函數(shù),用于將靜態(tài)結構數(shù)組中各種預置的字符串及其token分別通過哈希公式映射并添加到哈希表中*/
void InitKeywords(pTKWord keywords, int keywordsLen, pTKWord* tk_Hashtable) {
for (int i = 0; i < keywordsLen; i++) {
TKWord tmp = keywords[i];
if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->tkcode = tmp.tkcode;
/*string snew = tmp.spelling;
for (int j = 0; j < snew.size(); j++) {
pnew->spelling.push_back(snew[j]);
}*/
pnew->spelling = tmp.spelling;//拷貝字符串
tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
}
else {
TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
TKWord* q = p;
while (p != NULL) {
if (!p->spelling.compare(tmp.spelling)) {
break;
}
q = p;
p = p->next;
}
if (!p) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->spelling = tmp.spelling;
pnew->tkcode = tmp.tkcode;
tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
}
}
}
}
函數(shù)InitKeywords
![]()
int keywordsLen = sizeof(keywords) / sizeof(TKWord);
InitKeywords(keywords, keywordsLen, tk_Hashtable);
該步驟的main函數(shù)
2.2 打開文件test.txt,每次取一行放入str中。
![]()
ifstream file;
file.open("test.txt", ios::in);
if (!file.is_open()) {
return;
}
string str;
while (getline(file, str)) {
...
}
該步驟的main函數(shù)
2.3 (在while函數(shù)中操作)對這一行str分割成一個個具有獨立意義的字符串,并分別存放到向量(動態(tài)數(shù)組)中。
![]()
/*定義一個向量word,用于存放分割后的字符串*/
vector<TKWord>word;
定義向量word
![]()
/*定義函數(shù),用于將str分割成一個個有獨立意義的字符串,并存放在向量word中*/
void split(vector<TKWord>& word,const string str) {
for (int i = 0; i < str.length(); i++) {
if (isalpha(str[i]) || str[i] == '_') {//函數(shù)名或變量名
TKWord tmp;
tmp.tkcode = TK_IDENT;
tmp.next = NULL;
while (isalnum(str[i])||str[i]=='_') {
tmp.spelling.push_back(str[i]);
i++;
}
word.push_back(tmp);
i--;
}
else if(str[i]=='"') {//字符串常量
TKWord tmp;
tmp.tkcode = TK_CSTR;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
i++;
while (str[i] != '"') {
tmp.spelling.push_back(str[i]);
i++;
}
tmp.spelling.push_back('"');
word.push_back(tmp);
}
else if (str[i] == '\'') {//字符常量
TKWord tmp;
tmp.tkcode = TK_CCHAR;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
i++;
while (str[i] != '\'') {
tmp.spelling.push_back(str[i]);
i++;
}
tmp.spelling.push_back('\'');
word.push_back(tmp);
}
else if (ispunct(str[i])) {//運算符
TKWord tmp;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
word.push_back(tmp);
}
else if (str[i] == ' ') {//空格
TKWord tmp;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
word.push_back(tmp);
}
else if(isdigit(str[i])){//純數(shù)字(目前將整型常量和浮點型常量考慮在一起)
TKWord tmp;
tmp.tkcode = TK_CINT;
tmp.next = NULL;
while (isdigit(str[i]) || str[i] == '.') {
tmp.spelling.push_back(str[i]);
i++;
}
word.push_back(tmp);
i--;
}
else if(str[i]=='\t') {//tab鍵
TKWord tmp;
tmp.next = NULL;
tmp.spelling = " ";
word.push_back(tmp);
}
}
}
定義分割函數(shù)split
![]()
if (str.empty()) {
continue;
}
word.clear();
split(word, str);
該步驟的main函數(shù)
2.4 (在while函數(shù)中操作)將word中存放好的一個個字符串們分別處理。首先,將字符串鏈接到哈希表上。通過哈希函數(shù)得到哈希值,通過哈希值在哈希表上定位,判斷對應位置是否為NULL:若為NULL,將該字符串所在的結構體鏈接到該位置;若不為NULL,由于采用鏈表法處理哈希沖突,故此時應該在該位置所鏈接的鏈表中不斷比較字符串直到找到匹配的字符串所在結構體,若最終沒有匹配成功,就申請一個新的結構體并將該字符串所在結構體的所有信息拷貝到新的結構體中,并將這個新結構體鏈接到鏈表表尾。然后,根據(jù)該字符串的token顏色打印該字符串。
![]()
/*顏色打印函數(shù)*/
void printColor(string str, int token) {
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
if (token >= TK_IDENT) {//變量名或者函數(shù)名為灰色
SetConsoleTextAttribute(h, FOREGROUND_INTENSITY);
}
else if (token >= KW_CHAR) {//關鍵字為綠色
SetConsoleTextAttribute(h, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
}
else if (token >= TK_CINT) {//整型常量、浮點型常量、字符常量、字符串常量等為褐色
SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_GREEN);
}
else {//運算符為紅色
SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY);
}
if (-1 == str[0]) {
printf("\n ENd Of File");
SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
}
else {
cout << str;
}
}
顏色打印函數(shù)
![]()
for (int i = 0; i < word.size(); i++) {
TKWord tmp = word[i];
if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->tkcode = tmp.tkcode;
/*string snew = tmp.spelling;
for (int j = 0; j < snew.size(); j++) {
pnew->spelling.push_back(snew[j]);
}*/
pnew->spelling = tmp.spelling;//拷貝字符串
tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
}
else {
TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
TKWord* q = p;
while (p != NULL) {
if (!p->spelling.compare(tmp.spelling)) {
word[i].tkcode = p->tkcode;
break;
}
q = p;
p = p->next;
}
if (!p) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->spelling = tmp.spelling;
pnew->tkcode = tmp.tkcode;
q->next = pnew;
}
}
printColor(word[i].spelling, word[i].tkcode);
該步驟的main函數(shù)
3 完整代碼
![]()
#include <string>
#include <Windows.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <ctype.h>
using namespace std;
/*通過枚舉對預置的字符串進行編號*/
enum e_TokenCode
{
/* 運算符及分隔符 */
TK_PLUS, // + 加號
TK_MINUS, // - 減號
TK_STAR, // * 星號
TK_DIVIDE, // / 除號
TK_MOD, // % 求余運算符
TK_EQ, // == 等于號
TK_NEQ, // != 不等于號
TK_LT, // < 小于號
TK_LEQ, // <= 小于等于號
TK_GT, // > 大于號
TK_GEQ, // >= 大于等于號
TK_ASSIGN, // = 賦值運算符
TK_POINTSTO, // -> 指向結構體成員運算符
TK_DOT, // . 結構體成員運算符
TK_AND, // & 地址與運算符
TK_OPENPA, // ( 左圓括號
TK_CLOSEPA, // ) 右圓括號
TK_OPENBR, // [ 左中括號
TK_CLOSEBR, // ] 右中括號
TK_BEGIN, // { 左大括號
TK_END, // } 右大括號
TK_SEMICOLON, // ; 分號
TK_COMMA, // , 逗號
TK_ELLIPSIS, // ... 省略號
TK_EOF, // 文件結束符
/* 常量 */
TK_CINT, // 整型常量
TK_CFLOAT, // 浮點型常量
TK_CCHAR, // 字符常量
TK_CSTR, // 字符串常量
/* 關鍵字 */
KW_CHAR, // char關鍵字
KW_SHORT, // short關鍵字
KW_INT, // int關鍵字
KW_VOID, // void關鍵字
KW_STRUCT, // struct關鍵字
KW_IF, // if關鍵字
KW_ELSE, // else關鍵字
KW_FOR, // for關鍵字
KW_CONTINUE, // continue關鍵字
KW_BREAK, // break關鍵字
KW_RETURN, // return關鍵字
/* 標識符 */
TK_IDENT // 函數(shù)名或變量名
};
typedef enum e_TokenCode tokencode;
/*存儲字符串的結構體定義*/
typedef struct TKWord {
int tkcode;
string spelling;
struct TKWord* next;
}TKWord, *pTKWord;
#define MAXKEY 50
void printColor(string str, int token);
int elf_hash(string key);
void InitKeywords(pTKWord keywords, int keywordsLen, pTKWord* tk_Hashtable);
void split(vector<TKWord>& word, const string str);
complier.h
![]()
#include "complier.h"
/*定義哈希函數(shù)*/
int elf_hash(string key) {
int h = 0, g, i = 0;
while (key[i]) {
h = (h << 4) + key[i++];
g = h & 0xf0000000;
if (g)
h ^= g >> 24;
h &= ~g;
}
return h % MAXKEY;
}
/*定義函數(shù),用于將靜態(tài)結構數(shù)組中各種預置的字符串及其token分別通過哈希公式映射并添加到哈希表中*/
void InitKeywords(pTKWord keywords, int keywordsLen, pTKWord* tk_Hashtable) {
for (int i = 0; i < keywordsLen; i++) {
TKWord tmp = keywords[i];
if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->tkcode = tmp.tkcode;
/*string snew = tmp.spelling;
for (int j = 0; j < snew.size(); j++) {
pnew->spelling.push_back(snew[j]);
}*/
pnew->spelling = tmp.spelling;//拷貝字符串
tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
}
else {
TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
TKWord* q = p;
while (p != NULL) {
if (!p->spelling.compare(tmp.spelling)) {
break;
}
q = p;
p = p->next;
}
if (!p) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->spelling = tmp.spelling;
pnew->tkcode = tmp.tkcode;
tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
}
}
}
}
/*定義函數(shù),用于將str分割成一個個有獨立意義的字符串,并存放在向量word中*/
void split(vector<TKWord>& word,const string str) {
for (int i = 0; i < str.length(); i++) {
if (isalpha(str[i]) || str[i] == '_') {//函數(shù)名或變量名
TKWord tmp;
tmp.tkcode = TK_IDENT;
tmp.next = NULL;
while (isalnum(str[i])||str[i]=='_') {
tmp.spelling.push_back(str[i]);
i++;
}
word.push_back(tmp);
i--;
}
else if(str[i]=='"') {//字符串常量
TKWord tmp;
tmp.tkcode = TK_CSTR;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
i++;
while (str[i] != '"') {
tmp.spelling.push_back(str[i]);
i++;
}
tmp.spelling.push_back('"');
word.push_back(tmp);
}
else if (str[i] == '\'') {//字符常量
TKWord tmp;
tmp.tkcode = TK_CCHAR;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
i++;
while (str[i] != '\'') {
tmp.spelling.push_back(str[i]);
i++;
}
tmp.spelling.push_back('\'');
word.push_back(tmp);
}
else if (ispunct(str[i])) {//運算符
TKWord tmp;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
word.push_back(tmp);
}
else if (str[i] == ' ') {//空格
TKWord tmp;
tmp.next = NULL;
tmp.spelling.push_back(str[i]);
word.push_back(tmp);
}
else if(isdigit(str[i])){//純數(shù)字(目前將整型常量和浮點型常量考慮在一起)
TKWord tmp;
tmp.tkcode = TK_CINT;
tmp.next = NULL;
while (isdigit(str[i]) || str[i] == '.') {
tmp.spelling.push_back(str[i]);
i++;
}
word.push_back(tmp);
i--;
}
else if(str[i]=='\t') {//tab鍵
TKWord tmp;
tmp.next = NULL;
tmp.spelling = " ";
word.push_back(tmp);
}
}
}
/*顏色打印函數(shù)*/
void printColor(string str, int token) {
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
if (token >= TK_IDENT) {//變量名或者函數(shù)名為灰色
SetConsoleTextAttribute(h, FOREGROUND_INTENSITY);
}
else if (token >= KW_CHAR) {//關鍵字為綠色
SetConsoleTextAttribute(h, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
}
else if (token >= TK_CINT) {//整型常量、浮點型常量、字符常量、字符串常量等為褐色
SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_GREEN);
}
else {//運算符為紅色
SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY);
}
if (-1 == str[0]) {
printf("\n ENd Of File");
SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
}
else {
cout << str;
}
}
complier.cpp
![]()
#include "complier.h"
/*定義一個靜態(tài)結構數(shù)組*/
static TKWord keywords[] = {
{TK_PLUS,"+",NULL},
{TK_MINUS,"-",NULL},
{TK_STAR,"*",NULL},
{TK_DIVIDE,"/",NULL},
{TK_MOD,"%",NULL},
{TK_EQ,"==",NULL},
{TK_NEQ,"!=",NULL},
{TK_LT,"<",NULL},
{TK_LEQ,"<=",NULL},
{TK_GT,">",NULL},
{TK_GEQ,">=",NULL},
{TK_ASSIGN,"=",NULL},
{TK_POINTSTO,"->",NULL},
{TK_DOT,".",NULL},
{TK_AND,"&",NULL},
{TK_OPENPA,"(",NULL},
{TK_CLOSEPA,")",NULL},
{TK_OPENBR,"[",NULL},
{TK_CLOSEBR,"]",NULL},
{TK_BEGIN,"{",NULL},
{TK_END,"}",NULL},
{TK_SEMICOLON,";",NULL},
{TK_COMMA,",",NULL},
{TK_ELLIPSIS,"...",NULL},
{TK_EOF,"End Of File",NULL},
{TK_CINT,"整形常量",NULL},
{TK_CFLOAT,"浮點型常量",NULL},
{TK_CCHAR,"字符常量",NULL},
{TK_CSTR,"字符串常量",NULL},
{KW_CHAR,"char",NULL},
{KW_SHORT,"short",NULL},
{KW_INT,"int",NULL},
{KW_VOID,"void",NULL},
{KW_STRUCT,"struct",NULL},
{KW_IF,"if",NULL},
{KW_ELSE,"else",NULL},
{KW_FOR,"for",NULL},
{KW_CONTINUE,"continue",NULL},
{KW_BREAK,"break",NULL},
{KW_RETURN,"return",NULL},
{40}
};
/*定義哈希表*/
TKWord* tk_Hashtable[MAXKEY] = { 0 };
/*定義一個向量word,用于存放分割后的字符串*/
vector<TKWord>word;
void main() {
int keywordsLen = sizeof(keywords) / sizeof(TKWord);
InitKeywords(keywords, keywordsLen, tk_Hashtable);
ifstream file;
file.open("test.txt", ios::in);
if (!file.is_open()) {
return;
}
string str;
while (getline(file, str)) {
if (str.empty()) {
continue;
}
word.clear();
split(word, str);
for (int i = 0; i < word.size(); i++) {
TKWord tmp = word[i];
if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->tkcode = tmp.tkcode;
/*string snew = tmp.spelling;
for (int j = 0; j < snew.size(); j++) {
pnew->spelling.push_back(snew[j]);
}*/
pnew->spelling = tmp.spelling;//拷貝字符串
tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
}
else {
TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
TKWord* q = p;
while (p != NULL) {
if (!p->spelling.compare(tmp.spelling)) {
word[i].tkcode = p->tkcode;
break;
}
q = p;
p = p->next;
}
if (!p) {
TKWord* pnew = new TKWord;
pnew->next = NULL;
pnew->spelling = tmp.spelling;
pnew->tkcode = tmp.tkcode;
q->next = pnew;
}
}
printColor(word[i].spelling, word[i].tkcode);
}
cout << endl;
}
}
main.cpp
4 測試文件及顯示結果
![]()
int split(vector<string> &word,const string str){
for(int i=0;i<str.length();i++){
if(str[i]==34){
string temp;
temp.push_back(str[i]);
i++;
while(str[i]!=34){
temp.push_back(str[i]);
i++;
}
temp.push_back(str[i]);
word.push_back(temp);
}else if(ispunct(str[i])||str[i]==' \b'){
string temp;
temp.push_back(str[i]);
word.push_back(temp);
}else if(isdigit(str[i])){
string temp;
while(isdigit(str[i])){
temp.push_back(str[i]);
++i;
}
if(str[i]=='.'){
++i;
if(isdigit(str[i])){
temp.push_back('.');
while(isdigit(str[i])){
temp.push_back(str[i]);
i++;
}
}else{
return -1;
}
}
word.push_back(temp);
--i;
}else if(isalpha(str[i])){
string temp;
while(isalnum(str[i])){
temp.push_back(str[i]);
i++;
}
word.push_back(temp);
--i;
}else if(str[i]=='\t'){
string temp=" ";
word.push_back(temp);
}
}
}
test.txt
![]()
5 尚需改進的地方
分析不完全。如沒有將所有運算符考慮進去;在分割函數(shù)中,函數(shù)名和變量名、數(shù)字的整型和浮點型也都沒有分開考慮。
6 經(jīng)驗和教訓
bug: 前面定義里含有string的結構體,后面用malloc申請一個新的結構體,并將舊的結構體拷貝到新結構體中,但是這期間拷貝string時總是報錯,在多次嘗試之后,最后發(fā)現(xiàn)將malloc換用new后程序正確運行。
教訓:不要將C和C++的操作混用!(這里用C語言的malloc函數(shù)申請一個包含C++獨用的string類型的結構體,這是會在后面的操作中出現(xiàn)錯誤)
![]()
posted on
2022-03-19 15:52
田園脆雞堡
閱讀( 159)
評論()
收藏
舉報
|