问答题
【程序说明】
下列文法可用来描述化学分子式的书写规则(例如,A12(C03)、Cu(OH)2):
λ→β|βλ
β→δ|δn
δ→ξ|ξθλ
其中,λ是一个分子式;δ或是一个元素,或是一个带括号的(子)分子式,元素或是一个大写字母(记为ξ),或是一个大写字母和一个小写字母(记为ξθ);β或是一个δ,或是在δ之后接上一个整数n,δn表示β有n个δ的元素或(子)分子式。一个完整的分子式由若干个β组成。
当然一个正确的分子式除符合上述文法规则外,还应满足分子式本身的语义要求。下面的程序输入分子式,按上述文法分析分子式,并计算出该分子式的分子量。例如,元素H的原子量是1,元素O的原子量是16。输入分子式H2O,程序计算出它的分子量为重18(1×2+16)。程序中各元素的名及它的原子量从文件atom.dat中读入。
【程序】
#include <stdio.h>
#include <string.h>
#define MAXN 300
#define CMLEN 30
struct elem{
char name[3];/*元素名*/
double v; /*原子量*/
}nTbl[MAXN];
char cmStr[CMLEN], *pos;
int c;
FILE *fp;
double factor();
double atom() /*处理文法符号δ*/
{
char w[3]; int i; double num;
while((c = *pos++)=="|| c==’\t’); /* 略过空白字符 */
if(c==’\n’) return 0.0;
if(c>=’A’ && c<=’Z’){/* 将元素名存入W*/
w[i=0]=c; c=*pos++;
if(c>=’a’ && c<=’z’) w[++i]=c;
else pos--;
w[++i]=’\0’;
for(i=0; nTbl[i].v>0.0; i++)
if(strcmp(w, nTbl[i].name)==0) return nTbl[i].v;
printf("\n 元素表中没有所输入的元素: \t%s\n",w);
return -1.0;
}
else if(c==’(’){
if((num = (1) <0.0)return -1.0; /* 包括可能为空的情况 */
if(*pos++ !=’)’){
printf(" 分子式中括号不匹配!\n");
return -1.0;
}
return num;
}
printf("分子式中存在非法字符: \t%c\n",c);
return -1.0;
}
double mAtom() /* 处理文法符号β*/
{
double num; int n=1;
if((num = (2) )<0.0) return -1.0;
c = *pos++;
if(c>=’0’&& c <=’9’){
n=0;
while(c>=’0’ && c<=’9’){
n= (3) ;
c=*pos++;
}
}
pos--;
return num *n;
}
double factor() /* 处理文法符号λ */
{
double num=0.0, d;
if((num=mAtom())<0.0) return -1.0;
while(*pos>=’A’ && *pos<= ’Z’ || *pos==’(’){
if((d= (4) <0.0) return -1.0;
}
return num;
}
void main()
{
char fname[]="atom.dat"; /*元素名及其原子量文件*/
int i; double num;
if((fp=fopen(fname, "r"))==NULL){/* 以读方式打开正文文件*/
printf("Can not open %s file.\n", fname);
return;/* 程序非正常结束 */
}
i=0;
while(i<MAXN && fscanf(fp, "%s%lf", nTbl[i].name, &nTbl[i].v) == 2)i++;
fclose(fp);
nTbl[i].v=-1.0;
while(I){ /* 输入分子式和计算分子量循环,直至输入空行结束*/
printf ("\n 输入分子式!(空行结束)\n");
gets(cmStr);
pos=cmStr;
if(cmStr[0]==’\0’)break;
if((num=factor())>0.0)
if (*pos != ’\0’)printf("分子式不完整!\n");
else printf(" 分子式的分子量为 %f\n", num);
}
}
【参考答案】
(1) factor() (2) atom() (3) n* 10+c-’0’ (4) mAtom()或factor()......
(↓↓↓ 点击下方‘点击查看答案’看完整答案 ↓↓↓)