Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 有没有办法使loading()在main()函数之前开始?_C - Fatal编程技术网

C 有没有办法使loading()在main()函数之前开始?

C 有没有办法使loading()在main()函数之前开始?,c,C,我对C非常陌生,我正在尝试创建一种在实际程序运行之前出现的加载屏幕。我编译了它,有一次它运行得很好,但在那之后,它就再也不能运行了。我在想我是不是把事情搞砸了?我不希望它出现在主功能中的原因是,我想允许返回主菜单,而无需再次输入名称。任何帮助都将是惊人的,就像我说的我是C.P.S.的新手。如果需要,我可以附加头文件。我不确定是什么问题 主文件: #include "periodic-header.h" void blue() { printf("\033[

我对C非常陌生,我正在尝试创建一种在实际程序运行之前出现的加载屏幕。我编译了它,有一次它运行得很好,但在那之后,它就再也不能运行了。我在想我是不是把事情搞砸了?我不希望它出现在主功能中的原因是,我想允许返回主菜单,而无需再次输入名称。任何帮助都将是惊人的,就像我说的我是C.P.S.的新手。如果需要,我可以附加头文件。我不确定是什么问题

主文件:

#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提供,可由各种不同的语言使用

这是在过去几年中增加的

之前