C语言问答进阶--2、C语言简介及基本的输入输出函数

C语言简介

Q:您好,能大体介绍下C语言吗?

A:当然可以。C语言是一种计算机语言,它主要被用在系统编程里,可以说,C语言的产生就和操作系统的编写密不可分。

C语言简要历史】

1978年由美国电话电报公司(AT&T)的贝尔实验室正式发表了C语言。同时由B.W.KernighanD.M.Ritchie合著了著名的“THECPROGRAMMINGLANGUAGE”一书。通常简称为《K&R》,也有人称之为《K&R》标准。但是,在《K&R》中并没有定义一个完整的标准C语言,后来由美国国家标准协会(AmericanNationalStandardsInstitute)在此基础上制定了一个C语言标准,于1983年发表。通常称之为ANSIC

【什么是系统编程】

系统编程就是在系统级别进行程序设计。什么是系统级别?这里的系统可以把它理解成把计算机软件分为两类(系统软件和应用软件)中的系统软件,它是应用软件得以正常执行的依托。

Q:学习它有什么作用吗?

A:刚刚也说了,C语言是系统级程序设计语言,您可以用它编写操作系统和Shell,做你自己的编译器;当然,它也可以用于应用程序的设计。

【什么是操作系统】

操作系统,简单地说,就是一些程序的集合,它提供了一个基本环境,可以让您编写的应用程序得以方便地执行。比如说,你的程序中有个printf函数要打印一句话,这个时候就会进行系统调用,而操作系统就会在这个时候处理里面的细节;可以说,它方便了程序员。

【什么是Shell

Shell,英文翻译为壳的意思,在操作系统中,它一般被称作外壳。它和内核组成了操作系统。

它有什么用呢?它提供了一个接口,供用户和操作系统的内核程序进行交互。举个例子,Windows下的命令提示符cmd.exe就是Shell,比如您在C盘位置输入了dir,就可以看到C盘包含的文件夹和文件。

那么,什么又是内核呢?

它是操作系统中最基本的部分,它存在的必要性在于它屏蔽了硬件的复杂性,为应用程序提供了一个统一的接口,方便了程序设计。其实,上面所说的外壳中的各种命令就是在通过内核来完成的。

【什么是编译器】

编译器,从它的名字看,就知道它的作用是编译。编译是做什么的?从源代码的角度说,它是对源代码进行分析,得到计算机硬件能理解的二进制代码的。为什么要得到这样的二进制代码?原因很简单,计算机硬件看不懂您的源代码,它只能明白01组成的指令,想要你的程序能执行,当然需要这个转化过程了。

Q:能举个C语言很实际的一个应用?

A:可以啊。当年的Unix系统开始是用汇编写的,但是后来发现很多场合需要移植,而汇编的可移植性很差,于是就用可移植性较好的C语言改写了。

Unix系统是什么】

它是历史较悠久的操作系统,在1969年,由贝尔实验室的KenThompsonDennisRitchie等人开发出来。之后,此操作系统越来越成熟,在服务器市场占据较大比例。当然如今,Linux操作系统在服务器市场有更响亮的声音,不过它和Unix是兼容的,它的思想源于Unix.

【什么是Linux操作系统】

Linux的出现,最早开始于一位名叫LinusTorvalds的计算机业余爱好者,当时他是芬兰赫尔辛基大学的学生。他的目的是想设计一个代替Minix(这个操作系统是当时一个操作系统示教系统,Linux对此操作系统的功能不满,所以才想要设计新的)的操作系统,它和Unix的一大区别就是Linux的内核源代码是开放免费的,任何人还可以根据需要对源代码进行修改。

【什么是汇编语言】

汇编,英文为"assemble",意为组装、装配。可以把它看做是机器语言的另外一种形式。当然,它使用了大量的助记符,这个也使得程序员摆脱了机器语言那样的01代码,使得程序设计变得相应更简单点。当然,它不能让硬件直接执行,得通过一个叫汇编器的工具把汇编代码转化成机器代码这样才可以。在程序设计早期,汇编很流行,尤其是高级语言没有出现前。而在高级语言出现之后(如C出现之后),汇编的地位变得弱了,因为毕竟汇编还是和硬件有较大关系,这不方便程序员的程序设计。但是,在一些对速度要求极高的场合(如操作系统中与硬件打交道中的某些地方),汇编还是有可以发辉的场地。

【什么是机器语言】

机器语言,顾名思义,就是机器能看明白的语言。它就是01的序列,可以让硬件直接执行;当然,它有自己的规则。在程序语言最开始,就是用的这种语言,然而,可想而知,如果程序员每天都在和01打交道,这会是多么乏味和棘手的事情。也正是这个原因,之后的汇编语言诞生了。

QC++C有什么区别和联系吗?

ACC++的子集,C++是扩展了的C。它增加了比如面向对象思想中的类的概念等。C写的代码一般可以当作C++代码去编译,当然反过来就不一定成立了。

C++简要介绍】

C++是美国的贝尔实验室的BjarneStroustrup博士在20世纪80年代初期发明并实现的,最开始C++是被称作"带类的C",以后才被正式称作C++的。

Q:还有很多种程序设计语言,比如Java,C#等等,它们和C语言的区别是什么?

A:程序设计语言一般来说都有共同的特征,这个就像汉语和英语同为人类交流的语言,都有主语、谓语、宾语一样;当然,程序设计语言又各有不同:因为就在于它们是被设计用作不同用途而导致有所区别。

举个很简单的例子,你和你的同事工作于一个机密场合,你们为了防止你们的对话被别人截取,你们两个设计了一套语言规则:

BB,就等于告诉对方再见(ByeBye);

HL,就等于告诉对方您好(Hello);

SP,就等于告诉对方停止(Stop);

或者说,在你们的范围内,这些是成立的;当然对于别人看来,可能一点都不明白了。程序设计语言也是,C#语言中有个foreach关键字,而这在C语言中就是不可理解的。

另外,Java最注重网络的应用和跨平台特性,c#Java类似,它们都为了使得程序能在不同平台更方便地移植而设计的。

Java简要介绍及与C的一些不同】

Java语言最初并不是为了能使得程序可以在不同平台方便移植而设计的,只是后来发现它可以在这方面有所作为,Sun公司才把Java向这方向推动的。它为什么可以在不同平台很方便地移植?原因在于它有一个虚拟机,它负责在不同计算机硬件平台之间进行中间转换,使得Java程序可以在不同平台可以不加修改地执行。而正因为如此,Java的程序首先被编译成了中间状态的代码,也被称作字节码,即.class格式文件,这种文件可以被Java的虚拟机执行,它根据不同平台,然后再把真正要执行的指令传给计算机的硬件去执行。这和C语言的程序不同,C语言程序是被编译成机器码而被执行的,这当然有硬件相关性,也是造成C语言不能像Java那样非常方便地移植。可是,之前说过C语言比汇编的优点就在于它的可移植性,在这里怎么又说它的移植性不太好了?其实,说到底,问题就在于,想要可以在Windows环境下运行的C语言的程序也能在Linux下环境,就必须把它的源代码在Linux平台上的C编译器上再进行编译(当然这里排除一些WindowsLinux下极不兼容的地方),这样基本就可以执行了。然而也正是这个原因,它在这个方面没有Java有优势。

C#简要介绍】

C#语言是微软公司推出的和Java语言竞争的一门新语言,它和Java酷似。它综合了VB的高生产率和Java的跨平台性,为了实现在.NET环境下代码的可移植性。当然,如今Java依然占据着跨平台的领头羊的位置,C#将会扮演什么角色,我们拭目以待。

HelloWorld!程序

Q:举个“HelloWorld!”的例子吧。

A

#include

intmain()

{

printf("HelloWorld!");

return0;

}

运行结果如下(是用VC6.0编译的,后面的代码如果没有特别说明,均是用此编译器编译的):

Q:好像我能看明白有个printf似乎是打印的意思;然后后面有要打印的"HelloWorld!"的字符。为什么它的两边要有花括号括起来呢?VB中的print没有这个括号,这里是什么语法规定吗?

A:是的,这是语法规定。这里的printf是个函数名,它后面是要加参数的,而参数就放在括号内。您现在就把括号理解成函数的必要组成部分好了。

Q:函数?和我在初中、高中学的函数是一个意思吗?

A:呵呵。在意义上很相似,在实际上也基本上一个意思。

Q:那我只是想打印一条语句,为什么要用到函数呢?这又不像我想求平方根一样,用一个函数来表示。

A:问的好。应该说,C语言为了统一模式吧,把任何一个过程都得看成是函数模式,所以在这里的打印也得用上个函数。但是,不要小看这个打印过程,在硬件上可是要进行很多操作的,如果这么想来,把它当作个函数也不为过。

Q:那它的函数名是什么?是"intmain()"吗?

A:你想呢?

Q:我想应该是这样。但是要是我想,用一个单词就应该表示了。

正如以前学的y=f(x)函数一样,函数名就一个字母f,够简洁的了。

A:说的好。其实这里的函数名就是main,后面的return0;就是配合这里的int的。int代表了main函数的返回值类型。数学中学的y=f(x)函数不会对返回值做太多的限制,而在计算机中这个问题就是重要问题了,因为返回值类型决定了用多少个字节来保存这个数据等等作用。

Q:哦。那int是什么?

A:它代表整型。

Q:就是数学中的整型数吗?

A:应该说,只是数学中整数的子集,而且是整数集合中很小的一部分。

Q:啊?为什么这么说呢?计算机不是可以为我们计算很多事情的吗?怎么它还表示不了所有的整数?

A:是的,它表示不了所有的整数。其实这个问题你得从以前的思维中转变过来:以前我们要表达一个很大的数,比如100亿,你可以写10000000000,但是如果遇到您的纸张大小不够,您也写不了。计算机的各种计算是在CPU中计算的,而要为被操作的数留个位置,这些位置被称作寄存器,但是寄存器的存储容量是有限的,这也决定了光用计算机的硬件可以表达的数是有限的。

当然,我们可以通过软件的方式来扩展数,达到我们想要的大小和范围。

Q:好像我明白了一些。那么有int类型的返回值,也有别的类型吧?

A:对。还有比如float,double之类的浮点类型。不过基本类型不多,很快你就会接触了。

Qintinteger的缩写吧?

A:是的。还比如有一种叫字符型的,被写作char,它就是character的简写。在程序设计语言里,简写是个很常见的事情了,毕竟简便多了。不同语言的简写方式也可能有所不同,就像Basic语言中的整型被简写成Integer.

Q:哦。那么main之后的括号的作用是什么?哦!对了!它和y=f(x)的括号的意义是一样的吧?

A:是的。

Q:可是它里面怎么什么也没有啊?数学中的函数可一般都有参数的!

A:呵呵……那你想在里面放什么呢?

Q:让我想想……

我在想,如果只是打印这句"HelloWorld!"这句话,那么不如把"HelloWorld!"放进main后面的括号中,就当作是默认在后面就直接打印它就结束,不用再在后面写那个printf的打印语句了,这样不行吗?

A:嗯!好想法!不过C语言的设计者不是你这么想的。他们只把这个main函数后面的参数限定为两种参数模式:

一种是无参,也就是这里的什么都没有;

另外一种是类似如下的形式:intargc,char*argv[]

.

Q:那这后面一种是什么意思?好古怪啊!

A:是啊。挺古怪,不过这是有道理的。应该说,在C语言诞生那个年代,人们用的操作系统是命令行式的系统,也就是输入一段数据,然后得到我们要的结果;不像我们现在用的更多的是GUI界面。命令行,您可以在MS-DOS中的CMD里获得体验。

输入dir,回车,然后就会显示出您所在目录下的文件及文件夹。

输入dir/s,回车,然后就会显示出您所在目录下的文件和子文件的文件。

dirdir/s的区别是什么?

一个字符多,一个字符少。而在程序语言中,这就被称作参数个数的不同,也就是argc的值;

显然,第一个的argc等于1,第二个等于2.

后面的char*argv[]就是指参数的值:第一个指dir,而第二个指dir/s.

不过这个现在说了有点早了,以后您会体会地更深刻的。

Q:那么main()后面的{和最后的}也被看做是函数的一部分了?不能不要它们吗?

#include

intmain()

printf("HelloWorld!");

return0;

把这个作为一个文件,我想计算机也可以看得明白写的是什么意思呀。

A:需要加两个花括号当然有它的原因了,至少能使程序更美观,可以让一个程序员较为清楚地知道这个函数的范围。当然,程序代码中并不一定只有一个函数,当有别的函数时,如果没有可以表明函数结束的标记,那么怎么知道一个函数已经结束了?

Q:那么最上面的#include是做什么的?

A:您看到printf()这个形式的东西了吗?它是什么?

Q:它是个函数。

A:它从何而来?

Q:我不知道。

A:那就对了。它正是#include后面的stdio.h文件包含的。有了这个语句,后面就可以直接使用print函数了。

Q:前面给的是C的基本输出程序,能给个C++的基本输出程序吗?

A:如下代码:

#include

usingnamespacestd;

intmain()

{

cout<<"Hello"<

return0;

}

执行结果是:

QC中是用函数输出的,这里没有括号,这里不是用函数输出的吗?

A:呵呵,其实这里也用函数了,就是<<,它是运算符重载的效果,以后会具体介绍的。

Q:在C++中,只要把要输出的放到cout<<后面的双引号中,就可以按双引号中的样子输出了是吧?

A:是的,这和C中把它们放到printf后输出列表的双引号中是一个道理。

Qcout是什么意思?

A:你得把它分开看:开始是c,代表了C++语言;后面是out,代表是"输出"的意思。

Q#include这也是个头文件包含吧,这个头文件怎么没.h的标示了呢?

A:其实有没有.h并不重要,只要这个文件里面确实有我们所要的一些函数、宏定义等信息就可以了。

如下是此文件所在文件夹里的位置(头文件一般位于Include文件夹下):

Q:那么usingnamespacestd;是什么意思?

A:这个是表明使用标准命名空间的意思。关于命名空间,以后会有更具体地介绍。

Q<代表什么?

A:这个代表输出换行;

【此程序的另外一个形式】

#include

intmain()

{

std::cout<<"Hello"<

return0;

}

执行结果是:

执行是一样的;但代码的区别是什么?是第一程序多了

usingnamespacestd;

而第二个没有这个,但是把函数的前面加了std这个修饰符,当然起到了同样的作用!

而若是没有,那就错了:

#include

intmain()

{

cout<<"Hello"<

return0;

}

编译错误:

错误表明是那个叫cout的系统不认识它,这也就是命名空间应该起到的作用

【深入编译错误】

看到上面的errorC2065这样的东西,表示编译的错误代号是2065C大概代表是Compile,

VCMSDN中,输入C2065就可以查看到关于此种编译错误的具体内容。

如下为示例:

C++的一个简洁之处】

假设定义了3个整型变量a,b,c:

也许曾几何时你还在这种表达感到麻烦的时候:

printf("%d/n%d/n%d/n",a,b,c);

/n的作用】

/n代表换行,即在控制台窗口中另起一行输出。

C++用这个就可以了:

cout<

一气呵成,当然写的时候也挺畅快!

当然,printf也有一些简洁的地方:

charc='a';

printf("%d",c)

现在就打印了字符的整型表达方式;

而用cout就得:

charc='a';

cout<<(int)c<<endl;

尤其是在需要改变的格式多的时候,cout就显得力不从心了,而printf函数只需要简单地改下那个%后面的字符就可以方便用不同格式显示出来!

【关于以后程序的基本输出】

鉴于C++cout在表达输出方面有较多的简洁性,以后的程序代码如果没有特别说明,都以cout来输出。

【深入一段代码的汇编形式】

代码如下:

#include

intmain()

{

printf("HelloWorld!");

return0;

}

代码的文件名是:hello.c

在这里,我们使用VC6.0编译器,得到此代码的汇编形式

(使用的编译命令是:cl/Fahello.asmhello.c):

TITLE hello.c

.386P

includelisting.inc

if@Versiongt510

.modelFLAT

else

_TEXT SEGMENTPARAUSE32PUBLIC'CODE'

_TEXT ENDS

_DATA SEGMENTDWORDUSE32PUBLIC'DATA'

_DATA ENDS

CONST SEGMENTDWORDUSE32PUBLIC'CONST'

CONST ENDS

_BSS SEGMENTDWORDUSE32PUBLIC'BSS'

_BSS ENDS

_TLS SEGMENTDWORDUSE32PUBLIC'TLS'

_TLS ENDS

FLAT GROUP_DATA,CONST,_BSS

ASSUME CS:FLAT,DS:FLAT,SS:FLAT

endif

PUBLIC _main

EXTRN _printf:NEAR

_DATA SEGMENT

$SG336 DB 'HelloWorld!',00H

_DATA ENDS

_TEXT SEGMENT

_main PROCNEAR

;Filehello.c

;Line3

push ebp

mov ebp,esp

;Line4

push OFFSETFLAT:$SG336

call _printf

add esp,4

;Line5

xor eax,eax

;Line6

pop ebp

ret 0

_main ENDP

_TEXT ENDS

END

我们看到了例如Line3之类的文字,它们正是源代码的位置,其下的汇编即是源代码所在位置被编译过程中生成的汇编形式代码。关于汇编形式的代码,以后将深入探讨。

【得到汇编代码的机器码格式】

正如上的代码,在VC6.0编译器下查看反汇编(在调试状态,单击“查看”菜单,再单击“调试窗口”菜单,再进入“Disassembly”子菜单):

最左侧的以0040开头的代表的是虚拟地址;

后面有一些十六进制的格式的数即是机器码的格式;

再后面就是汇编格式的代码,和刚刚的机器码对应;

对于机器码,并不是本书会详细解释的内容。

简单的加法程序

Q:哦!明白了。现在我想知道怎么编写一个计算加法的程序。

A:如果现在让你自己设计计算加法的步骤,你会怎么设计?

Q:我会设定两个量,一个叫x,一个叫y,它们分别代表着给定的值12,然后把这两个量加起来得到我要的和。

A:您的意思就是类似如下伪代码:

x=1

y=2

printx+y

是吗?

Q:是的!

A:嗯!想得很好。C中的代码如下:

#include

intmain()

{

inta=1;

intb=2;

intc;

c=a+b;

printf("%d",c);

return0;

}

执行为:

但是它只能限定是计算两个整数的和,而且两个数的值已经在代码中给定了,别的类型和别的值是不可以计算的。

Q:我有个问题:我看在花括号里的每一行最后都有个分号;,它就是为了标明一句话的结束吗?

A:嗯!是的。前面我们说C语言的基本组成部分是函数,而这些以分号结尾的一句话就是函数的基本组成部分,也可以说是C程序就是由语句组成的了。

Q:哦!是这样呀。我看VB中一条语句都不带分号结束的,它们之间有什么本质的区别吗?

A:这个其实没什么太本质的区别,只是不同语言的语法规定不一样了;VB中可以用回车代表一条语句结束,C中以分号表明。

Q:那也就是说,下面也是可以的了?

inta=1;intb=2;intc;

A:是的!

Q:我看刚刚的那句话好麻烦:既然都是整型,用一个int标明不就可以了?

A:嗯。您说的对,C中可以在一条语句中声明或定义好几个变量。如果我不说C中怎么设计的,您能想出一个方式来表达你的想法吗?

Q:让我想想……

inta=1b=2c;这样行吗?

A:呵呵。好像也行。不过感觉有点不舒服,中间的空格让我有很悬乎的感觉。而他们是怎么设计的呢?

如下:

inta=1,b=2,c;

他们只是在你想到基础上加了几个逗号隔开不同的变量,应该看起来更清楚。

Q:哦!那么它们的声明顺序对程序有影响吗?

A:应该说,在这个程序里没影响。不过要是更复杂的了,就可能要考虑变量声明顺序的影响了。

Q:那么c=a+b;的意思就是c等于ab的和吧?

A:可以这么想。不过这个"="和我们平常数学中用的等于号还是有区别的。这里的符号叫"赋值操作符",这条语句的意思是把ab的和赋值给c.其实说到底,还是等于的意思,这个以后会具体讲解的。

Q:我看

intc;

c=a+b;

分开写挺浪费行数的,可以合在一起写吧?

A:可以!您觉得应该怎么合?

Q:和前面说的声明类似:intc=a+b;这样可以吗?

A:可以。我想学到这里你应该有一些感触了吧:

C语言,是一种计算机语言,不过得能让计算机先看得懂,计算机才能知道如何去做代码想要做的事情。正如上面:

c=a+b;这种格式理解成把ab的和放置到c中,不仅程序员或是别的人可以较容易明白,计算机也能较容易理解,当然这里所说的计算机指的是编译器了。应该说,这就是好的程序设计语言的标志之一。

Q:编译器?能介绍下编译器吗?

A:编译器就是编译这些源代码的工具。比如有MicrosoftVisualC++编译器,还有gcc编译器,还有TurboC编译器。它们的作用都是去分析源代码,得出源代码的意思,然后用类似机器代码或者就是机器代码描述源代码的意思,然后交给计算机去处理。可以说,它们是源代码和机器的接口,也可以看成是程序员和机器的接口,没有它们您的代码也就失去了可以执行的意义了,所以它们是很重要的哦。

Q:那能举个具体的例子说明下编译器是如何工作的吗?

A:可以。比如就刚刚这个程序:

#include

intmain()

{

inta=1;

intb=2;

intc;

c=a+b;

printf("%d",c);

return0;

}

首先,编译器看到了第一句话#include,当然它就把这句话当作是一个包含文件的意思,当然它的内部还很复杂;

接着,看到了int这个单词,它把它理解成整型,当然它的后面可以跟上我们说过的函数名,表示返回值为整型的函数,也可以说我们说的变量名,表示声明或是定义变量了。到后面,它看到了main,当然它也就把这个当作是函数声明了;再接着,编译器发现了{符号,那么也就把函数声明增强为函数定义了。

再朝下,就到了一些变量的声明,以及简单地计算了,编译器可以很轻松地把这些都转换成汇编代码、机器代码,在后面可以让计算机顺利而准确地执行。

当然,上面所说的只是一种简单地理解方式,实际上编译器的工作并不是这样的,它是先大致浏览所有代码,得出代码中基本结构,然后才进一步细致地分析的。

编译是一门学问,编译原理是一门单独地课程,还是很有研究价值的。

Qprintf("%d",c);中的c应该就是要被打印的那个和的值,那么前面的那个双引号里面还有个%d代表什么?

A:它代表是打印的是整型值,它正对应着后面的变量c.

ddecimal(十进制)的简写,%号是为了与d在一起表面后面要有个整型值代表它的内容。

双引号的意思是要把双引号中的内容按原文输出,当然遇到上面说的%d之类的符号就要特殊对待了。

Q:哇!好麻烦!既然前面都声明cint类型的了,为什么这里还要有个%d代表它是整型的呢?

A:那您认为怎么写就可以了呢?

Qprintf(c);这样就可以呀?

A:够简洁!不过实际上C语言这么设计是为了能表达更多的数据类型。

我们知道,数据的类型不是只有int这一种,还可以有float类型等等,那么想用别的类型格式打印您的变量值,就只需要改动双引号中的格式了。如下:

printf("%c",c);这个就代表用字符类型打印c的值。实际的运行效果是:

Q:还有个问题。就是printf("%d",c);中的c能直接用a+b替换吗?这样不更简洁吗?

A:是的。你说的是可以的。当然前面声明的变量c也就可以省略了。

#include<stdio.h>

intmain()

{

inta=1;

intb=2;

printf("%d",a+b);

return0;

}

Q:能给个关于输入的程序吗?

A

#include<stdio.h>

intmain()

{

inta;

scanf("%d",&a);

printf("%d",a);

return0;

}

Qscanf函数就是输入函数,那么也就可以计算两个数输入的数的和了吧?

A:当然可以。如下:

#include

intmain()

{

inta,b,c;

scanf("%d%d",&a,&b);

c=a+b;

printf("%d",c);

return0;

}

输入:12(回车)

结果:3

Q:这个scanf就是输入函数吧?

A:是的。后面的两个%d就分别代表要输入的两个整型数。

Q:那ab前面为什么要加&号呢?

A:这应该是最容易犯错误的地方了,现在就要记住它:scanf函数后面输入变量参数一定得是变量的地址格式,关于为什么,将在以后介绍。&是取地址运算符,关于此运算符,以后会具体介绍。

Q:哦。那这里的scanf函数也可以分开写吧,就是写成:

scanf("%d",&a);

scanf("%d",&b);

这样也可以吧?

A:当然。

Q:可是如果用您刚刚写的程序,为什么输入了1,2(回车),而之后会得不到正确的结果呢?

A:呵呵。这是因为scanf函数要求输入一定要按照双引号里面的方式来输入,不能随便改动,否则计算机可看不明白你的输入。

Q:哦。

A:你可以输入

12(回车)

1(回车)

2(回车)

都可以,当scanf函数中两个要输入的数的格式间什么也没有的时候,就默认采用空格或回车当作分隔符(当然用TAB键也可以)。

但是如果程序改为:scanf("%d,%d",&a,&b);

看到没?输入的数间加了个逗号,那么您输入的时候也要加这个逗号!不加就得不到您要的结果了。

如下为输入的时候没有加逗号得到的结果(得到了错误的结果):

如下为输入的时候加了逗号得到的结果(得到了正确的结果):

Q:有个问题:为什么用这个程序在TC中输入了1000030000,会得到一个错误的值;而在VC6.0中就得到了正确的值呢?

TC下的执行:

VC下的执行:

A:这就是发生溢出了。如果您的机器是16位的,也就是CPU中数据寄存器是16位的,那么int默认是16位的,它的取值范围为-32768~32767.如果超过这个范围的,都可能得到一个错误的结果。而,如果是32位的,这个程序的执行结果就不会错,因为int的范围在大约正负21亿。

Q:也就是计算机不能保证计算的加法得到的一定就是对的了?没有可以检测是否发生溢出的吗?

A:目前看来,计算机在计算发生溢出的时候并不提示,除了一个除数为0的情况;别的情况只能程序员自己写检测程序来判断是否发生溢出了。

Q:那么在执行这个程序的时候,为什么一定就出现个小黑框框,你的是个白框框,然后可以在里面输入数据?有别的形式的输入环境吗?

A:你如果用的是Windows,那么在执行这个程序的时候一定是出现这个了,因为这个叫命令提示符的程序就是这种程序默认执行的环境。

Q:能说的更具体吗?

A:就是在Windows下写的EXE程序,大体可以被分成两类:

一类是Console应用程序,也就是控制台应用程序,就像我们前面写的程序一样;它们默认就是控制台应用程序,它们的执行环境就是cmd.exe.

另一类就叫Application,是有窗体等GUI图形的,比如Windows自带的计算器calc..exe这样的程序。

Q:能给个C++的加法程序吗?

A:如下:

#include<iostream>

usingnamespacestd;

intmain()

{

inta=1;

intb=2;

intc;

c=a+b;

cout<<c;

return0;

}

Qcout<<后面直接跟上变量c就可以输出c的值了?

A:是的。它不像printf函数那样让人觉得有点麻烦。

【深入cout<<

这里的cout其实是个输出流对象,<<是一个运算符,在这里被重载了,这些在以后将会有介绍。

Q:我看cout的这个样子,如果要打印别的变量,也可以直接跟在后面了?

A:是的。比如,你还要打印c+1的值,那么你就:

cout<<c<<c+1;

QC++中的换行用什么?

A:除了可以用C中的'/n'之外,还可以在cout<<流对象输出中直接用endl函数。

如果把上面程序中cout<<c;这句话改为:

cout<<c<<endl<<c;

那么执行结果如下:

Q:那么给个有输入存在的程序吧。

A

#include<iostream>

usingnamespacestd;

intmain()

{

inta;

cin>>a;

cout<<a;

return0;

}

Qcin>>就是输入函数?

A:是的。在它后面直接跟上要输入的变量名就可以了。

Q:这比scanf函数要简洁多了,scanf还要个取地址符号呢。

A:嗯,是的。C++在输入输出方面的简化做的不错。

Q:那么也就可以再来写个输入两个数并求它们和的程序了。

A:对。

#include<iostream>

usingnamespacestd;

intmain()

{

inta,b,c;

cin>>a;

cin>>b;

c=a+b;

cout<<c;

return0;

}

Qcin>>a;

cin>>b;

可以和到一起写吧?

A:是的。可以用cin>>a>>b;这样更方便。

你可能感兴趣的:(C语言问答进阶--2、C语言简介及基本的输入输出函数)