c语言中的print原理
时间: 2024-05-25 07:18:24 浏览: 14
printf是一个C语言标准库函数,用于将格式化的输出写入标准输出流(通常是终端窗口)。其原理是将格式化字符串和参数传递给printf函数,然后根据格式化字符串中的占位符,将参数格式化为对应的字符串,最终将结果输出到标准输出流中。
printf函数的格式化字符串中可以包含普通字符和转换说明符,转换说明符以百分号(%)开头。其中,常用的转换说明符包括:%d(整型)、%f(浮点型)、%c(字符型)等等,还可以通过一些控制符控制输出的格式,例如:%10d(右对齐输出整型,占用10个字符宽度)。
在执行printf函数时,会先按照格式化字符串中的占位符,将相应的参数格式化为对应的字符串,然后再将这些字符串按照格式化字符串的顺序拼接起来,最终输出到标准输出流中。
相关问题
编译原理C语言词法分析器
编译原理中的词法分析器是编译器的第一个阶段,它负责将源代码分解成一个个的词法单元(token)。对于C语言的词法分析器,可以按照C语言的词法定义来实现。以下是一个简单的C语言词法分析器的示例:
```python
import re
# 定义C语言的关键字
keywords = ['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if', 'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof', 'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while']
# 定义C语言的运算符
operators = ['+', '-', '*', '/', '%', '=', '==', '!=', '>', '<', '>=', '<=', '&&', '||', '!', '&', '|', '^', '<<', '>>']
# 定义C语言的分隔符
delimiters = [';', ',', '(', ')', '{', '}', '[', ']']
# 定义词法分析函数
def lexer(code):
tokens = []
code = code.replace('\n', ' ') # 去除换行符
code = re.sub(r'\s+', ' ', code) # 去除多余的空格
code = code.strip() # 去除首尾空格
while code:
if code[0] == '"': # 处理字符串常量
end_index = code[1:].find('"') + 1
tokens.append(('STRING', code[:end_index+2]))
code = code[end_index+2:]
elif code[0].isalpha() or code[0] == '_': # 处理标识符和关键字
end_index = 1
while end_index < len(code) and (code[end_index].isalnum() or code[end_index] == '_'):
end_index += 1
token = code[:end_index]
if token in keywords:
tokens.append(('KEYWORD', token))
else:
tokens.append(('IDENTIFIER', token))
code = code[end_index:]
elif code[0].isdigit(): # 处理数字常量
end_index = 1
while end_index < len(code) and code[end_index].isdigit():
end_index += 1
tokens.append(('NUMBER', code[:end_index]))
code = code[end_index:]
elif code[0] in operators: # 处理运算符
tokens.append(('OPERATOR', code[0]))
code = code[1:]
elif code[0] in delimiters: # 处理分隔符
tokens.append(('DELIMITER', code[0]))
code = code[1:]
else: # 处理其他字符
code = code[1:]
return tokens
# 测试代码
code = '''
#include <stdio.h>
int main() {
int a = 10;
printf("Hello, world! %d\n", a);
return 0;
}
'''
tokens = lexer(code)
for token in tokens:
print(token)
```
运行以上代码,将会输出以下词法单元:
```
('KEYWORD', '#include')
('DELIMITER', '<')
('IDENTIFIER', 'stdio.h')
('DELIMITER', '>')
('KEYWORD', 'int')
('IDENTIFIER', 'main')
('DELIMITER', '(')
('DELIMITER', ')')
('DELIMITER', '{')
('KEYWORD', 'int')
('IDENTIFIER', 'a')
('OPERATOR', '=')
('NUMBER', '10')
('DELIMITER', ';')
('IDENTIFIER', 'printf')
('DELIMITER', '(')
('STRING', '"Hello, world! %d\\n"')
('OPERATOR', ',')
('IDENTIFIER', 'a')
('DELIMITER', ')')
('DELIMITER', ';')
('KEYWORD', 'return')
('NUMBER', '0')
('DELIMITER', ';')
('DELIMITER', '}')
```
编译原理语法分析c语言代码
编译原理中的语法分析是将代码转换为抽象语法树的过程。在C语言中,语法分析器通常使用自顶向下的递归下分析方法。以下是一个简单的C语言代码示和相应的语分析器实现:
设我们有以下C语言代码:
```c
#include <stdio.h>
int main() {
int a = 1;
int b = 2;
int c = a + b;
printf("The sum of a and b is %d", c);
return 0;
}
```
我们可以使用递归下降分析器来解析这段代码。下面是一个简单的实现:
```python
import re
# 定义C语言的语法规则
# 这里只列出了一部分规则,实际上C语言的语法规则非常复杂
rules = {
'program': ['INCLUDES main'],
'INCLUDES': ['include <stdio.h>'],
'main': ['INT MAIN LPAREN RPAREN LBRACE declarations statements RETURN NUMBER SEMI RBRACE'],
'declarations': ['INT ID SEMI declarations', ''],
'statements': ['statement statements', ''],
'statement': ['assignment_statement', 'print_statement'],
'assignment_statement': ['INT ID EQUALS NUMBER SEMI'],
'print_statement': ['PRINTF LPAREN STRING COMMA ID RPAREN SEMI']
}
# 定义一个Token类来表示代码中的单词
class Token:
def __init__(self, type, value):
self.type = type
self.value = value
def __str__(self):
return 'Token({type}, {value})'.format(
type=self.type,
value=repr(self.value)
)
# 定义一个Lexer类来将代码转换为Token序列
class Lexer:
def __init__(self, text):
self.text = text
self.pos = 0
self.current_char = self.text[self.pos]
def error(self):
raise Exception('Invalid character')
def advance(self):
self.pos += 1
if self.pos > len(self.text) - 1:
self.current_char = None
else:
self.current_char = self.text[self.pos]
def skip_whitespace(self):
while self.current_char is not None and self.current_char.isspace():
self.advance()
def integer(self):
result = ''
while self.current_char is not None and self.current_char.isdigit():
result += self.current_char
self.advance()
return int(result)
def get_next_token(self):
while self.current_char is not None:
if self.current_char.isspace():
self.skip_whitespace()
continue
if self.current_char.isdigit():
return Token('NUMBER', self.integer())
if self.current_char == '+':
self.advance()
return Token('PLUS', '+')
if self.current_char == '-':
self.advance()
return Token('MINUS', '-')
if self.current_char == '*':
self.advance()
return Token('MULTIPLY', '*')
if self.current_char == '/':
self.advance()
return Token('DIVIDE', '/')
if self.current_char == '(':
self.advance()
return Token('LPAREN', '(')
if self.current_char == ')':
self.advance()
return Token('RPAREN', ')')
if self.current_char == '{':
self.advance()
return Token('LBRACE', '{')
if self.current_char == '}':
self.advance()
return Token('RBRACE', '}')
if self.current_char == ';':
self.advance()
return Token('SEMI', ';')
if self.current_char == '=':
self.advance()
return Token('EQUALS', '=')
if self.current_char == ',':
self.advance()
return Token('COMMA', ',')
if self.current_char == '"':
self.advance()
string = ''
while self.current_char is not None and self.current_char != '"':
string += self.current_char
self.advance()
if self.current_char == '"':
self.advance()
return Token('STRING', string)
else:
self.error()
if self.current_char.isalpha():
word = ''
while self.current_char is not None and (self.current_char.isalpha() or self.current_char.isdigit() or self.current_char == '_'):
word += self.current_char
self.advance()
if word.upper() == 'INT':
return Token('INT', 'int')
if word.upper() == 'PRINTF':
return Token('PRINTF', 'printf')
if word.upper() == 'RETURN':
return Token('RETURN', 'return')
if word.upper() == 'MAIN':
return Token('MAIN', 'main')
if word.upper() == 'INCLUDE':
return Token('INCLUDE', 'include')
if word.upper() == 'STDIO':
return Token('STDIO', 'stdio')
return Token('ID', word)
self.error()
return Token('EOF', None)
# 定义一个Parser类来将Token序列转换为抽象语法树
class Parser:
def __init__(self, lexer):
self.lexer = lexer
self.current_token = self.lexer.get_next_token()
def error(self):
raise Exception('Invalid syntax')
def eat(self, token_type):
if self.current_token.type == token_type:
self.current_token = self.lexer.get_next_token()
else:
self.error()
def program(self):
includes_node = self.includes()
main_node = self.main()
return (includes_node, main_node)
def includes(self):
self.eat('INCLUDE')
self.eat('STDIO')
self.eat('.')
self.eat('H')
return ('INCLUDES',)
def main(self):
self.eat('INT')
self.eat('MAIN')
self.eat('LPAREN')
self.eat('RPAREN')
self.eat('LBRACE')
declarations_node = self.declarations()
statements_node = self.statements()
self.eat('RETURN')
number_node = self.number()
self.eat('SEMI')
self.eat('RBRACE')
return ('MAIN', declarations_node, statements_node, number_node)
def declarations(self):
declarations_node = ('DECLARATIONS',)
while self.current_token.type == 'INT':
declaration_node = self.declaration()
declarations_node += (declaration_node,)
return declarations_node
def declaration(self):
self.eat('INT')
id_node = self.variable()
self.eat('SEMI')
return ('DECLARATION', id_node)
def variable(self):
token = self.current_token
self.eat('ID')
return ('VAR', token.value)
def statements(self):
statements_node = ('STATEMENTS',)
while self.current_token.type in ['ID', 'PRINTF']:
statement_node = self.statement()
statements_node += (statement_node,)
return statements_node
def statement(self):
if self.current_token.type == 'ID':
assignment_statement_node = self.assignment_statement()
return assignment_statement_node
elif self.current_token.type == 'PRINTF':
print_statement_node = self.print_statement()
return print_statement_node
def assignment_statement(self):
id_node = self.variable()
self.eat('EQUALS')
number_node = self.number()
self.eat('SEMI')
return ('ASSIGNMENT', id_node, number_node)
def print_statement(self):
self.eat('PRINTF')
self.eat('LPAREN')
string_node = self.string()
self.eat('COMMA')
id_node = self.variable()
self.eat('RPAREN')
self.eat('SEMI')
return ('PRINT', string_node, id_node)
def string(self):
token = self.current_token
self.eat('STRING')
return ('STRING', token.value)
def number(self):
token = self.current_token
self.eat('NUMBER')
return ('NUMBER', token.value)
def parse(self):
return self.program()
# 将代码转换为Token序列
lexer = Lexer(text)
tokens = []
while True:
token = lexer.get_next_token()
if token.type == 'EOF':
break
tokens.append(token)
# 将Token序列转换为抽象语法树
parser = Parser(Lexer(text))
ast = parser.parse()
print(ast)
```
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)