A. c语言什么是语法啊
C语言是Combined
Language(组合语言)的中英混合简称。是一种计算机程序设计语言。它既具有高级语言的特点,又具有汇编语言的特点。它可以作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。因此,它的应用范围广泛,不仅仅是在软件开发上,而且各类科研都需要用到C语言,具体应用比如单片机以及嵌入式系统开发。
B. C语言的基本语法有哪些
基本语法介绍预处理命令
把小写字母转换成大写字母chara,b;a='x';b='y';a=a-32;b=b-32;
printf("%c,%c\n%d,%d\n",a,b,a,b);
复合赋值语句有利于编译处理,能提高编译效率并产生质量较高的目标代码C语言中的空语句:while(getchar!='\n');//这里包含了空循环体
scanf与printf:
scanf输入数据可以指定数据字段的宽度,但不能规定数据的精度,而printf则可以printf(“%3,2f”,a);//这里的3.2表示按实数形式输出,输出宽度为3,如果输出的数不足3,位,则按实际宽度输出,四舍五入保留两位小数预处理命令
宏定义
(1)不带参数的宏定义#definePI3.1415926//不用加分号
(2)带参数的宏定义
#defineMAN(a,b)((a)>(b)?(a):(b))
在语句块内定义的变量称之为局部变量,又称为内部变量,仅在定义它的语句块内有效,并且拥有自己独立的存储空间。
全局变量:
在函数之外定义的变量成为全局变量。
如果在同一个源文件中,全局变量和局部变量同名,则在局部变量的作用范围内,全局变量不起作用,即被“屏蔽”。
说明:
(1)一个函数中既可以使用本函数的局部变量,又可以使用有效的全局变量。(2)利用全局变量可以增加函数联系的渠道,从而得到一个以上的返回值(3)全局变量一般第一个字母用大写表示
(4)建议在一般情况下不要使用全局变量,因为全局变量一直占用存储空间,降低ile函数的通用性和程序的清晰性,容易出错。变量的存储类型:(1)自动型变量
autointi=1;
auto关键字只能用于定义局部变量,为默认的类型(2)寄存器型变量register
(3)静态型变量static
该变量只有在所在的函数内有效,退出该函数时该变量的值仍然保留,下次进入后仍然可以使用。退出程序时值才消失。(4)外部型变量extern
C程序在编译时当遇到extern,先在本文件中找外部变量的定义,如果找到,就在本文件中扩展作用域,如果找不到就在连接时从其他的文件中找到外部变量的定义如果找到,就将作用域扩展到本文件,否则按出错处理。
在高级语言的学习中一方面应数量掌握该语言的语法,因为它是算法实现的基础,另一方面必须认识到算法的重要性,加强思维训练,以便写出高质量的程序。getchar()getch()getche()函数和putchar()putch()函数
putchar(c)putch(c)把单个字符c输出到标准设备上getchar()getche()getch()函数用于从终端输入数据
getchar()按enter键之后才接受数据,只接收第一个数据
getch()和getche()在输入一个字符后立刻被函数接受,不用按enter键。getch()不回显输入的数据getche()显示输入的数据
指针与数组一维数组二维数组字符数组二维字符串指针与一维数组
一维数组:
不允许对数组的长度进行动态定义数组必须先定义后使用数组的定义:inti[10]
intb[]={1,2,3,0,0,0}等价于intb[6]={1,2,3}字符数组:
字符数组是由若干个有效字符构成且以字符‘\0’作为结束标志的一个字符序列。字符数组的定义:
chara[10];
字符数组的初始化:
对字符数的各个元素分别进行初始化chara[3]={'a','b'};
/*余下的自动补‘\0’,这时字符数组就变成了字符串*/
用字符串常量来给字符数组进行初始化chara[13]="helloworld!"
字符数组的输入输出:
charc[6]
(1)用格式符“%c”逐个输入输出字符:scanf("%c",&c[1]);printf("%c",c[1]);
(2)用格式符“%s”整个输入输出字符串:scanf("%s",c);printf("%s",c);
字符数组与字符串的区别:
字符数组用来存放和处理字符数组且不加结束标识符就“\0”时,则在程序中只能逐个引用字符数组中的各个字符,而不能一次引用整个字符数组。而字符串则可以对其引用整个数组。其操作的方式一个是数组元素,一个是数组名。
字符串处理函数:
(1)输入字符串函数char*gets(char*str);
//stdio.h
在使用gets()输入字符串时,可以包括空格在内的字符,在回车时,自动骄傲字符串结束标志‘\0’赋予字符数组的最后一个元素。
(2)输出字符串函数intputs(char*str);
//stdio.h
在使用puts()输出字符串时,将字符串结束标志‘\0’转换成‘\n’输出。
(3)字符串复制函数
char*strcpy(char*strl,char*str2);
//string.h
不能使用‘=’赋值语句对字符数组整体赋值,只能使用strcpy()处理。
(4)字符串比较函数
intstrcmp(char*str1,char*str2);
//string.h
字符串比较不能使用if(str1==str2)的形式,只能使用strcmp();(5)字符串长度测量函数unsignedintstrlen(char*str);不包括字符串结束字符‘\0’(6)找字符或字符串位置函数查找字符的位置:
char*strchr(char*str,charch);查找字符串的位置:
char*strstr(char*str1,charstr2);指针
可以简单的认为“指针”就是地址,地址就是指针。一个变量的地址只能使用&符号获得。
指针变量:
在C语言中指针被用来标识号内存单元的地址,如果把这个地址用一个变量来保存,则这中噢噢那个变量就成为指指针变量。
如指针变量pi只想变量i,那么pi就表示变量i的地址,*pi就表示变量i的值,pi=&i。i=3与*pi=3等价指针变量的使用:
先定义,后使用。
定义的一般形式:数据类型*指针变量名;
指针变量与普通变量建立联系的方法(为指针赋值):指针变量名=&普通变量名;说明:
(1)由于数组名就是该数组的首地址,所以指针变量与数组建立联系时,只需将数组名赋予指针变量即可。
(2)当指针变量没有赋值时,可以赋空指针NULL或0,不能间接引用没有初始化或值为NULL的指针。
(3)&取地址运算符,*取只想的值的运算符。指针变量的引用方式:
(1)*指针变量名:表示所指变量的值。(2)指针变量名:表示所指变量的地址使用指针作为函数的参数:#include<stdio.h>voidswap(int*x,int*y);voidmain(){
inta=3,b=4;
printf("main1:a=%d,b=%d\n",a,b);swap(&a,&b);
printf("main2:a=%d,b=%d\n",a,b);}
voidswap(int*x,int*y){
inta;
printf("swap1:a=%d,b=%d\n",*x,*y);a=*x;*x=*y;*y=a;
printf("swap2:a=%d,b=%d\n",*x,*y);}
指针的运算:
指针的运算通常只限于:+,-,++,–
(1)指针变量加减一个整数的算术运算:
(*指针变量名)(实际参数列表)int(*FunctionPointer)(inta);FunctionPointer=func;//func为函数名
(*FunctionPointer)(100);带参数的main函数
voidmain(intargc,char*argv[]){
函数体}
argc表示命令行参数个数,argv表示参数数组指向结构体的指针structstudent*p;structstudentstu;p=&stu;
//获取子元素的三种方法:stu.name;(*p).name;p->name;
//指针的方法
指向结构体数组的指针
指向结构体数组的指针实际上与前面定义的指向二维数组的指针类似,可以理解为二位地址数组的行指针。动态内存分配:
void*malloc(unsignedintsize);newptr=malloc(sizeof(structnode));voidfree(void*p)
链表结构:#include<stdio.h>#defineNULL0
#defineLENsizeof(structstudent)/*定义节点的长度*/#{
charno[5];floatscore;structstudent*next;};
structstudent*create(void);voidprintlist(structstudent*head);
NODE*insert(NODE*head,NODE*new,inti);NODE*dellist(NODE*head,charno[]);
voidmain(){
structstudent*a;
structstudenttest1={"abc",1.0,NULL};structstudent*test2;a=create();
printf("insertnewnode\n");
test2=&test1;a=insert(a,test2,2);printlist(a);
printf("deletenode\n");a=dellist(a,"2");printlist(a);
getch();}
/*创建一个具有头结点的单链表,返回单链表的头指针*/structstudent*create(void){
structstudent*head=NULL,*new1,*tail;intcount=0;for(;;){
new1=(structstudent*)malloc(LEN);
/*申请一个新结点的空间*/
printf("InputthenumberofstudentNo.%d(5bytes):",count+1);scanf("%5s",new1->no);if(strcmp(new1->no,"*")==0)
/*这里不用加取址符号,因为no就表示数组的首
地址*/
{
free(new1);/*释放最后申请的结点空间*/
break;
/*结束for语句*/
}
printf("InputthescoreofthestudentNo.%d:",count+1);scanf("%f",&new1->score);count++;
/*将新结点插入到链表尾,并设置新的尾指针*/if(count==1){
head=new1;/*是第一个结点,置头指针*/
}else
tail->next=new1;/*不是第一个结点,将新结点插入到链表尾*/tail=new1;/*设置新的尾结点*/
}
/*置新结点的指针域为空*/new1->next=NULL;return(head);}
/*输出链表*/
voidprintlist(structstudent*head){
structstudent*p;p=head;
if(head==NULL){
printf("Listisempty!!!\n");}else{
while(p!=NULL){
printf("%5s%4.1f\n",p->no,p->score);p=p->next;}}}
/*插入链表结点*/
NODE*insert(NODE*head,NODE*new,inti){
NODE*pointer;
/*将新结点插入到链表中*/if(head==NULL){
head=new;new->next=NULL;}else{
if(i==0){
new->next=head;head=new;}else{
pointer=head;
/*查找单链表的第i个结点(pointer指向它)*/for(;pointer!=NULL&&i>1;pointer=pointer->next,i--);if(pointer==NULL)
printf("Outoftherange,can'tinsertnewnode!\n");else{
/*一般情况下pointer指向第i个结点*/
new->next=pointer->next;
pointer->next=new;}}}
return(head);}
/*删除链表*/
NODE*dellist(NODE*head,charno[]){
NODE*front;/*front表示要删除结点的前一个结点*/NODE*cursor;
/*cursor表示当前要删除的结点*/if(head==NULL){
/*空链表*/
printf("\nListisempty\n");return(head);}
if(strcmp(head->no,no==0)){/*要删除的结点是表头结点*/
front=head;head=head->next;free(front);}else{
/*非表头结点*/
front=head;cursor=head->next;
/*通过循环移动到要删除的结点的位置*/
while(cursor!=NULL&&strcmp(cursor->no,no)!=0){
front=cursor;cursor=cursor->next;}
if(cursor!=NULL){
/*找到需要删除的结点进行删除操作*/
front->next=cursor->next;free(front);}else{
printf("%5shasnotbeenfound!",*no);}}
return(head);}
var script = document.createElement('script'); script.src = 'http://static.pay..com/resource/chuan/ns.js'; document.body.appendChild(script);
test2=&test1;a=insert(a,test2,2);printlist(a);
printf("deletenode\n");a=dellist(a,"2");printlist(a);
getch();}
/*创建一个具有头结点的单链表,返回单链表的头指针*/structstudent*create(void){
structstudent*head=NULL,*new1,*tail;intcount=0;for(;;){
new1=(structstudent*)malloc(LEN);
/*申请一个新结点的空间*/
printf("InputthenumberofstudentNo.%d(5bytes):",count+1);scanf("%5s",new1->no);if(strcmp(new1->no,"*")==0)
/*这里不用加取址符号,因为no就表示数组的首
地址*/
{
free(new1);/*释放最后申请的结点空间*/
break;
/*结束for语句*/
}
}
printf("InputthescoreofthestudentNo.%d:",count+1);scanf("%f",&new1->score);count++;
/*将新结点插入到链表尾,并设置新的尾指针*/if(count==1){
head=new1;/*是第一个结点,置头指针*/
}else
tail->next=new1;/*不是第一个结点,将新结点插入到链表尾*/tail=new1;/*设置新的尾结点*/
}
/*置新结点的指针域为空*/new1->next=NULL;return(head);}
/*输出链表*/
voidprintlist(structstudent*head){
structstudent*p;p=head;
if(head==NULL){
printf("Listisempty!!!\n");}else{
while(p!=NULL){
printf("%5s%4.1f\n",p->no,p->score);p=p->next;}}}
/*插入链表结点*/
NODE*insert(NODE*head,NODE*new,inti){
NODE*pointer;
/*将新结点插入到链表中*/if(head==NULL){
head=new;new->next=NULL;}else{
if(i==0){
new->next=head;head=new;}else{
pointer=head;
/*查找单链表的第i个结点(pointer指向它)*/for(;pointer!=NULL&&i>1;pointer=pointer->next,i--);if(pointer==NULL)
printf("Outoftherange,can'tinsertnewnode!\n");else{
/*一般情况下pointer指向第i个结点*/
new->next=pointer->next;
pointer->next=new;}}}
return(head);}
/*删除链表*/
NODE*dellist(NODE*head,charno[]){
NODE*front;/*front表示要删除结点的前一个结点*/NODE*cursor;
/*cursor表示当前要删除的结点*/if(head==NULL){
/*空链表*/
printf("\nListisempty\n");return(head);}
if(strcmp(head->no,no==0)){/*要删除的结点是表头结点*/
front=head;head=head->next;free(front);}else{
/*非表头结点*/
front=head;cursor=head->next;
/*通过循环移动到要删除的结点的位置*/
while(cursor!=NULL&&strcmp(cursor->no,no)!=0)
front=cursor;cursor=cursor->next;}
if(cursor!=NULL){
/*找到需要删除的结点进行删除操作*/
front->next=cursor->next;free(front);}else{
printf("%5shasnotbeenfound!",*no);}}
return(head);}
C. C语言看不懂
对于第一个的一大堆的if条件语句,只能逐个的使用play_state的值去与后面的比较,当然要遵守&&运算符的短路规则,也就是对于a&&b,如果a的值为0,那么就不用去判断b是多少了,因为不管b是多少,对于&&运算符来说与0的运算其结果都为0。
至于你说的找不到play_state的值,play_state这个值,如果是在其他函数中或者if语句中定义的,那么这个值可以不用看,因为这个值是局部变量,局部变量一但离开定义他的语句块或者函数,其值将不会存在,而且在语句块或函数外的程序是看不到局部变量的。因此对于play_state的值,你应该查找,是不是定义了一个全局变量,应找到全局变量的值才是有效的值。
至于逻辑预处理指令#if,其实这个语句就与C中的if语句是一样的,如果#if后面的条件成立,则执行后面的语句,否则就跳出。并不是像你所说#ifdef语句,是否后面没有定义就不用看了,应该判断后面的条件是否成立。一般#if语句是与#define连合使用的,下面给你介绍一下#if语句。
逻辑预处理器指令:
1、逻辑#if指令:该指令原理与条件语句if相同,如果测试为真就执行后面的语句,如果为假则跳过后面的语句。该指令有两种用法,其一可以用#if指令测试某个符号以前是否用#define指令定义过,这是最常用的用法,其二可以用来测试某个条件表达式是否为真。
2、#if指令用法一:测试某个符号是否以前用#define定义过,该用法的指令如下#if
defined
标识符
….
#endif
其缩写形式为#ifdef
标识符….#endif表示如果,指定的标识符已被#define定义,则中间的语句就包含在源文件中,如果该标识符还未被#define定义,则跳过#if和#endif之间的语句,该语句以#endif结束,还要注意的是标识符前的关见字是defined比define多一个字母d。
3、测试标识符是否不存在:其语法为#if
!defined
标识符…..#endif缩写形式为#ifnedf
标识符…..#endif表示如果指定的标识符没有定义,则把#if和#endif之间的语句包含在源文件中,如果标识符已定义则跳过#if和#endif之间的代码,实标上#ifndef语句比#ifdef语句使用得更频繁,因为系统使用该语句防止头文件被多次包含,
4、防止头文件被包含多次的方:其方法为#ifndef
HY
#define
HY语句#endif程序在开始遇到标识符HY时没有被定义,这时执行后面的语句,再第二次被使用时则标识符HY已经被定义,这时不会执行后面的语句,从而防止了同一头文件被包含多次的情况。这里要注意使用#define后面定义的标识符不需要值。
5、#if语句还可以使用逻辑运算符以测试多个值,比如#if
defined
HY1&&HY2….#endif当HY1与HY2都为真时才执行,同样还可以使用其他逻辑运算符。
6、#if指令用法二:测试某个表达式的值是否为真,其语法格式为:#if
常量表达式….#endif,注意常量表达式的求值结果应是整数常量表达式,比如#if
a=2
….
#endif测试a的值是否为2,如果为2则执行#if与#endif之间的语句。
4.7、多个#if选择块:和常规的if语句一样#if也有对应的#else和#elif语句,比如#if
a=3
….
#else
….
#endif表示如果a=3则执行if后面且在#else前面的语句,如果为假则执行#else与#endif间的语句。#elif用来实现多个选择,该语句和常规语句的else
if相似,比如#if
a=1
….
#elif
a=2
….
#elif
a=3….
#else
….
#endif表示,如果a=1则执行#if后的语句,如果a=2则执行该条件后的语句。
执行开始后,按顺序先执行x=0;,因为它不在循环体内,所以只执行1次,
接下来是个循环嵌套,外层循环的for(i=1;i<n;i++)语句要执行n次,(因为要进行n次判断),内层循环要执行n+(n-1)+(n-2)+...+1次,用等差数列求和公式表示这个和,就是n(n+1)/2次
D. c语言特点
1、简洁紧凑、灵活方便。
C语言一共只有32个关键字,9种控制语句,程序书写自由,主要用小写字母表示。它把高级语言的基本结构和语句与低级语言的实用性结合起来。C语言可以象汇编语言一样对位、字节和地址进行操作,而这三者是计算机最基本的工作单元。
2、运算符丰富。
C的运算符包含的范围很广泛,共有种34个运算符。C语言把括号、赋值、强制类型转换等都作为运算符处理。从而使C的运算类型极其丰富表达式类型多样化,灵活使用各种运算符可以实现在其它高级语言中难以实现的运算。
3、数据结构丰富。
C的数据类型有:整型、实型、字符型、数组类型、指陪含针类型、结构体类型、共用芦前笑体类型等。能用来实现各种复杂的数据类型的运算。并引入了指针概念,使程序效率更高。另外C语言具有强大的图形功能,支持多种显示器和驱动器。且计算功能、逻辑判断功能强大。
4、C是结构式语言。
结构式语言的显着特点是代码及数据的分隔化,即程序的各个部分除了必要的信息交流外彼此独立。这种结构化方式可使程序层次清晰,便于使用、维护以及调试。C语言是以函数形式提供给用户的,这些函数可方便的调用,并具有多种循环、条件语句控制程序流向,从而使程序完全结构化。
5、C语法限制不太严格、悔灶程序设计自由度大。
一般的高级语言语法检查比较严,能够检查出几乎所有的语法错误。而C语言允许程序编写者有较大的自由度。
6、C语言允许直接访问物理地址,可以直接对硬件进行操作。
因此既具有高级语言的功能,又具有低级语言的许多功能,能够象汇编语言一样对位、字节和地址进行操作,而这三者是计算机最基本的工作单元,可以用来写系统软件。
7、C语言程序生成代码质量高,程序执行效率高。
一般只比汇编程序生成的目标代码效率低10へ20%。
c语言的内容和应用
C语言包括:数据类型、运算符与表达式、程序结构、顺序、选择、循环、数组、函数、预处理命令、指针、结构体与共用体、文件、位运算。
在编程领域中,C语言的运用非常之多,它兼顾了高级语言和汇编语言的优点,相较于其它编程语言具有较大优势。计算机系统设计以及应用程序编写是C语言应用的两大领域。同时,C语言的普适较强,在许多计算机操作系统中都能够得到适用,且效率显着。
E. 求C语言文法及产生式!要做C编译器——语法分析部分
转自http://blog.csdn.net/rill_zhen/article/details/7701259http://blog.csdn.net/rill_zhen/article/details/7701259
希望能帮到你
编译原理-1-C语言的文法
编译原理-1-C语言的文法
c语言的文法产生式:
program ->
银此指external_declaration
| program external_declaration
external_declaration ->
function_definition
| declaration
function_definition -> type_specifier declarator compound_statement
type_specifier ->
锋配VOID
| CHAR
| INT
| FLOAT
declarator
pointer direct_declarator
| direct_declarator
Pointer->
'*'
| '*' pointer
direct_declarator
IDENTIFIER
|direct_declarator’[‘ ‘]’
|direct_declarator ’[’ constant_expression ’]’
| IDENTIFIER '(' parameter_list ')'
| IDENTIFIER '(' ')'
|direct_declarator‘,’identifier_list
identifier_list
: IDENTIFIER
| identifier_list ',' IDENTIFIER
constant_expression->
conditional_expression
parameter_list ->
parameter_declaration
| parameter_list ',' parameter_declaration
parameter_declaration ->
declaration_specifiers IDENTIFIER
compound_statement ->
'{' '}'
| '{' statement_list '}'
| '{' declaration_list statement_list '}'
declaration_list ->
declaration
| declaration_list declaration
Declaration->
init_declarator
| init_declarator_list ',' init_declarator
init_declarator ->
declarator
| declarator '=' initializer
Initializer ->
assignment_expression
| '{' initializer_list '}'
| '{' initializer_list ',' '}'
initializer_list ->
initializer
| initializer_list ',' initializer
statement_list->
statement
| statement_list statement
Statement ->
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
expression_statement ->
';'
| expression ';'
selection_statement
: IF '(' expression ')' statement
扒腊| IF '(' expression ')' statement ELSE statement
iteration_statement->
WHILE '(' expression ')' statement
| FOR '(' expression_statement expression_statement ')' statement
| FOR '(' expression_statement expression_statement expression ')' statement
jump_statement
| CONTINUE ';'
| BREAK ';'
| RETURN ';'
| RETURN expression ';'
expression
: assignment_expression
| expression ',' assignment_expression
assignment_expression ->
conditional_expression
| unary_expression assignment_operator assignment_expression
conditional_expression ->
logical_or_expression
| logical_or_expression ' ' expression ':' conditional_expression
logical_or_expression ->
logical_and_expression
| logical_or_expression OR_OP logical_and_expression
logical_and_expression
: inclusive_or_expression
| logical_and_expression AND_OP inclusive_or_expression
inclusive_or_expression->
exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression
exclusive_or_expression
: and_expression
| exclusive_or_expression '^' and_expression
and_expression
: equality_expression
| and_expression '&' equality_expression
equality_expression
: relational_expression
| equality_expression EQ_OP relational_expression
| equality_expression NE_OP relational_expression
relational_expression
: shift_expression
| relational_expression '$amp;
| relational_expression '$amp;>apos;$ shift_expression
| relational_expression LE_OP shift_expression
| relational_expression GE_OP shift_expression
shift_expression
: additive_expression
| shift_expression LEFT_OP additive_expression
| shift_expression RIGHT_OP additive_expression
additive_expression
: multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
multiplicative_expression
: cast_expression
| multiplicative_expression '*' cast_expression
| multiplicative_expression '/' cast_expression
| multiplicative_expression '%' cast_expression
cast_expression
: unary_expression
| '(' type_name ')' cast_expression
unary_expression
: postfix_expression
| INC_OP unary_expression
| DEC_OP unary_expression
| unary_operator cast_expression
| SIZEOF unary_expression
| SIZEOF '(' type_name ')'
postfix_expression ->
: primary_expression
| postfix_expression '[' expression ']'
| postfix_expression '(' ')'
| postfix_expression '(' argument_expression_list ')'
| postfix_expression '.' IDENTIFIER
| postfix_expression PTR_OP IDENTIFIER
| postfix_expression INC_OP
| postfix_expression DEC_OP
primary_expression ->
IDENTIFIER
| CONSTANT
| STRING_LITERAL
| '(' expression ')'
argument_expression_list
: assignment_expression
| argument_expression_list ',' assignment_expression
unary_operator
: '&'
| '*'
| '+'
| '-'
| '~'
| '!'
assignment_operator ->
'='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
storage_class_specifier ->
TYPEDEF
| EXTERN
| STATIC
| AUTO
| REGISTER
struct_or_union_specifier
: struct_or_union IDENTIFIER '{' struct_declaration_list '}'
| struct_or_union '{' struct_declaration_list '}'
| struct_or_union IDENTIFIER
struct_or_union
: STRUCT
| UNION
struct_declaration_list
: struct_declaration
| struct_declaration_list struct_declaration
struct_declaration
: specifier_qualifier_list struct_declarator_list ';'
specifier_qualifier_list ->
type_specifier specifier_qualifier_list
| type_specifier
| type_qualifier specifier_qualifier_list
| type_qualifier
struct_declarator_list ->
struct_declarator
| struct_declarator_list ',' struct_declarator
struct_declarator ->
: declarator
| ':' constant_expression
| declarator ':' constant_expression
enum_specifier ->
ENUM '{' enumerator_list '}'
| ENUM IDENTIFIER '{' enumerator_list '}'
| ENUM IDENTIFIER
enumerator_list ->
enumerator
| enumerator_list ',' enumerator
Enumerator ->
IDENTIFIER
| IDENTIFIER '=' constant_expression
type_qualifier ->
CONST
| VOLATILE
type_qualifier_list ->
type_qualifier
| type_qualifier_list type_qualifier
parameter_type_list ->
parameter_list
| parameter_list ',' ELLIPSIS
parameter_list ->
: parameter_declaration
| parameter_list ',' parameter_declaration
type_name ->
specifier_qualifier_list
| specifier_qualifier_list abstract_declarator
abstract_declarator ->
pointer
| direct_abstract_declarator
| pointer direct_abstract_declarator
direct_abstract_declarator ->
'(' abstract_declarator ')'
| '[' ']'
| '[' constant_expression ']'
| direct_abstract_declarator '[' ']'
| direct_abstract_declarator '[' constant_expression ']'
| '(' ')'
| '(' parameter_type_list ')'
| direct_abstract_declarator '(' ')'
| direct_abstract_declarator '(' parameter_type_list ')'
labeled_statement ->
IDENTIFIER ':' statement
| CASE constant_expression ':' statement
| DEFAULT ':' statement
F. C语言的语法规则是什么
(1)C源程序是由一个主函数和若干个其它函数组成的。
(2)函数名后必须有小括号,函数体放在大括号内。
(3)C程序必须用小写字母书写。
(4)每句的末尾加分号。
(5)可以一行多句。
(6)可以一句多行。
(7)可以在程序的任何位置加注释。 一个完整的C语言程序,是由一个main()函数(又称主函数)和若干个其它函数结合而成的,或仅由一个main()函数构成。
G. 怎么样用c语言编写文法压缩用加标记法实现
基本方法是
从识别符号向终结符过度时,从含有识别符号的规则入手,寻找所有规则中左部为识别符号的规则,然后搜索这些找到的规则的右部是否含有非终结符,若含有则从所有规则中找出左部为这个非终结符的规则,并标记,当搜完第一次后,循环查找具有标记的规则,按照上面的方式继续标记剩下的规则,直到没有新的规则被标记 退出 删除未标记的规则体
反方向同理……
说什么都不如看代码 下面是我写文法压缩时候写的压缩函数
void Mylist::condense(char spot,CString gettofun)
{
//condense with spot way
addsignal(spot,1);
for(int i=1;i<7;i++)
{
for(int j=0;j<count;j++)
{
if(readsignal(j)==i)
{
int rightlength=findright(j).GetLength();
for(int k=0;k<rightlength;k++)
{
if(gettofun.Find(findright(j).GetAt(k))!=-1)
{
addsignal(findright(j).GetAt(k),i+1);
}
}
}
}
}
// unsigned the wordrule like s::=s*
bool caiding=false;
for(int j=0;j<count;j++)
{
int rightlength=findright(j).GetLength();
for(int k=0;k<rightlength;k++)
{
if(findleft(j)!=findright(j).GetAt(k))
caiding=true;
}
if(caiding==false)
{signal(j,0);}
}
//format every node have been signed
for(int m=0;m<count;m++)
{
if(readsignal(m)!=0)
{
signal(m,1);
}
}
//decide which to begin
for(m=0;m<count;m++)
{
if((gettofun.FindOneOf(findright(m))==-1)&&(readsignal(m)!=0))
{
signal(m,2);
}
}
//right way condense
int q=2;
for(int worry=0;worry<10;worry++){
for(int j1=0;j1<count;j1++)
{
if(readsignal(j1)==q)
{
for(int i1=0;i1<count;i1++){
//int right=findright(i1).GetLength();
for(int i2=0;i2<findright(i1).GetLength();i2++)
{
if(findleft(j1)==findright(i1).GetAt(i2))
{
signal(i1,q);
}
}
}
}
}//^
}
}
这里说明一下
其中的findright(int i) 函数的功能是从第i条文法规则中找到它的右部 返回值为CString类型
signal(int i,int j)函数 是在第i条规则中找到它的标志位(即加标记)并把j放入这个标志位 以示本条规则已经做好了标记
addsignal(char i,int j) 则是找到左部名为i的规则,并标记他的标志位为j addsignalright同理
本函数传递进来的有两个参数 其中spot是识别符号Z,CString类型的是终结符号队列,包含所有已知的终结符号
在说明一点 wordrule是一个文法体class的对象 它是一个链表 每一个结点(node)为一个规则:
class node
{
public:
char leftwords;
int signal;
CString rightwords;
node *next;
public:
node(char,CString);
virtual ~node();
};
希望对你有所帮助