首页 > 编程语言 >手把手教你用C语言写一个简单的quine(输出自身的程序)

手把手教你用C语言写一个简单的quine(输出自身的程序)

时间:2024-11-16 18:19:05浏览次数:1  
标签:10 include 输出 教你用 C语言 转义字符 printf main quine

第一步,写个简单的框架

#include<stdio.h>
int main(){
	printf("#include<stdio.h>\nint main(){\n\tprintf();\n\treturn 0;\n}");
	return 0;
}

printf的东西先留空。
这时你会发现printf里面的东西需要是这句东西本身,如果把这句话复制进去,你会发现最内层还存在一个空的括号,反反复复下去就无底洞了。所以需要换个思路:

用变量。

第二步,考虑把printf的东西扔到变量里,然后使用格式符输出。

#include<stdio.h>
int main(){
	char *s="#include<stdio.h>\nint main(){\n\tprintf(s);\n\treturn 0;\n}";
	printf(s);
	return 0;
}

有人要问了,你这不还没在字符串s里面定义如何写char嘛,如果在字符串里面把s写出来,那不又成刚才那样的无底洞了?
且慢,由于s此时是printf的第一个参数,我们完全可以利用好printf的功能——%s嘛。有了这招,我们就不用那样写无底洞了,用%s参数把s放进去就行了。

#include<stdio.h>
int main(){
	char *s="#include<stdio.h>\nint main(){\n\tchar *s=%s;\n\tprintf(s,s);\n\treturn 0;\n}";
	printf(s,s);
	return 0;
}

这里有个小技巧,printf(s,s),第一个s格式描述符把程序框架输出,%s的位置交给第二个s把字符串s本身再输出一遍。
且慢...输出的结果貌似不太对?

答案是由于转义字符的缘故。其中我们以明文形式写的\n、\t等转义字符,在输出的时候会变成换行,制表符。我们希望它输出程序框架的时候是正常输出制表和换行的,而在输出s内容的时候直接保留原文...

第三步,继续利用printf的参数

如果用%c,然后用字符的ASCII码代替转义字符,就没这问题了。
逐一把转义字符写成ASCII码,堆在printf的后面,写完后把字符串s内容中的printf参数也这样换一遍,就大功告成了。
printf的参数会变得很多,不过能正常运行就行。

#include<stdio.h>
int main(){
	char *s="#include<stdio.h>%cint main(){%c%cchar *s=%c%s%c;%c%cprintf(s,10,10,9,s,10,9,10,9,10);%c%creturn 0;%c}";
	printf(s,10,10,9,34,s,34,10,9,10,9,10);
	return 0;
}

成功运行,撒花!

标签:10,include,输出,教你用,C语言,转义字符,printf,main,quine
From: https://www.cnblogs.com/jisuanjizhishizatan/p/18549648

相关文章

  • c语言的分支结构
    C语言程序有3种基本结构:顺序结构、选择结构和循环结构1)顺序结构:所谓顺序结构,就是从上到下的所有语句都会依次执行2)选择结构:选择结构中存在一条(或多条)分支语句,当满足分支的条件时语句才会执行,否则不会执行3)循环结构:循环结构即是在某些条件的控制下重复执行一段代码语句,当......
  • c语言快速排序
    快速排序(Quicksort)是一种高效的排序算法,采用分治法(DivideandConquer)策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。快速排序的步骤:选择基准(Pivot):从数列中挑出一个元素,称为"基准"(pivot)。分区(Partitioning):重新排序数列,所有元素比基准值小的摆放......
  • 【落羽的落羽 C语言篇】指针·之其二
    文章目录一、const使用指南1.const修饰变量2.const修饰指针变量二、野指针1.野指针的概念2.野指针的成因3.如何规避野指针三、assert(断言)使用指南四、传值调用和传址调用1.传值调用2.传址调用一、const使用指南1.const修饰变量众所周知,变量是可以修......
  • 什么是C语言中的指针?
    1.基本概念在C语言中,指针是一种变量,它存储的是另一个变量的内存地址。可以把内存想象成一个巨大的公寓楼,每个变量就像住在公寓里的居民,而指针就是写着居民房间号(内存地址)的纸条。例如,假设有一个整型变量a,它存储在内存中的某个位置,指针变量p就可以用来保存变量a的内存地......
  • c语言sizeof与strlen的区别详细解析
    char*p="abcdef";printf("%d\n",sizeof(p));p是指针变量(地址),地址就是地址,大小就是4/8字节printf("%d\n",sizeof(p+1));p+1是b的地址,还是地址4/8字节printf("%d\n",sizeof(*p));*p是‘a’,sizeof(*p)计算的是字符的大小,是1字节printf("%d\n"......
  • c语言——三子棋基础游戏
    首先,我们先有整体思路:它的棋盘到底是怎么样子的?它实现的过程是怎么一步一步来的棋盘到底是怎么样子的?大概是这么一个轮廓。实现过程中,我们该如何思考呢?1.我们想到,开始游戏的时候,我们肯定会一个菜单的吧?2.利用菜单选择是否开始游戏3.开始游戏后,我们就开始设计排版棋盘了:1......
  • 【C语言指南】C语言内存管理 深度解析
           ......
  • 关于我重生到21世纪学C语言这件事——指针详解(2)
    人无完人,持之以恒,方能见真我!!!共同进步!!文章目录1.数组名的理解2.使⽤指针访问数组3.⼀维数组传参的本质4.冒泡排序5.⼆级指针6.指针数组7.指针数组模拟⼆维数组1.数组名的理解在上⼀个章节我们在使⽤指针访问数组的内容时,有这样的代码:intarr[10]={1,......
  • c语言笔记(鹏哥)课件+上课板书汇总(深入指针1)
    深入指针(1)⽬录:一、内存和地址二、指针变量和地址三、取地址操作符四、指针变量类型的意义(这一讲到这)五、const修饰指针六、指针运算七、野指针八、assert断⾔九、指针的使⽤和传址调⽤内存和地址引例:假设有一个宿舍楼,你在一个房间里,宿舍楼里每一间房间都......
  • 数据结构程序设计(C语言)校园导游系统
    使用队列以及深度搜索算法,加上dos命令调用图片的校园导游系统#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<Windows.h>structgraph{ intnode_num;//顶点数 intedge_num;//边数 charnode_name[20][50......