C语言集合程序打印笑脸而非字符问题求助
问题:布尔数组实现集合操作时出现字符乱码
现象
用布尔数组实现集合操作的C语言函数,运行时出现以下异常:
- O之前的字母显示为笑脸(随机乱码),O之后显示正常
- 打印集合并集时所有字母均显示为笑脸
- 尝试调换A和O的位置、改用
{'A','B',...}形式定义字符数组,问题仍存在
完整代码
#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define megisto_plithos 26 typedef bool typos_synolou[megisto_plithos]; typedef int stoixeio_synolou; void Dimiourgia(typos_synolou synolo); void Katholiko(typos_synolou synolo); void Eisagogi(stoixeio_synolou stoixeio, typos_synolou synolo); bool Melos(stoixeio_synolou stoixeio, typos_synolou synolo); bool IsaSynola(typos_synolou s1, typos_synolou s2); bool Yposynolo(typos_synolou s1, typos_synolou s2); void EnosiSynolou(typos_synolou s1, typos_synolou s2, typos_synolou enosi); void TomiSynolou(typos_synolou s1, typos_synolou s2, typos_synolou tomi); void DiaforaSynolou(typos_synolou s1, typos_synolou s2, typos_synolou diafora); void EmfanisiSynolou(typos_synolou synolo, char letters[]); int main() { char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; typos_synolou agglika_kefalaia[megisto_plithos]; Dimiourgia(agglika_kefalaia[megisto_plithos]); Katholiko(agglika_kefalaia[megisto_plithos]); EmfanisiSynolou(agglika_kefalaia[megisto_plithos], letters); typos_synolou S[megisto_plithos], T[megisto_plithos]; Dimiourgia(S[megisto_plithos]); Dimiourgia(T[megisto_plithos]); Eisagogi(0, S[megisto_plithos]); Eisagogi(1, S[megisto_plithos]); Eisagogi(2, S[megisto_plithos]); Eisagogi(3, S[megisto_plithos]); Eisagogi(0, T[megisto_plithos]); Eisagogi(2, T[megisto_plithos]); Eisagogi(4, T[megisto_plithos]); Eisagogi(6, T[megisto_plithos]); Eisagogi(8, T[megisto_plithos]); printf("\n"); EmfanisiSynolou(S[megisto_plithos], letters); printf("\n"); EmfanisiSynolou(T[megisto_plithos], letters); printf("\n"); if(IsaSynola(S[megisto_plithos], T[megisto_plithos])) { printf("ISA SYNOLA"); } else printf("NOT ISA SYNOLA"); printf("\n"); if(Yposynolo(S[megisto_plithos], T[megisto_plithos])) { printf("S YPOSYNOLO T"); } else printf("NOT S YPOSYNOLO T"); printf("\n"); if(Yposynolo(T[megisto_plithos], S[megisto_plithos])) { printf("T YPOSYNOLO S"); } else printf("NOT T YPOSYNOLO S"); typos_synolou enosi[megisto_plithos]; printf("\n"); EnosiSynolou(S[megisto_plithos], T[megisto_plithos], enosi[megisto_plithos]); EmfanisiSynolou(enosi[megisto_plithos], letters); printf("\n"); typos_synolou tomi[megisto_plithos]; TomiSynolou(S[megisto_plithos], T[megisto_plithos], tomi[megisto_plithos]); EmfanisiSynolou(tomi[megisto_plithos], letters); printf("\n"); typos_synolou diafora[megisto_plithos]; DiaforaSynolou(S[megisto_plithos], T[megisto_plithos], diafora[megisto_plithos]); EmfanisiSynolou(diafora[megisto_plithos], letters); return 0; } void Dimiourgia(typos_synolou synolo) { stoixeio_synolou i; for (i = 0; i < megisto_plithos; i++) synolo[i] = false; } void Katholiko(typos_synolou synolo) { stoixeio_synolou i; for (i = 0; i < megisto_plithos; i++) synolo[i] = true; } void Eisagogi(stoixeio_synolou stoixeio, typos_synolou synolo) { synolo[stoixeio] = true; } bool Melos(stoixeio_synolou stoixeio, typos_synolou synolo) { return synolo[stoixeio]; } bool IsaSynola(typos_synolou s1, typos_synolou s2) { stoixeio_synolou i; bool isa; isa = true; i=0; while (i < megisto_plithos && isa) if (Melos(i,s1) != Melos(i,s2)) isa = false; else i++; return isa; } bool Yposynolo(typos_synolou s1, typos_synolou s2) { stoixeio_synolou i; bool yposyn; yposyn = true; i=0; while (i < megisto_plithos && yposyn) if (Melos(i, s1) && !Melos(i, s2)) yposyn = false; else i++; return yposyn; } void EnosiSynolou(typos_synolou s1, typos_synolou s2, typos_synolou enosi) { stoixeio_synolou i; for (i = 0; i < megisto_plithos; i++) enosi[i] = Melos(i, s1) || Melos(i, s2); } void TomiSynolou(typos_synolou s1, typos_synolou s2, typos_synolou tomi) { stoixeio_synolou i; for (i = 0; i < megisto_plithos; i++) tomi[i] = Melos(i, s1) && Melos(i, s2); } void DiaforaSynolou(typos_synolou s1, typos_synolou s2, typos_synolou diafora) { stoixeio_synolou i; for (i = 0; i < megisto_plithos; i++) diafora[i] = Melos(i, s1) && (!Melos(i, s2)); } void EmfanisiSynolou(typos_synolou synolo, char letters[megisto_plithos]) { int i; for(i = 0; i < megisto_plithos; i++) { if(synolo[i] == true) { printf("%c ", letters[i]); } } }
问题原因
核心错误是集合变量的声明和参数传递完全错误:
- 类型定义误解:
typedef bool typos_synolou[megisto_plithos];已经将typos_synolou定义为一个包含26个bool的数组类型,声明单个集合时直接写typos_synolou 变量名;即可,不需要再加[megisto_plithos]——否则会变成包含26个集合的二维数组(26*26个bool)。 - 越界访问内存:比如
Dimiourgia(agglika_kefalaia[megisto_plithos]);中,agglika_kefalaia[megisto_plithos]是访问二维数组的第27个元素(索引从0开始),属于严重越界,会破坏内存中其他变量(比如letters数组)的内容,这就是乱码的根源。 - 前14个字符异常是内存布局巧合:越界操作刚好覆盖了
letters数组的前半部分,O是第15个字符(索引14),因此之后的字符未被影响。
修正方案
修改main函数中所有集合变量的声明和传递方式:
- 将
typos_synolou agglika_kefalaia[megisto_plithos];改为typos_synolou agglika_kefalaia; - 将
Dimiourgia(agglika_kefalaia[megisto_plithos]);改为Dimiourgia(agglika_kefalaia); - 同理,
typos_synolou S[megisto_plithos], T[megisto_plithos];改为typos_synolou S, T; - 所有传递这些变量的函数调用,都去掉
[megisto_plithos],比如Eisagogi(0, S);、EmfanisiSynolou(S, letters);等 - 集合运算的结果变量(
enosi、tomi、diafora)也做同样修改
修正后的main函数
int main() { char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; typos_synolou agglika_kefalaia; Dimiourgia(agglika_kefalaia); Katholiko(agglika_kefalaia); EmfanisiSynolou(agglika_kefalaia, letters); typos_synolou S, T; Dimiourgia(S); Dimiourgia(T); Eisagogi(0, S); Eisagogi(1, S); Eisagogi(2, S); Eisagogi(3, S); Eisagogi(0, T); Eisagogi(2, T); Eisagogi(4, T); Eisagogi(6, T); Eisagogi(8, T); printf("\n"); EmfanisiSynolou(S, letters); printf("\n"); EmfanisiSynolou(T, letters); printf("\n"); if(IsaSynola(S, T)) { printf("ISA SYNOLA"); } else printf("NOT ISA SYNOLA"); printf("\n"); if(Yposynolo(S, T)) { printf("S YPOSYNOLO T"); } else printf("NOT S YPOSYNOLO T"); printf("\n"); if(Yposynolo(T, S)) { printf("T YPOSYNOLO S"); } else printf("NOT T YPOSYNOLO S"); typos_synolou enosi; printf("\n"); EnosiSynolou(S, T, enosi); EmfanisiSynolou(enosi, letters); printf("\n"); typos_synolou tomi; TomiSynolou(S, T, tomi); EmfanisiSynolou(tomi, letters); printf("\n"); typos_synolou diafora; DiaforaSynolou(S, T, diafora); EmfanisiSynolou(diafora, letters); return 0; }
内容的提问来源于stack exchange,提问作者Shady Sheen
相关产品推荐
相关产品推荐

