"printf("未定义标识符 cout的表示符是怎么回事啊,用的vc2017

欢迎访问C语言网www.dotcpp.com
比赛栏每月有奖月赛!举办比赛联系QQ:问题反馈、粉丝交流
蓝桥杯训练群:
申请群时请备注排名里的昵称C语言研究中心 为您提供有图、有料、解渴的C语言专题! 欢迎讨论!
今天这篇,想给大家把printf拿出来再详细讲一讲,因为不少同学反映只会用,但一些参数、返回值什么的还不了解,所以今天总结一二,给大家总结和梳理一下,算是抛砖引玉,能给大家打开大门,下面开始。
首先,以下四种printf的用法想必大家都应该很熟悉。
除此以外,各种\n、\t 、\r、\b等转义字符不再讲解,大家可自行查表。
我们着重讲解以下几种功能:
1.多进制转换功能
除了上图截图所示,我们可以输出常规字符、数字、字符串、小数以外,我们还可以输出我们想要的十进制对应的八进制、十六进制数。如下图,输出99和它对应的八进制和十六进制数,方便快速转换输出:
但注意,程序里体现不出二进制哦!
2.控制输出占位宽、左右对齐。
以%d为例,我们输出的数字默认都是以实际占位输出,如下图:
当我们想以每个数字都用固定的宽度输出时,可以在%和d之间加一个数来表示位宽,比如占10位,则写成%10d,效果如下:
看到了吗?如果想让它们还像原来左打头呢,就把10换成-10即可,试试看:
此时依旧占位10个字节,虽然肉眼看不出来!
3.小数位数控制
大家在定义float和double类型时,有没有遇到过这样的情形呢?
浮点数a只有两位有效小数,而%f默认输出6位,就会有多余的4个0,我不想要怎么办?答:控制小数位数。
怎么控制?%和f之间加.2即可,变成%.2f,效果如下:
如果保留5位就%.5f以此类推,并且可以和上面讲的控制位宽和对齐方向同时使用哈。给大家看看:
一共占5位,靠右对齐(这里抛一个问题,如果这里位宽为3小于实际4位怎么办?请自行思考上机测试)
怎么样,大家学会了吗?
*在printf里可以代表一个泛整数,可以代表任何整数。它可以出现在位宽的位置,也可以出现在小数位数的位置。
但在printf的双引号外面,必须要有*对应的数值。
比如我的位宽不确定,想用整数a表示,则可以写成:
表示输出浮点数a,占b个宽度,能看明白吗?
同理,也可以左对齐,也可以再用一个*数字表示小数。注意*和数字的对应关系即可。如下:
5.返回值的作用及用法
不少同学问过我说printf的返回值是什么意思,此前可以参考文章《》中第一个题的讲解学习。
printf的返回值为一个整数类型,是打印的字符个数,而并非几个数字、几个字符。和位宽的概念一致,比如
注意这里\n转义字符也算一个。
以上,大家亲自上机测试,很容易明白。
有问题请大家随时留言联系我们!
以上几种功能,大家看明白了吗?看明白赶紧上机测试吧!
还有什么功能、不明白的问题欢迎留言告知我们!
(www.dotcpp.com)
C语言网, 版权所有丨如未注明 , 均为原创丨本网站采用协议进行授权 , 转载请注明!Visual Studio 2015 的安装与使用
时间: 12:58:26
&&&& 阅读:83231
&&&& 评论:
&&&& 收藏:3
标签:为什么要使用Visual Studio 2015?
它是中文的、界面友好、自动补全、实时语法错误提示(上图中波浪线部分)、单步调试……最重要的社区版是免费的!所以你不必再昧着良心使用不合法、老旧的不兼容当代系统的VC++6.0,Come to VS2015 and enjoy it!
接下来我将告诉你如何安装以及使用它编写、运行C/C++程序!
?获得Visual Studio 2015
进入,点击"下载Visual Studio社区"。
如果一切正常,你会得到一个大小大约为3MB的应用程序(我假设你知道如何下载,并且知道如何找到下载的文件):
双击它,稍等片刻,来到这个界面:
不用修改安装目录,选择"自定义",点击"下一步",来到这里:
只选择"编程语言"下的"Visual C++",点击下一步,来到这里:
核对一下,点击"安装",看到这个界面后:
就可以点击"最小化"玩别的了,安装过程大约要一个小时,期间需要保持网络畅通。
完成了!看到那个巨大的"启动"了吗?点!
在VS中建立一个C/C++程序项目
现在,我们就可以开启VS之旅了!
打开VS2015,它可能会让你登录:
这里可以如果你愿意,可以登录,我这里选择"以后再说":
这里的开发设置,我选择"Visual C++",颜色我选择了酷炫的"深色"。(根据喜好来就行,不必犯选择困难症,反正以后也能改)
万事俱备,"启动Visual Studio"!
稍等片刻,你就会看到这个界面:
点击菜单:"文件"-"新建"-"项目",会出现这个窗口:
选择左侧的"Visual C++"之后,选择右侧的"空项目",项目名称填写"MyFristCPromgram",点击"确定"。(当然项目名你不必像我一样写这么长,随便打几个字母也是可以的)
之后,在左侧的"解决方案资源管理器"中,右键"头文件","添加","新建项"。(如果没有左侧的"解决方案资源管理器",可以点击菜单:"窗口"-"重置窗口布局")
在弹出的窗口中,修改新项的名称为"main.h"(你喜欢的话也可以用"main.c"或"main.cpp"或者随便起名字)
现在就可以书写你的代码了:
让我们向这个世界问好,写下这些代码:
点击工具栏上的那个三角形的绿色按钮("本地Windows调试器")来运行,或者更快捷的方式是直接按F5。
勾选"不再显示此对话框",点击"是"。
一闪而过!
"导演,剧本看起来不对啊!"
当你点击运行按钮或按F5后,程序一闪而过,怎么回事,VS2015的BUG?
并不是,我们看看这段程序,这段程序只有一行printf,没有任何别的语句,计算机瞬间就能执行完,执行完不就结束了吗,这就是一闪而过的原因。
但是我要看输出的文字啊,怎么让它在printf后停住呢?
很简单只需要使用 system("pause"); 命令即可,像这样:
你会发现 system 被画了红色的波浪线,将鼠标移上去发现VS告诉我们这是一个未定义的标识符,因为system所在的库我们没有包含,我们加上这行include:
按下F5,现在,你就已经学会如何使用Visual Studio来编写和运行简单的C/C++程序了:
如果你不想为使用system("pause");包含一个库,也可以使用scanf函数来等待输入,从而暂停程序,或者你可以在最后一个花括号那行,设置一个断点,这种方法我们将会在之后详细讲解。
教练,scanf不能用?!
"VS的问题怎么这么多!连scanf都不能用还写C程序?"
等等,请你先冷静下来,打勾"不再显示此对话框"点击"否",让我们仔细看看输出的这条错误信息:
error C4996: ‘scanf‘: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
VS告诉我们,这个函数可能不安全,应该考虑使用scanf_s来代替(到底哪里不安全,有兴趣的宝宝可以看本节尾部的选读小节)。或者定义_CRT_SECURE_NO_WARNINGS宏来屏蔽这个警告。
所以第一种方式我们可以修改scanf为scanf_s,便可以通过编译
它看上去工作良好!
"不行!我偏要用scanf!我偏要用!偏要用!!"
对于这种强迫症患者,我们可以通过定义_CRT_SECURE_NO_WARNINGS宏来关闭VS的安全警告:
这两种方法任选其一即可,同时在关闭VS安全警告后,scanf_s仍然是可用的。
不安全的scanf(选读)
当使用scanf通过%s读入字符串的时候,很多初学者会忽略用户输入的字符串长度的问题,导致缓冲区溢出后程序不稳定。观察下面这个程序:
首先程序开辟了5个字符的空间来接受输入,但问题是,你并不知道用户会输入多少。
让我们运行起来这个程序,输入一个明显大于5个字符的文本,测试一下:
"哈哈!什么事情都没有,你根本在吓唬我!"
别高兴的太早,按任意键结束这个程序:
VS给我们提出了警告,告诉我们"str"这个变量的堆栈不正常,其实这就是之前我们提到的术语"缓冲区溢出",当我们将长数据放入短位置的时候,多出来的部分就会覆盖程序的其它数据,有时被覆盖的东西不重要,程序正常工作,有时重要,程序崩溃,这就叫不安全。
"但是我用VC++6.0的时候可没出这个错啊?"
我想是因为VC++6.0太老旧,没有检查这种问题的能力。
这种问题还有一个比较隐蔽的发生形式:如果我们正好输入5个字符呢?比如"Hello"。
事实上仍然会缓冲区溢出,因为字符串是以‘/0‘字符结尾,其本身也占一个位置,所以"Hello"实际上是6个字符!
使用VS自动调整代码缩进
经常我们从别处粘贴来的代码缩进不正确,或者很多不拘小节的人写代码可能从来不注意缩进,虽然缩进不是C/C++语法的一部分,但是十分影响程序的可读性。
就比如一个判断三角形形状的程序,有的小朋友就能写成这样:
别笑,这正是我见过的。这确实对编译器并没有什么障碍,但是如果你要修改这样的代码,你得比平常多花起码三倍精力。就比如我问你,倒数第二个else搭配的是哪个if?你能一眼看出来吗。
现在我们使用VS的自动格式化代码的功能,选择要被格式化的代码,这来我们选择全部(Ctrl+A):
按住Ctrl,按一下K,按一下F,神奇吗?
那么现在我再问你,倒数第二个else搭配的是哪个if?
?使用VS的断点与单步跟踪功能
经常,为了找出程序的问题点,我们可以在VS中设下断点并且一步一步跟它着执行,观察各个变量的变化情况,来找到错误的地方。
回到本文之前的那个计算完全平方的程序,右键for循环的那一行,"断点"-"插入断点"。(或者先将光标移动到这一行,然后按F9,再或者直接点击行首空白处)
在本行的首部将出现一个红圈,点击这个红圈可以取消断点。
F5运行程序,为scanf_s输入"10"回车,窗口会自动跳转至VS,光标自动定位到断点行。
这时将鼠标移动到任意一个变量名上,就可以查看这个变量的值。我们移动到i这个变量上:
看到它拥有一个诡异的值。
"不对,啊,我不是给i赋值0了吗?就在这行!"
是的,但断点断下的时刻是这行执行之前,也就是现在的i还没被定义以及初始化,它的值自然是不确定的。
我们点击这个大头针,将固定显示i的值。
你可以将它拖动到舒适的位置,甚至你还可以手动修改它的值,添加注释,但这里我们不需要这样做。
我们按F10让程序向前走一步:
立即发现i的值变成了0,并且VS还用红色显示给我们,同时光标自动移动到了if语句,左边的黄色箭头表面当前程序运行到的位置。再按F10。
因为i满足开方后仍然是整数的条件,所以进入了if分支,准备输出这个i。
一路F10,你就可以观察清楚整个程序i是何时增加,何时输出。
当你不想再跟踪的时候,点击左边的红圈取消断点,按F5,让程序自己跑便是。
wangzexi标签:原文地址:http://www.cnblogs.com/wangzexi/p/4906597.html
多谢。中间卡在&创建新项目那里了。1.创建的新项目——“Empty&Project”,&结果创建&&&&&*.h&头文件后,&&在按&&F5&运行时,&提示&找不到&&*****.exe&文件的错误。然后去&&项目文件夹/debug&下面找&&,并没有看到&&.exe&文件。2.后来,&查了几十篇文章,&也没解决这个问题。&&&&&再后来,解决办法是&&创建了&一个&&“win32&控制台&项目”,&&然后创建的是&&&&*.cpp&文件,&&&这样子就可以顺利的跑起来了。
您好,帮我看看为啥&安装之后发生错误
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!C语言参考答案_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
C语言参考答案
&&C语言参考答案
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩39页未读,
定制HR最喜欢的简历
你可能喜欢【转】printf(&%f/n&,5)的输出结果为什么是0.000000
1,之所以没输出5,这是C语言设计的原因。
2,之所以输出0,这是计算机体系结构的问题。
具体来说:
C语言设计中,int类型一般是32bit或者16bit,而float一般是64bit,并且有可能使用科学计数保存。这点就和huhugo88所
说一样,5在内存中为00101。而且5一般都在,程序的静态存储区默认是0,那么当用%f来读时,就会读
64bit,也就是会读之前的很多位0,最后按照(有效数字)×(基数2)pow(指数)的方式来取数,自然结果是0
之所以Vc中不允许这种情况,而有些编译器就允许这么输出就是编译器设置的问题。按理说,这样访问内存是属于越界访问,
应该禁止。不过只是读,伤害性不大而已。
对于单精度浮点数(32bit),不少c语言编译系统以24位表示小数部分(包括1bit符号位),以8位表示指数部分。
==========================
printf("%d/n",5.01);
为什么输出一个大数?
在讲这个题目之前,预备知识,讲一下,printf函数,输入参数是读入缓冲区保存,再按照%?的格式从缓冲区中读出数据,并据此格式解释数据。
有了这个知识之后,在讲程序员面试宝典上看到一个题:
#include "stdio.h"
int main(int argc, char* argv[])
printf("%d/n",5.01);
输出结果为:
然后开始研究为什么会是这个数?
5.01是double类型,内存中占8个字节,保存在缓冲区。而%d为整型,占4个字节,printf从缓冲区中读入4字节,先读到低32位的数据。也就是说printf输出的应该是5.01以double类型保存数剧的低32位。为了检验此结果是否正确,对比5.01在内存中的表示与输出。
#include "stdio.h"
int main(int argc, char* argv[])
double d = 5.01;
int *p = (int *)(&d);
int rst = ;
printf("1).%x/n",*p);
printf("2).%x/n",*(p+1));
printf("3).%x/n",rst);
1).0x70a3d70a
2).0x40140a3d
3).0x70a3d70a
这也就证明了%d输出了5.01的低32低。5.01的double类型,在内存的的表示为0xa3d70a。
事情看似也就完成了。
我又想,如果输入是浮点类型的5.01f,又会发生什么呢?
#include "stdio.h"
int main(int argc, char* argv[])
float f = 5.01f;
int *p = (int *)(&f);
printf("1).0x%x/n",*p);
printf("2).0x%x/n",5.01f);
1).0x40a051ec
我们发现,此时输出的并不是浮点类型5.01f的内存的表示,这是为什么呢?
然后看到一个说法,是printf会把%f按double类型输出,也就是说会把参数float型的转成double型在输出。
但现在并不是%f,当然用%f显示的是正确的结果。于是我猜测,printf是将所在float型读入的数据都自动的转化为double型了,然后%f就按double处理,而我们这是%d,所以显示的为float转化为double型后的低4字节。
验证此想法:
#include "stdio.h"
int main(int argc, char* argv[])
double f = 5.01;
int *p = (int *)(&f);
printf("1).0x%x/n",*p);
printf("2).0x%x/n",*(p+1));
printf("3).0x%x/n",5.01f);
1).0x70a3d70a
2).0x40140a3d
但是我们发现结果并不一样,于是我又猜想,也是许printf将float转化为double的方式与默认的方式不一样
5.01d的默认的表示为:0xa3d70a,在上面已经说明了
#include "stdio.h"
int main(int argc, char* argv[])
printf("0x%8x/n0x%8x/n",5.01f);
0x40140a3d
与是发现printf将5.01f-&5.01d的表示是:0x00000
接着就是看这两个值是否都是为5.01了:
#include "stdio.h"
int main(int argc, char* argv[])
int d1[2], d2[2];
d1[1]=0x40140a3d;
d2[0]=0x70a3d70a;
d2[1]=0x40140a3d;
double *p1 = (double *)d1;
double *p2 = (double *)d2;
printf("1).%f/n",*p1);
printf("2).%f/n",*p2);
1).5.010000
2).5.010000
也就证明了0x00000,与0xa3d70a都是5.01d在机器中的表示。前者为5.01f(0x40a051ec)由printf转化为double后的表示,后者为5.01d的默认的表示。
总结:printf将输的浮点型参数全都自动转化为双精度型,且与默认的双精度的表示方法是不同的。最重要一点,printf不安全,类型不安全,要是类型不对了,也许我们就挂了^_^
没有更多推荐了,I asked a similar question, but I have some update which is really confusing me. Essentially, I want to link a number of object files with the linker as follows:
/usr/ccs/bin/ld -o q -e start_master -dn -z defs -M ../../../mapfile.q {list of object files}
I get the following error:
first referenced
The interesting things is, that memset is not referenced in reconf.c and I also grep'ed the whole directory but there is also no reference in any of the other files to _memset. Therefore I am wondering why I get this error message from the linker, although nowhere in my source code _memset is actually used. Anyone an idea what could be going on here?
Thanks so much, this error is driving us mental!
I tried to add the path to the library of memset and linked it with -lc and run it in verbose mode:
/usr/ccs/bin/ld -o q -e start_master -dn -z defs -z verbose -L/usr/lib -M ../../../mapfile.q {list of object files} -lc
Then I get the following error:
ld: fatal: library -lc: not found
ld: fatal: File processing errors. No output written to q
And this although libc.so is clearly in /usr/lib ...
Doing some more research it seems that on Solaris 10 static linking disappeard as you can read here:
Probably this is my problem. Has anyone an idea how I could rewrite my linker command for a workaround to this problem?
Many thanks!
解决方案 Probably you did:
struct S v = { 0 };
v = (some const-variable).
uint8_t b[100] = { 0 };
Some compilers are putting implicitly the built-in memset (or memcpy) for such things. The built-in memset then is called _memset (in your case). Once you link and your libc (or what provides standard-function in your case) does not providie it, you are getting this link error.
本文地址: &
我问过类似的问题,但我有一些更新,其中实在是困惑我。从本质上讲,我想和链接器链接一些对象文件如下: 的/ usr / CCS /斌/劳工处-o q -e start_master -dn -z DEFS -M ../../../mapfile.q {目标文件列表} 我收到以下错误: 未定义第一次引用 在文件符号_memset reconf.o 有趣的事情是,这memset的不reconf.c引用,我也grep'ed整个目录,但也有没有参考任何其他文件,以_memset。因此,我很奇怪,为什么我得到的链接此错误信息,但无处在我的源$ C $ C _memset实际使用。任何人的想法可能是怎么回事?太感谢了,这个错误是推动我们精神!编辑:我试图路径添加到memset的图书馆,并与-lc链接,并在详细模式下运行: 的/ usr / CCS /斌/劳工处-oq -e start_master -dn -z DEFS -z详细-L / usr / lib目录-M ../../../ mapfile.q {目标文件列表} -lc 然后我得到以下错误:
LD:致命的:库-lc:未找到
LD:致命的:文件处理错误。无输出写入到q 这虽然libc.so显然是在/ usr / lib中... 混淆编辑II:做一些更多的研究,似乎在Solaris 10上静态链接disappeard,你可以在这里阅读:
也许这是我的问题。有没有人一个想法,我怎么可以重写我的链接器命令的解决方法,这个问题?非常感谢!解决方案 也许你所做的: 的struct V = {0}; 或 的struct伏;V =(一些常数变量)。 或
uint8_t有B〔100] = {0};
一些编译器是把隐含内置的memset(或者memcpy的)这样的事情。内置的memset则称为_memset(你的情况)。一旦你的链接和您的libc(或者什么你的情况提供了标准的功能)不providie,你收到此链接错误。
本文地址: &
扫一扫关注IT屋
微信公众号搜索 “ IT屋 ” ,选择关注
与百万开发者在一起
(window.slotbydup = window.slotbydup || []).push({
id: '5828425',
container: s,
size: '300,250',
display: 'inlay-fix'

我要回帖

更多关于 未定义标识符gets 的文章

 

随机推荐