一个自己打印自已的C程序
时间: 2024-09-22 15:06:15 浏览: 36
在C语言中,创建一个能够"打印自己"的程序通常意味着实现一个递归函数,该函数会打印自身的源代码。这并不是直接打印程序本身的二进制代码,而是展示其人类可读的文本形式。下面是一个简单的示例,它是一个递归函数,打印出自身函数的定义:
```c
#include <stdio.h>
// 定义一个递归函数,它的任务就是打印自己的源码
void printSelf() {
FILE* file = fopen(__FILE__, "r"); // 打开当前文件
if (file) {
char ch; // 逐字符读取
while ((ch = fgetc(file)) != EOF) { // 当遇到文件结束标志时停止
printf("%c", ch); // 输出每个字符到控制台
}
fclose(file); // 关闭文件
} else {
fprintf(stderr, "Error opening the file.\n");
}
}
int main() {
printSelf(); // 调用函数,开始打印
return 0;
}
相关问题
帮我用8086汇编语言写个程序,.在显示屏中央开一个窗口显示自已的名字(以拼音显示)。 要求:窗口的大小(行列的象素数,可由用户输入两个数字调整)
好的,以下是一个简单的8086汇编程序,可以在显示屏中央开一个窗口显示拼音名字。窗口大小可以由用户输入调整。
```
; 设置窗口的大小
mov ah, 0Ah ; 调用DOS中断0x21中的0x0A功能
mov bh, 0 ; 显示页面号
mov cx, 0 ; 列号为0
mov dx, 0 ; 行号为0
mov ah, 0x0A ; 调用DOS中断0x21
int 0x21
; 获取用户输入的窗口大小
mov ah, 0x0A ; 调用DOS中断0x21中的0x0A功能
mov bh, 0 ; 显示页面号
mov cx, 0 ; 列号为0
mov dx, 0 ; 行号为0
mov ah, 0x0A ; 调用DOS中断0x21
int 0x21
mov ah, 0x0B ; 调用DOS中断0x21中的0x0B功能
mov bl, 0 ; 显示页面号
mov cx, 0 ; 列号为0
mov dx, 0 ; 行号为0
int 0x21
mov [window_cols], cx ; 将列号保存到内存中
mov [window_rows], dx ; 将行号保存到内存中
; 计算窗口的位置
mov ax, [window_cols] ; 获取窗口的列数
mov bx, 2 ; 计算每个字符所占的字节数,这里默认使用80x25文本模式
mul bx ; 计算窗口的宽度(以字节为单位)
mov bx, 80 ; 每行有80个字符
sub bx, ax ; 计算左边留白的字符数
shr bx, 1 ; 将字符数右移一位以得到留白字符数的一半
mov [window_x], bx ; 将留白字符数保存到内存中
mov ax, [window_rows] ; 获取窗口的行数
mov bx, 25 ; 计算每个字符所占的行数,这里默认使用80x25文本模式
mul bx ; 计算窗口的高度(以行数为单位)
mov bx, 25 ; 屏幕上有25行
sub bx, ax ; 计算上面留白的行数
shr bx, 1 ; 将行数右移一位以得到留白行数的一半
mov [window_y], bx ; 将留白行数保存到内存中
; 显示窗口和名字
mov ah, 0x0E ; 调用DOS中断0x21中的0x0E功能
mov al, ' ' ; 空格字符
mov bh, 0 ; 显示页面号
mov cx, [window_x] ; 计算窗口左侧空白的字符数
mov dx, [window_y] ; 计算窗口上方空白的行数
int 0x10 ; 显示左侧空白
mov cx, [window_cols] ; 获取窗口的列数
mov dx, [window_rows] ; 获取窗口的行数
mov si, name ; 将名字的地址保存到SI寄存器中
call print_window ; 显示名字
mov cx, [window_x] ; 计算窗口左侧空白的字符数
add cx, [window_cols] ; 计算窗口右侧空白的字符数
mov dx, [window_y] ; 计算窗口下方空白的行数
add dx, [window_rows] ; 计算窗口下方空白的行数
int 0x10 ; 显示右侧和下方的空白
; 程序结束
mov ah, 0x4C ; 调用DOS中断0x21中的0x4C功能
int 0x21
; 打印窗口中的名字
print_window:
push ax
push bx
push cx
push dx
push si
mov bx, 0x07 ; 属性为白底黑字
mov cx, [window_cols] ; 获取窗口的列数
mov dx, [window_rows] ; 获取窗口的行数
mov ah, 0x02 ; 调用DOS中断0x21中的0x02功能来打印字符
xor bx, bx ; BX寄存器用于计数
mov al, ' ' ; 空格字符
jmp next_row
print_char:
lodsb ; 从SI寄存器中读取下一个字符
stosw ; 将字符和属性写入显存
inc bx ; 计数器加1
cmp bx, cx ; 判断是否到达右侧边界
jne next_char
jmp next_row
next_char:
add si, 1 ; 指向下一个字符
jmp end_print
next_row:
add si, cx ; 跳到下一行的起始位置
add si, cx ; 跳过留白部分的位置
mov bx, 0 ; 重置计数器
cmp bx, dx ; 判断是否到达下方边界
jne print_char
end_print:
pop si
pop dx
pop cx
pop bx
pop ax
ret
; 数据段
name db 'my name', 0
window_cols dw 0
window_rows dw 0
window_x dw 0
window_y dw 0
; 代码段结束
```
请注意,这只是一个简单的示例程序,可能需要根据您的具体环境和需求进行修改。
阅读全文