这是在面试中被问到的一个问题,回答了是。这问题第一感觉答案就是否定的,一时也没想出来理由只能回答了是。当时太紧张了,其实回想一下汇编语言就该想到程序的入口地址是可以指定的,c语言编译器默认以main作为入口地址。
网上查阅后,发现了 __attribute__ 这个关键字,它可以设置函数属性,变量属性,类型属性。
1、前言
最近看到一份代码,看到一个函数前面用__attribute__((destructor))修饰,当时感觉有点怪怪的,搜了整个程序,也没发现哪个地方调用这个函数。于是从字面意思猜想,该函数会在程序结束后自动调用,与C++中的析构函数类似。第一次接触GNU下的attribute,总结一下。
2、__attribute__介绍
__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。__attribute__前后都有两个下划线,并且后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数
__attribute__语法格式为:__attribute__ ( ( attribute-list ) )
若函数被设定为constructor属性,则该函数会在main()函数执行之前被自动的执行。类似的,若函数被设定为destructor属性,则该函数会在main()函数执行之后或者exit()被调用后被自动的执行。例如下面的程序:
#include <stdioh> #include <stdlibh> static int g_count = NULL; __attribute__((constructor)) void load_file() { printf("Constructor is called\n"); g_count = (int )malloc(sizeof(int)); if (g_count == NULL) { fprintf(stderr, "Failed to malloc memory\n"); } } __attribute__((destructor)) void unload_file() { printf("destructor is called\n"); if (g_count) free(g_count); } int main() { return 0; }
程序执行结果如下:
看下面的例子:
// gcc 编译器#include<stdioh>__attribute__((constructor)) void before_main(){ printf("%s\n",__FUNCTION__);}__attribute__((destructor)) void after_main(){ printf("%s\n",__FUNCTION__);}int main(){ printf("%s\n",__FUNCTION__); return 0;}
输出结果为:before_main
main
after_main
可以看到上面的程序并不是从main函数开始执行的。constructor 设置在main前面执行,destructor 设置在main之后执行。
main不是关键字,你可以定义一个变量int main;而不会出错,
main函数是控制台程序的默认入口函数,win32app程序的入口函数是WinMain
main()称之为主函数,既可以是无参函数,也可以是有参的函数。main()函数的带参的形式:
main(argc,argv)
int argc,char argv[];
{ }
//int main(int argc, char argv[]) { }
不带参 main() { }
main()函数可以调用其他有参或无参函数。调用有参函数时,参数在调用时传递。
一个完整的C语言程序,是由一个main()函数和若干个其它函数结合而成的,或仅由一个main()函数构成。
从main()函数开始执行当主函数执行完毕时,亦即程序执行完毕。
习惯上,将主函数main()放在最前头。
每个程序不一定都要有main这个名字的函数
其实叫什么名字无所谓,但是必须有"主函数",哪怕这个函数什么也不做直接返回
对于应用程序来说,叫做入口点
我们写程序之所以要有main这个函数,是因为编译器默认的入口函数就是main(对于DLL来说就是DllMain),其实你完全可以不要main这个函数,而改用比如test123之类的函数,但是在编译的时候你需要附加额外的命令行来指定入口函数是那一个
main()函数称之为主函数,一个C程序总是从main()函数开始执行的,但是不一定在main函数最后结束。
在 main() 之后的最后一条语句结束后,程序还要运行一些代码,以正常返回 *** 作系统。main函数执行完后还执行其他语句,
有时候需要有一种与程序退出方式无关的方法来进行程序退出时的必要处理,方法就是用atexit()函数来注册程序正常终止时要被调用的函数,atexit()函数的参数是一个函数指针,函数指针指向一个没有参数也没有返回值的函数,它的原型是:
int atexit(void ()(void));
扩展资料
main函数的使用
示例:
#include <stdlibh>
#include <stdioh>
void fn1(void);
void fn2(void);
int main(void)
{
atexit(fn1);
atexit(fn2);
printf("main exit \n");
return 0;
}
void fn1()
{
printf("calling fn1()\n");
}
void fn2()
{
printf("calling fn2()\n");
}
参考资料来源:百度百科—main函数
一、定义
main函数,又称主函数,是程序执行的起点,main是相对来说的,如同音学理论之主调于泛音,泛音即程序中的除main之外的其他函数,迎合人们的思考方式而生成的而非必定的模式有主有次,执行起来条清缕析,既可将程序模块化又实现了一个闭合的整体。
二、main()函数的形式
在最新的 C99 标准中,只有以下两种定义方式是正确的:
int main( void ) / 无参数形式 /
{
return 0;
}
int main( int argc, char argv[] ) / 带参数形式 /
{
return 0;
}
int指明了main()函数的返回类型 ,函数名后面的圆括号一般包含传递给函数的信息。void表示没有给函数传递参数。
三、main()函数的返回值
从前面我们知道main()函数的返回值类型是int型的,而程序最后的 return 0; 正与之遥相呼应,0就是main()函数的返回值。那么这个0返回到那里呢?返回给 *** 作系统,表示程序正常退出。
因为return语句通常写在程序的最后,不管返回什么值,只要到达这一步,说明程序已经运行完毕。而return的作用不仅在于返回一个值,还在于结束函数。
四、main()函数的参数
C编译器允许main()函数没有参数,或者有两个参数 (有些实现允许更多的参数,但这只是对标准的扩展)。这两个参数,一个是int类型,一个是字符串类型。
第一个参数是命令行中的字符串数。按照惯例(但不是必须的),这个int参数被称为argc(argument count)。第二个参数是一个指向字符串的指针数组。命令行中的每个字符串被存储到内存中,并且分配一个指针指向它。
按照惯例,这个指针数组被称为argv(argument value)。系统使用空格把各个字符串格开。一般情况下,把程序本身的名字赋值给argv[0],接着,把最后的第一个字符串赋给argv[1] ,等等。
扩展资料
C++中的main函数的应用:
C++继承了C语言的大部分特性,因此保留了“程序总是从main函数开始执行,且总是默认从main函数的return语句或结尾处结束运行”这一传统,但是要注意,C++中的main函数要想作为程序执行的出入口,必须写在全局(Global)范围,不能写成某个结构体或某个类的成员。
虽然main函数可以作为结构体或者类的成员函数,但相应地会失去作为程序出入口的功能。C++中全局main函数的书写格式与C语言完全相同,功能也完全相同,且同一C++程序同样只能有一个全局main函数。
参考资料:
在 C 语言中,主函数的名字通常是 main。这是 C 语言的一个约定,所有的 C 程序都必须有一个名为 main 的主函数。这是 C 程序的入口点,在执行程序时系统会自动调用 main 函数。
然而,在一些特殊情况下,你也可以使用其他名字来定义主函数。例如,在某些编译器中,你可以使用 WinMain 作为主函数名,这样程序就可以在 Windows 系统上运行。但是,这种做法并不是 C 语言的标准用法,而且不同的编译器对于主函数名的支持也可能会有所差异,因此不建议在通用 C 程序中使用其他名字来定义主函数。
以上就是关于C程序必须从main()函数开始执行全部的内容,包括:C程序必须从main()函数开始执行、C语言中 main 是什么意思详细的啊、每一个C++程序都有一个main函数吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)