百思不得其解!关于using namespace std;的问题

小小海怪 2017-03-21 08:36:41
是一道简单的PAT上的题目:N个数求和 链接:https://www.patest.cn/contests/gplt/L1-009
但是遇到了一个困惑鄙人好几天的问题,
代码完全是用C语言写的,交代码的时候显示第三个用例错误,但是只要将预定义写成
#include<cstdlib>;
#include<cstdio>;
using namespce std;
就正确了。有人知道这是为什么吗?!求助!
代码如下:
//#include<cstdio>
//#include<cstdlib>
#include<stdio.h>
#include<stdlib.h>
#define ll long long
//using namespace std;
ll gcd(ll a, ll b)//最大公约数
{
return a%b==0?b:gcd(b,a%b);
}

int main()
{
ll N,gfm,fzh,zs,fsfz;//公分母 分子和 整数 分数分子
ll fz[100000],fm[100000];
scanf("%lld",&N);
for(int i=0;i<N;i++)
{
scanf("%lld/%lld",&fz[i],&fm[i]);
}
gfm = fm[0];
for(int i=1;i<N;i++)//求公分母
{
gfm = gfm/gcd(fm[i],gfm)*fm[i];
}
fzh = 0;
for(int i=0;i<N;i++)//求分子和
{
fzh += gfm/fm[i]*fz[i];
}
zs = fzh/gfm;//整数部分
fsfz = abs(fzh%gfm);//分数部分的分子
if(fsfz==0)
printf("%lld\n",zs);
else
{
if(zs!=0)
{
printf("%lld ",zs);
}
if(fzh<0&&zs==0)
printf("-");
printf("%lld/%lld\n",fsfz/gcd(fsfz,gfm),gfm/gcd(fsfz,gfm));
}
return 0;
}

...全文
542 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
小小海怪 2017-03-27
  • 打赏
  • 举报
回复
懂了懂了!谢谢14楼大神 正解
小小海怪 2017-03-24
  • 打赏
  • 举报
回复
引用 16 楼 idzeta的回复:
更正一下: abs是在<cstdlib>与<stdlib.h>中声明的。 [quote=引用 15 楼 chdjqh 的回复:]那c语言就没法交对这个代码了吗
C99标准中: <stdlib.h>有long long llabs(long long n); <inttypes.h>有intmax_t imaxabs(intmax_t n); [/quote] 还是不理解哎,我想知道这个代码怎么改,然后再从中领悟为什么
idzeta 2017-03-24
  • 打赏
  • 举报
回复
更正一下: abs是在<cstdlib>与<stdlib.h>中声明的。
引用 15 楼 chdjqh 的回复:
那c语言就没法交对这个代码了吗
C99标准中: <stdlib.h>有long long llabs(long long n); <inttypes.h>有intmax_t imaxabs(intmax_t n);
小小海怪 2017-03-23
  • 打赏
  • 举报
回复
引用 14 楼 idzeta的回复:
这个问题以前已经有人指出了(但是许多人都无视)。 C++标准中,cstdio声明的是
namespace std {
          int abs (          int n);
     long int abs (     long int n);
long long int abs (long long int n);
}
C语言标准的stdio.h中声明的只是int abs (int n)。 所以,如果不“包含cstdio并指定在std名空间中查找”的话,编译器只会通过stdio.h找到来自C语言的int ::abs (int n),而不是你想要的int long long int std::abs (long long int n)。 如果不使用using namespace std,而明确以std::abs(参数)的形式调用,编译器就不会在你只包含stdio.h的时候悄悄使用int ::abs (int n)。(这也是经典C++编程中不建议使用using namespace std的理由。)
那c语言就没法交对这个代码了吗
idzeta 2017-03-23
  • 打赏
  • 举报
回复
这个问题以前已经有人指出了(但是许多人都无视)。 C++标准中,cstdio声明的是
namespace std {
          int abs (          int n);
     long int abs (     long int n);
long long int abs (long long int n);
}
C语言标准的stdio.h中声明的只是int abs (int n)。 所以,如果不“包含cstdio并指定在std名空间中查找”的话,编译器只会通过stdio.h找到来自C语言的int ::abs (int n),而不是你想要的int long long int std::abs (long long int n)。 如果不使用using namespace std,而明确以std::abs(参数)的形式调用,编译器就不会在你只包含stdio.h的时候悄悄使用int ::abs (int n)。(这也是经典C++编程中不建议使用using namespace std的理由。)
小小海怪 2017-03-22
  • 打赏
  • 举报
回复
引用 5 楼 vnvlyp的回复:
C++是有命名空间的概念的!头文件cstdio和stdio.h是不一样的!其他类似头文件同理。 cstdio会将符号导入到std命名空间,只是在某些平台上才会导入到全局命名空间,比如微软的VS。 所以如果你用这个,需要写std::printf, std::scanf才行,或者先导入,用using std::printf;,或者直接导入所有用using namespace std; stdio.h的话则将符号直接导入到全局命名空间里。 理论上你要写::printf的,但是一般你不会自己定义一个printf,所以就算你直接写printf也会是stdio.h的那个printf
那用c交的话怎样改才正确
小小海怪 2017-03-22
  • 打赏
  • 举报
回复
引用 4 楼 ipqtjmqj的回复:
[quote=引用 2 楼 chdjqh 的回复:] [quote=引用 1 楼 ipqtjmqj的回复:]你的意思是用C语言是错的,改成C++是对的?
对,但是c++必须加上using这行才对[/quote] c++引入命令名间就是为了防止名字冲突,所以标准库中定义的函数都在std命令空间之内, 如果要使用xxx函数,则写using std::xxx; 写成using namespace std;会引入std内的所有名字。[/quote] 我用的不是自己定义的gcd函数吗?
小小海怪 2017-03-22
  • 打赏
  • 举报
回复
引用 3 楼 mango_haoming的回复:
可能用c编译的时候变量声明的问题,c语言的变量声明都全部要声明在前面。但是for循环里有int i;我觉得可能是这个问题
刚试了下,不是这个问题
vnvlyp 2017-03-22
  • 打赏
  • 举报
回复
C++是有命名空间的概念的!头文件cstdio和stdio.h是不一样的!其他类似头文件同理。 cstdio会将符号导入到std命名空间,只是在某些平台上才会导入到全局命名空间,比如微软的VS。 所以如果你用这个,需要写std::printf, std::scanf才行,或者先导入,用using std::printf;,或者直接导入所有用using namespace std; stdio.h的话则将符号直接导入到全局命名空间里。 理论上你要写::printf的,但是一般你不会自己定义一个printf,所以就算你直接写printf也会是stdio.h的那个printf
ipqtjmqj 2017-03-22
  • 打赏
  • 举报
回复
引用 2 楼 chdjqh 的回复:
[quote=引用 1 楼 ipqtjmqj的回复:]你的意思是用C语言是错的,改成C++是对的?
对,但是c++必须加上using这行才对[/quote] c++引入命令名间就是为了防止名字冲突,所以标准库中定义的函数都在std命令空间之内, 如果要使用xxx函数,则写using std::xxx; 写成using namespace std;会引入std内的所有名字。
「已注销」 2017-03-22
  • 打赏
  • 举报
回复
可能用c编译的时候变量声明的问题,c语言的变量声明都全部要声明在前面。但是for循环里有int i;我觉得可能是这个问题
小小海怪 2017-03-22
  • 打赏
  • 举报
回复
大家可以照着我说的去上面链接交一下试试,用c的预定义交c,c++的交c++,神奇的地方就是只要改成c++那套预定义就会正确了,
小小海怪 2017-03-22
  • 打赏
  • 举报
回复
引用 9 楼 vnvlyp的回复:
[quote=引用 8 楼 chdjqh 的回复:] [quote=引用 5 楼 vnvlyp的回复:]C++是有命名空间的概念的!头文件cstdio和stdio.h是不一样的!其他类似头文件同理。 cstdio会将符号导入到std命名空间,只是在某些平台上才会导入到全局命名空间,比如微软的VS。 所以如果你用这个,需要写std::printf, std::scanf才行,或者先导入,用using std::printf;,或者直接导入所有用using namespace std; stdio.h的话则将符号直接导入到全局命名空间里。 理论上你要写::printf的,但是一般你不会自己定义一个printf,所以就算你直接写printf也会是stdio.h的那个printf
那用c交的话怎样改才正确[/quote] C都不存在cstdio这种头文件,你当然只能#include <stdio.h> 而且C没有命名空间的概念,所以你直接用printf, scanf就好了 [/quote] 我的问题就是,用c的这些东西显示一个用例错误,只有使用了c++的那些头文件和using才正确
小小海怪 2017-03-22
  • 打赏
  • 举报
回复
引用 10 楼 ESMGAL的回复:
如果你真的百思了 我认为你还是能找到答案的。另外,建议把把C和C++当成两门语言来学,目前随着C++的拓展,差异越来越大了。
我是个初学者,自己思考量有限,就是到处找答案找了好久了
ESMGAL 2017-03-22
  • 打赏
  • 举报
回复
如果你真的百思了 我认为你还是能找到答案的。另外,建议把把C和C++当成两门语言来学,目前随着C++的拓展,差异越来越大了。
vnvlyp 2017-03-22
  • 打赏
  • 举报
回复
引用 8 楼 chdjqh 的回复:
[quote=引用 5 楼 vnvlyp的回复:]C++是有命名空间的概念的!头文件cstdio和stdio.h是不一样的!其他类似头文件同理。 cstdio会将符号导入到std命名空间,只是在某些平台上才会导入到全局命名空间,比如微软的VS。 所以如果你用这个,需要写std::printf, std::scanf才行,或者先导入,用using std::printf;,或者直接导入所有用using namespace std; stdio.h的话则将符号直接导入到全局命名空间里。 理论上你要写::printf的,但是一般你不会自己定义一个printf,所以就算你直接写printf也会是stdio.h的那个printf
那用c交的话怎样改才正确[/quote] C都不存在cstdio这种头文件,你当然只能#include <stdio.h> 而且C没有命名空间的概念,所以你直接用printf, scanf就好了
小小海怪 2017-03-21
  • 打赏
  • 举报
回复
引用 1 楼 ipqtjmqj的回复:
你的意思是用C语言是错的,改成C++是对的?
对,但是c++必须加上using这行才对
ipqtjmqj 2017-03-21
  • 打赏
  • 举报
回复
你的意思是用C语言是错的,改成C++是对的?

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧