C 有没有办法使loading()在main()函数之前开始?
我对C非常陌生,我正在尝试创建一种在实际程序运行之前出现的加载屏幕。我编译了它,有一次它运行得很好,但在那之后,它就再也不能运行了。我在想我是不是把事情搞砸了?我不希望它出现在主功能中的原因是,我想允许返回主菜单,而无需再次输入名称。任何帮助都将是惊人的,就像我说的我是C.P.S.的新手。如果需要,我可以附加头文件。我不确定是什么问题 主文件:C 有没有办法使loading()在main()函数之前开始?,c,C,我对C非常陌生,我正在尝试创建一种在实际程序运行之前出现的加载屏幕。我编译了它,有一次它运行得很好,但在那之后,它就再也不能运行了。我在想我是不是把事情搞砸了?我不希望它出现在主功能中的原因是,我想允许返回主菜单,而无需再次输入名称。任何帮助都将是惊人的,就像我说的我是C.P.S.的新手。如果需要,我可以附加头文件。我不确定是什么问题 主文件: #include "periodic-header.h" void blue() { printf("\033[
#include "periodic-header.h"
void blue() {
printf("\033[0;36m");
}
void lime() {
printf("\033[1;32m");
}
void yellow() {
printf("\033[1;33m");
}
void colorReset() {
printf("\033[0m");
}
loading();
int main(char *userName) {
int choice;
colorReset();
system("cls");
table();
printf("\n\n");
yellow();
printf("\t\t Using the numbers on your keyboard,\n");
printf("\t\t Please select an option:\n\n");
printf("\t\t 1) Examine element\n");
printf("\t\t 2) Input data for element\n");
printf("\t\t 3) Exit program\n");
choose(&choice,3);
switch(choice){
case 1:{
examineElement();
break;
}
case 2:{printf("\t\t Test 2\n");
// addElement();
break;
}
case 3:{
system("cls");
printf("\n\n\t\t Thanks for stopping by %s,\n", userName);
Sleep ( 300 );
printf("\t\t ... hope to see you again soon!\n");
colorReset();
exit(1);
break;
}
default: printf("\t\t Sorry %s, that is not a valid option", userName); break;
}
colorReset();
}
正在加载文件:
#include "periodic-header.h"
void loading(){
system("cls");
yellow();
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [ ASPECT ]\n");
colorReset();
blue();
Sleep ( 10000 );
printf("\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t Loading...\n");
Sleep ( 900 );
colorReset();
yellow();
system("cls");
printf("\n\n");
printf("\t\t Welcome...\n");
Sleep ( 300 );
printf("\t\t Please enter your name: ");
char userName [20];
fscanf(stdin, "%20s", userName);
Sleep ( 1300 );
}
头文件:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <string.h>
#include <stdbool.h>
extern char userName[20];
// Prints view of periodic table
void table();
// Manipulates periodic table
void examineElement();
void addElement();
//Not in use yet
void menuSelection();
char selection[2];
// Used to choose what you want to do with the program
int choose();
// Element Credentials
extern char elementName[50];
extern char sb[5];
extern int atm;
extern float atms;
extern char block;
extern char atc[20];
extern char prop[250];
#包括
#包括
#包括
#包括
#包括
#包括
#包括
外部字符用户名[20];
//元素周期表视图
空表();
//操纵周期表
无效检查元素();
void addElement();
//尚未使用
void menuSelection();
字符选择[2];
//用于选择要对程序执行的操作
int choose();
//元素凭据
外部字符元素名[50];
外部字符sb[5];
外部内部atm;
外部浮动自动柜员机;
外部字符块;
外部字符atc[20];
外部字符属性[250];
不幸的是,这是不可能的,因为main()
是程序的入口点,这意味着它是运行程序时执行的函数。但是,您可以将main的内容放在一个单独的函数中,并在程序开始之前在main中调用load()
。我指的是:
void load() {
// loading screen
}
void program() {
// the program
}
int main() {
load();
program();
}
不幸的是,这是不可能的,因为
main()
,是程序的入口点,这意味着它是运行程序时执行的函数。但是,您可以将main的内容放在一个单独的函数中,并在程序开始之前在main中调用load()
。我指的是:
void load() {
// loading screen
}
void program() {
// the program
}
int main() {
load();
program();
}
如果将任何函数设置为构造函数,则可以在调用main
之前使其运行
构造函数可以有一个“优先级”数字,所以我们可以有几个以特定顺序运行
较低优先级的数字是为gcc/glibc
内部回调函数保留的,因此我们应该添加一个偏差,以免与它们冲突
同样,我们可以设置一个“析构函数”函数
下面是一些示例代码:
#include <stdio.h>
#define ctors ctorx(0)
#define dtors dtorx(0)
#define ctorx(_prio) __attribute__((constructor(_prio + 201)))
#define dtorx(_prio) __attribute__((destructor(_prio + 201)))
void ctorx(0)
loading(void)
{
printf("%s ...\n",__FUNCTION__);
}
void ctorx(-1)
i_am_called_before_loading(void)
{
printf("%s ...\n",__FUNCTION__);
}
void ctorx(1)
i_am_called_after_loading(void)
{
printf("%s ...\n",__FUNCTION__);
}
void dtorx(0)
i_am_called_after_main_has_completed(void)
{
printf("%s ...\n",__FUNCTION__);
}
int
main(void)
{
printf("main: running ...\n");
return 0;
}
更新:
你能解释一下如何用C语言构造构造函数吗?我猜你的代码在没有C++编译器的情况下是行不通的。布伦丹 不,不管怎样,这都会起作用 这是gcc的一部分。有关更多详细信息,请参阅
info gcc
在AICT中,这[直接]使用了c++
将用于静态/全局构造函数/析构函数的[底层]机制。也就是说,c++
并不“拥有”该机制,而只是一个更通用机制的客户端,该机制由ELF提供,可由各种不同的语言使用
这是在过去几年中增加的
在此之前,可以使用ELF的.init/.fini
节属性来存储回调函数的指针
这就是共享库(.so
文件)如何获得对[hidden]初始化函数的回调。ELF解释器(例如/lib64/ld-linux-x86-64.so
)将在加载库时查找并发出回调
或者,对于非常旧的代码,必须调用init/fini函数init
和fini
。为此,我们可能不得不将函数放入一个单独的共享库(.so
)中,但现在情况不再如此
另外,旧机制仍然可用/可用/有效,可以与构造函数
属性并行使用
我不确定gcc
如何实现constructor
属性,但这里有一个猜测:
属性变形为一个函数指针,该指针被放入(例如,部分(gcc\u构造函数\u列表)
。crt0.o
[或等效]例程将调用该部分中定义的内容
另一种方法是生成指向函数的指针,并使用ELF的.init/.fini
部分
或者,发出对gcc\u constructor\u list
的调用的函数可以是ELF.init
函数(因此,根本不需要位于crt0.o
中)
要查看实际生成的内容,在构建程序后,我们可以执行readelf-a./program
,在输出中有:
.init
和.fini
节头。init_数组
和.fini_数组
“动态部分”中的一些条目有:INIT_数组
,INIT_数组
,FINI_数组
,FINI_数组,FINI_数组,如果我们将其设置为构造函数,则可以在调用main
之前运行任何函数
构造函数可以有一个“优先级”数字,所以我们可以有几个以特定顺序运行
较低优先级的数字是为gcc/glibc
内部回调函数保留的,因此我们应该添加一个偏差,以免与它们冲突
同样,我们可以设置一个“析构函数”函数
下面是一些示例代码:
#include <stdio.h>
#define ctors ctorx(0)
#define dtors dtorx(0)
#define ctorx(_prio) __attribute__((constructor(_prio + 201)))
#define dtorx(_prio) __attribute__((destructor(_prio + 201)))
void ctorx(0)
loading(void)
{
printf("%s ...\n",__FUNCTION__);
}
void ctorx(-1)
i_am_called_before_loading(void)
{
printf("%s ...\n",__FUNCTION__);
}
void ctorx(1)
i_am_called_after_loading(void)
{
printf("%s ...\n",__FUNCTION__);
}
void dtorx(0)
i_am_called_after_main_has_completed(void)
{
printf("%s ...\n",__FUNCTION__);
}
int
main(void)
{
printf("main: running ...\n");
return 0;
}
更新:
你能解释一下如何用C语言构造构造函数吗?我猜你的代码在没有C++编译器的情况下是行不通的。布伦丹
不,不管怎样,这都会起作用
这是gcc的一部分。有关更多详细信息,请参阅info gcc
在AICT中,这[直接]使用了c++
将用于静态/全局构造函数/析构函数的[底层]机制。也就是说,c++
并不“拥有”该机制,而只是一个更通用机制的客户端,该机制由ELF提供,可由各种不同的语言使用
这是在过去几年中增加的
之前