当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 16 篇帖子 ]  前往页数 1, 2  下一页
作者 内容
1 楼 
 文章标题 : [请教]关于linux下c语言(gcc)的语法与标准c不同的问题
帖子发表于 : 2008-02-20 22:41 
头像

注册: 2008-01-17 2:14
帖子: 21
地址: 成都-四川-中国
系统: Mac OS X 10.8
送出感谢: 0 次
接收感谢: 0 次
这是gcc的hello world:

#include <stdio.h>
int
main(void)
{
printf("Hello, world!\n");
return 0;
}
gcc编译无错通过
这是我写的 标准c上的筛质数程序:
zhishu2.c:

#include<stdio.h>

void main()

{int n,m,x,i,j;

printf("\n\nplease input min number:");

scanf("%d",&m);

printf("\n\nplease input max number:");

scanf("%d",&n);

if(m<=2&&n>=2) printf("2 ");

for(x=3;x<=n;x++)

{ j=0;

for(i=2;i<x;i++)

{

if(x%i!=0) j++;

if(j==x-2&&x>=m) printf("%d ",x);

}

}

printf("over\n");

}

编译有警告 zhishu2.c:3: 警告: ‘main’ 的返回类型不是 ‘int’
但还是通过了 并且执行通过了
请教一下 gcc的语法于标准c有何不同

:?:


_________________
代码:
AMD  640     //开6核美
HD6850                      //Hawk美
ST 500GB 7200.11    //固件门中招
GEIL 2G  *4                //8G美
GIGABYTE 770-UD3  //技嘉美
OS:
Mint Linux          //折腾中 Xfce 清爽
windows8         //怀念win7
MAC OS X   10.8    //Retina macbook pro 15 到手


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2008-02-21 13:01 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
因为你的不标准, 标准说明main必须返回int


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2008-02-21 13:06 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 272
引用:
gcc的strtof竟然要带-std=c99编译才正常。
我碰到过的。你也注意下。


_________________
● 鸣学


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2008-02-21 13:11 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
eexpress 写道:
引用:
gcc的strtof竟然要带-std=c99编译才正常。
我碰到过的。你也注意下。


默认的是貌似是使用c89

man strtof

代码:
       #define _XOPEN_SOURCE=600   /* or #define _ISOC99_SOURCE */


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2008-02-21 13:14 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 272
不是哦。我的total程序就是这样过来的。strtof是关键。


_________________
● 鸣学


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2008-02-21 14:04 

注册: 2007-01-31 12:47
帖子: 4
送出感谢: 0 次
接收感谢: 0 次
标准C的main函数只有两种写法
1:
代码:
int main() //main(int argc, char argv[])
{
    ... ...
    return 0;
}


2:
代码:
main() //main(int argc, char argv[])
{
    ... ...
}


页首
 用户资料  
 
7 楼 
 文章标题 :
帖子发表于 : 2008-02-21 14:32 
头像

注册: 2006-04-12 20:05
帖子: 8495
地址: 杭州
送出感谢: 0 次
接收感谢: 8
"Hello, world" example

The following simple application appeared in the first edition of K&R, and has become the model for an introductory program in most programming textbooks, regardless of programming language. The program prints out "hello, world" to the standard output, which is usually a terminal or screen display. Standard output might also be a file or some other hardware device, depending on how standard output is mapped at the time the program is executed.

代码:
main()
{
    printf("hello, world\n");
}


The above program will compile on most modern compilers that are not in compliance mode, but does not meet the requirements of either C89 or C99. Compiling this program in C99 compliance mode will result in warning or error messages.[8] A compliant version of the above program follows:

代码:
#include <stdio.h>

int main(void)
{
    printf("hello, world\n");
    return 0;
}


_________________
关注我的blog: ε==3


页首
 用户资料  
 
8 楼 
 文章标题 :
帖子发表于 : 2008-02-21 22:37 
头像

注册: 2008-01-17 2:14
帖子: 21
地址: 成都-四川-中国
系统: Mac OS X 10.8
送出感谢: 0 次
接收感谢: 0 次
那为什么不能直接定义main为空类型呢


_________________
代码:
AMD  640     //开6核美
HD6850                      //Hawk美
ST 500GB 7200.11    //固件门中招
GEIL 2G  *4                //8G美
GIGABYTE 770-UD3  //技嘉美
OS:
Mint Linux          //折腾中 Xfce 清爽
windows8         //怀念win7
MAC OS X   10.8    //Retina macbook pro 15 到手


页首
 用户资料  
 
9 楼 
 文章标题 :
帖子发表于 : 2008-02-21 22:51 

注册: 2007-03-23 11:41
帖子: 26
送出感谢: 0 次
接收感谢: 0 次
main 要return 给OS,返回值是有用的 ,不能为空


页首
 用户资料  
 
10 楼 
 文章标题 :
帖子发表于 : 2008-02-22 13:24 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
coolwdp 写道:
那为什么不能直接定义main为空类型呢


没有为什么, 这是规定


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
11 楼 
 文章标题 :
帖子发表于 : 2008-03-15 17:58 
头像

注册: 2006-03-04 23:10
帖子: 888
地址: 江西高安
送出感谢: 0 次
接收感谢: 2
RoyKing 写道:
标准C的main函数只有两种写法
1:
代码:
int main() //main(int argc, char argv[])
{
    ... ...
    return 0;
}


2:
代码:
main() //main(int argc, char argv[])
{
    ... ...
}


当时学习的时候,是使用第二种的。
原来还有一种格式。呵呵


_________________
QQ:273247606
EMAIL:yanghui1986527@gmail.com


页首
 用户资料  
 
12 楼 
 文章标题 :
帖子发表于 : 2008-03-15 18:59 
头像

注册: 2007-10-20 11:30
帖子: 1132
送出感谢: 1
接收感谢: 0 次
void main()
好像是VC的~


页首
 用户资料  
 
13 楼 
 文章标题 :
帖子发表于 : 2008-03-15 19:22 

注册: 2006-03-10 15:10
帖子: 3182
地址: xi'an China
送出感谢: 0 次
接收感谢: 2
C标准中从没有说过有 void main() 这种形式。

C语言标准 ISO/IEC 9899:1999(E) 第 5.1.2.2.1 节一开始就这样说:
代码:
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:
        int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
        int main(int argc, char *argv[]) { /* ... */ }
or equivalent;9) or in some other implementation-defined manner.


页首
 用户资料  
 
14 楼 
 文章标题 :
帖子发表于 : 2008-03-15 21:23 
头像

注册: 2006-05-03 0:39
帖子: 8273
地址: المريخ
送出感谢: 0 次
接收感谢: 1
yang_hui1986527 写道:
RoyKing 写道:
标准C的main函数只有两种写法
1:
代码:
int main() //main(int argc, char argv[])
{
    ... ...
    return 0;
}


2:
代码:
main() //main(int argc, char argv[])
{
    ... ...
}


当时学习的时候,是使用第二种的。
原来还有一种格式。呵呵

第二种不对,现在的C标准不将int作为默认返回值,一定要加int


_________________
PHP是最好的语言!不服来战!


页首
 用户资料  
 
15 楼 
 文章标题 :
帖子发表于 : 2008-03-21 23:23 

注册: 2007-10-26 10:14
帖子: 2
送出感谢: 0 次
接收感谢: 0 次
转载于http://bbs.xjtu.edu.cn/BMYFCDNGVVOVKBJEODGGKGEVBHWWPNWLQJHI_B/
----------------------------------------------------------------------------------------------------------------------------
1. main()函数的形式
先来说说main函数的定义,较早开始写C程序的肯定都用过这样的定义void main(){},其实翻翻C/C++标准,从来没有定义过void main()。
在C标准中main的定义只有两种:
int main(void)
int main(int argc, char *argv[])
在C++标准中main的定义也只有两种:
int main( )
int main(int argc, char *argv[])

换句话说:当你的程序不需要命令行参数的时候用int main(), 当需要命令行参数的时候请使用int main(int argc, char *argv[])

不过标准归标准,在不同的平台上,不同的编译器中对main()的定义方式总有自己的实现,比如早期编译器对void main()的支持(现在gcc也支持,不过会给出一个warning)。

特别的,因为历史的原因,在Unix-like平台上,大多还支持
int main(int argc, char *argv[], char *envp[])
其使用方式我们稍后再谈。

2. main()函数的返回
int main(...) 意味着需要return一个int值,如果不写,有的编译器会自动帮你添加一个return 0;,而有的则会返回一个随机值。为了避免不必要的问题,建议写的时候还是加上一个return 0;,浪费不了你多少时间,不是吗?
所以一个完整的test.c文件应该为:
int main(int argc, char *argv[])
{
return 0;
}
当然我们也可以尝试着让main返回一个long, double甚至是struct,更改main函数中的形参定义。这在有些编译器上是能编译通过的,不过可能会有一些警告(如GCC)。但是运行的时候如果编译器能做转换的还好,如返回long,float. 如果不能的话(如返回struct,或者main(int argc, char *argv0,char *argv1,char *argv2))会造成segmentation fault。


3. main()的调用和返回
在了解了main()函数的定义和返回形式后,我们再来看看main函数是怎么被调用的,它又"return"给了谁。在"gcc的编译过程"一中,我们回顾了程序从源码到可执行程序的过程,在"应用程序在linux上是如何被执行的"一文中,我们回顾了可执行文件怎么被操作系统加载的,今天我们继续这个过程。
上文提到不管是在load_elf_binary()中或者使用了动态链接库,最后都执行到了应用程序的入口。不过这个入口不是main.而是_start()。
执行
gcc -o test test.c
readelf -a test
可以看到test文件的Entry point address是0x80482e0,在往后看,这个地址是.text的地址(代码段的开始),也是_start()的地址。在_start()中又会调用__libc_start_main(),主要做一些程序的初始化工作,感兴趣的同学可以读读glibc中的源码,注释很清楚。然后主角登场了,在 __libc_start_main()中最后会调用
int result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);//这是Unix-like下main函数的调用方式,这下大家明白main函数中形参的由来了吧。
result中放着main函数的返回值,然后带着这个值退出。
exit (result);

注意:虽然main函数是一个特殊的函数,是程序运行的入口,但它毕竟也是一个函数,是可以被调用的。如:
int main()
{
if(...)
return 0;
main();
return 0;
}
不过要小心调用方式,和退出条件,避免无穷递归。

4. shell中执行程序
通过前几次和上面的分析,我们终于基本弄清了应用程序的执行过程,再回顾一遍: 在某个交互式shell中敲入./test, 此shell fork()/clone()出一个子进程,这个子进程执行

execve("./test",char * const argv[], char * const envp[])

execve加载./test,并把参数argv[],envp[]一步一步传递下去。加载了./test之后,从./test的入口开始执行,即ELF文件中的_start(),_start()调用__libc_start_main(),

最后到了main。

int main(int argc, char *argv[], char *envp[])

看着这个main的定义和execve相似吧,没错main中的参数都是execve一步步传递下来的。argc是命令行参数个数,argv[]存储着各个参数的指针(注意argv[0]通常是程序
名,argv[1]开始才是命令行参数。这是由shell设置的),envp[]存储着环境变量表。然而在标准C中只定义了int main(int argc, char *argv[]),所以unix-like平台也提供了全局变量environ指向环境变量表。
extern char **environ;
当然也可以用getenv和putenv来访问特定的环境变量。

对了,父shell还在wait()./test的结束呢,不错,test中main函数return的值,在被__libc_start_main() exit之后,终于被父shell抓住了,可以用$?访问。
如$> ./test
$> echo $?
可以得到test返回的值。这样,你就知道main()函数中return的意义,以及如何在shell中使用了吧。尽管可以return任何值,也建议用return 0来表示程序正常结束。这样别人用shell脚本调用你写的程序的时候,就可以$?等于0来判断你的程序是否正常执行了。

最后小结一下:
1. 避免使用void main(),尽量使用int main() 或者 int main(int argc, char *argv[])。
2. 在main的结尾记得 return int;, 最好用return 0;表示程序的正常结束。
3. main函数和普通函数一样也是能被调用的。
4. main return的值最终会返回给其调用者,如shell中执行的程序,可以在shell中用$?得到其返回值。
5. 在unix-like环境中,可以使用int main(int argc, char *argv[], char *envp[]), extern char **environ; , getenv()等方式来得到环境变量。
By Pthread
08.01.03



转载于http://bbs.xjtu.edu.cn/BMYFCDNGVVOVKBJEODGGKGEVBHWWPNWLQJHI_B/[/list]


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 16 篇帖子 ]  前往页数 1, 2  下一页

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译