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

news2024/11/16 15:53:17

C语言简介

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

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

【C语言简要历史】

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

【什么是系统编程】

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

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

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

【什么是操作系统】

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

【什么是Shell】

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

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

那么,什么又是内核呢?

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

【什么是编译器】

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

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

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

【Unix系统是什么】

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

【什么是Linux操作系统】

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

【什么是汇编语言】

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

【什么是机器语言】

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

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

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

【C++简要介绍】

C++是美国的贝尔实验室的Bjarne Stroustrup博士在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编译器上再进行编译(当然这里排除一些Windows和Linux下极不兼容的地方),这样基本就可以执行了。然而也正是这个原因,它在这个方面没有Java有优势。

【C#简要介绍】

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

Hello World!程序

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

A:

#include<stdio.h>

int main()

{

  printf("Hello World!");

  return 0;

}

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

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

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

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

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

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

来表示。

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

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

A:你想呢?

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

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

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

Q: 哦。那int是什么?

A: 它代表整型。

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

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

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

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

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

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

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

Q: int是integer的缩写吧?

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

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

A: 是的。

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

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

Q:让我想想……

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

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

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

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

.

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

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

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

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

dir 和 dir /s的区别是什么?

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

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

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

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

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

#include<stdio.h>

int main()

  printf("Hello World!");

  return 0;

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

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

Q:那么最上面的#include<stdio.h>是做什么的?

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

Q:它是个函数。

A:它从何而来?

Q:我不知道。

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

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

A:如下代码:

#include <iostream>

using namespace std;

int main()

{

    cout<<"Hello "<<endl;

    return 0;

}

执行结果是:

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

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

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

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

Q:cout是什么意思?

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

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

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

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

Q:那么using namespace std; 是什么意思?

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

Q:<<endl 代表什么?

A:这个代表输出换行;

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

#include <iostream>

int main()

{

    std::cout<<"Hello "<<std::endl;

    return 0;

}

执行结果是:

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

using namespace std;

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

而若是没有,那就错了:

#include <iostream>

int main()

{

    cout<<"Hello "<<endl;

    return 0;

}

编译错误:

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

【深入编译错误】

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

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

 如下为示例:

 

【C++的一个简洁之处】

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

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

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

【/n的作用】

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

在C++中用这个就可以了: 

cout<<a<<endl<<b<<endl<<c<<endl;

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

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

char c='a';

printf("%d",c)

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

而用cout就得:

char c='a';

cout<<(int)c<<endl;

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

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

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

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

代码如下:

#include<stdio.h>

int main()

{

  printf("Hello World!");

  return 0;

}

代码的文件名是: hello.c

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

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

TITLE hello.c

.386P

include listing.inc

if @Version gt 510

.model FLAT

else

_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'

_TEXT ENDS

_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'

_DATA ENDS

CONST SEGMENT DWORD USE32 PUBLIC 'CONST'

CONST ENDS

_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'

_BSS ENDS

_TLS SEGMENT DWORD USE32 PUBLIC '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 'Hello World!', 00H

_DATA ENDS

_TEXT SEGMENT

_main PROC NEAR

; File hello.c

; Line 3

push ebp

mov ebp, esp

; Line 4

push OFFSET FLAT:$SG336

call _printf

add esp, 4

; Line 5

xor eax, eax

; Line 6

pop ebp

ret 0

_main ENDP

_TEXT ENDS

END

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

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

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

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

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

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

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

简单的加法程序

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

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

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

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

x=1

y=2

print x+y

是吗?

Q:是的!

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

#include<stdio.h>

int main()

{

  int a=1;

  int b=2;

  int c;

  c=a+b;

  printf("%d",c);

  return 0;

}

执行为:

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

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

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

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

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

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

int a=1;  int b=2;  int c;

A:是的!

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

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

Q:让我想想……

   int a=1 b=2 c;   这样行吗?

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

如下:

int a=1,b=2,c;

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

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

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

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

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

Q:我看

 int c;

 c=a+b;

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

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

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

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

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

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

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

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

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

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

#include<stdio.h>

int main()

{

  int a=1;

  int b=2;

  int c;

  c=a+b;

  printf("%d",c);

  return 0;

}

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

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

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

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

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

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

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

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

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

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

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

Q:printf(c); 这样就可以呀?

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

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

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

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

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

#include<stdio.h>

int main()

{

  int a=1;

  int b=2;

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

  return 0;

}

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

A:

#include <stdio.h>

int main()

{

   int a;

   scanf("%d",&a);

   printf("%d",a);

   return 0; 

}

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

A:当然可以。如下:

#include<stdio.h>

int main()

{

  int a,b,c;

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

  c=a+b;

  printf("%d",c);

  return 0;

}

输入: 1 2 (回车)

结果: 3

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

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

Q:那a和b前面为什么要加 & 号呢?

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

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

   scanf("%d",&a);

   scanf("%d",&b);  

这样也可以吧?

A:当然。

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

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

Q:哦。

A:你可以输入

1 2 (回车)

或 

1 (回车)

2 (回车)

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

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

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

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

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

Q:有个问题:为什么用这个程序在TC中输入了10000和30000,会得到一个错误的值;而在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>

using namespace std;

int main()

{

  int a=1;

  int b=2;

  int c;

  c=a+b;

  cout<<c;

  return 0;

}

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

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

【深入cout<<】

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

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

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

cout<<c<<c+1;

Q:C++中的换行用什么?

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

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

cout<<c<<endl<<c;

那么执行结果如下:

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

A:

#include <iostream>

using namespace std;

int main()

{

    

   int a;

   cin>>a;

   cout<<a;

   return 0;

}

Q:cin>> 就是输入函数?

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

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

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

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

A:对。

#include <iostream>

using namespace std;

int main()

{

    

   int a,b,c;

   cin>>a;

   cin>>b;

   c=a+b;

   cout<<c;

   return 0;

}

Q:cin>>a;

   cin>>b; 

可以和到一起写吧?

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2043057.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis7.0.15 主从复制、哨兵模式搭建

主从复制&#xff1a;master以写为主&#xff0c;slave以读为主&#xff0c;当master数据变化的时候&#xff0c;自动将新的数据异步同步到其他的slave数据库 1. Redis复制介绍&#xff1a; https://redis.io/docs/latest/operate/oss_and_stack/management/replication/ 读写…

Unity游戏开发001

Unity游戏开发 系列文章的目录&#xff1a; 第一章&#xff1a;Hello&#xff0c;Unity&#xff01; “好读书&#xff0c;不求甚解&#xff1b;每有会意&#xff0c;便欣然忘食。” 本文目录&#xff1a; Unity游戏开发 Unity游戏开发前言今天我们来体验一下unity开发创建第一…

基于MMIO的Virtio流程分析——QEMU平台

目录 一、相关概念 1、Virtio 2、QEMU 3、KVM 4、MMIO 5、小结 二、QEMU中Virtio的实现方法 1、virtio_blk 2、virtio_net 三、Virtio Driver和Virtio Device 的初始化流程 1、Virtio Driver Init 2、Virtio Mmio Driver Init 3、Virtio Device Init (1) get dev…

培训第二十九天(python脚本使数据库读写分离,mysql主从开机自动同步,python操作数据库,MyCat插件的学习)

上午 1、python脚本实现数据库主从分离 # 引入模块 python链接mysql工具&#xff0c;驱动包&#xff0c;连接器import pymysql# python 类 类名 rwsplit,名字可以和文件名不一致# 三个函数&#xff0c;函数的标识 def 函数名 (self,参数列表):# __init__ 初始化函数&#xff…

详解最大比合并算法(Maximum Ratio Combining)

目录 一. 空间分集&#xff08;space diversity&#xff09; 二. 系统模型 三. 尝试性译码 3.1 选择性合并算法&#xff08;selection combining&#xff09; 3.2 简单相加 四. 最大比合并算法 4.1 合并信号 4.2 设计权重值w 五. 波束赋形 5.1 小结 5.2 与波束赋形的…

牛客小白月赛98

牛客小白月赛98 A 骰子魔术 链接&#xff1a;https://ac.nowcoder.com/acm/contest/85598/A 来源&#xff1a;牛客网 题目描述 jackle 正在给他的朋友表演一个关于骰子的魔术&#xff1a; jackle 会拿出一枚骰子&#xff0c;骰子的表面分别写上了从 1∽500 的数字&#xff0c…

Hadoop环境安装及HDFS初步使用

一、Hadoop原理 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。Hadoop实现了一个分布式文件系统( Distributed File System),其中一个组件是HDFS(Hadoop Distr…

【深度学习】【语音TTS】GPT-SoVITS v2 实战,训练一个人的音色,Docker镜像

文章目录 原理Dockerdocker push训练教程: https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/xyyqrfwiu3e2bgyk 原理 Docker 不用docker不行,不好分配显卡, 做个docker镜像: docker pull pytorch/pytorch:2.1.2

【数据结构与算法 | 图篇】Dijkstra算法(单源最短路径算法)

1. 前言 由图&#xff1a; 如果我们想要求得节点1到节点5&#xff08;也可以是其他节点&#xff09;的最短路径&#xff0c;我们可以使用Dijkstra算法。 2. 步骤与思路 1. 将所有顶点标记为未访问(顶点类的visited属性设置为false)。创建一个未访问顶点的集合。 2. 为每个顶…

Web开发:使用Abp.AutoMapper进行实体映射的demo

控制台程序为例&#xff0c;展示该demo 一、安装Nuget包 二、文件结构 三、AutoMapperProfile.cs&#xff08;映射规则&#xff09; using AutoMapper;namespace ConsoleApp1 {public class AutoMapperProfile : Profile{public AutoMapperProfile(){CreateMap<Student, T…

面向新人的 Java 面试问题(1-50)

1. Java 是否独立于平台&#xff1f;如果是&#xff0c;那么如何独立&#xff1f; 是的&#xff0c;Java 是一种独立于平台的语言。与许多编程语言不同&#xff0c;javac 将程序编译为字节码或 .class 文件。此文件独立于正在运行的软件或硬件&#xff0c;但需要在操作系统中预…

--- java 包装类 泛型 ---

包装类 因为在java中基本类型&#xff08;int char...&#xff09;不是继承值Object类&#xff0c;为了满足泛型的需要&#xff0c;于是给每种基本类型都设计了对应的包装类 基本类型包装类intInteger char CharacterbyteByteShortShortfloatFloatdoubleDoublelongLongboolea…

mars3D引用模型库以及图标配置

文章目录 一、icon总结 一、icon 引入基本场景后 还差几个样式引入 mars3D图标用的 https://fontawesome.dashgame.com/ 引入对应的 <link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"&…

WebGIS开发中一些常见的概念

0. 坐标系投影 地理坐标系和投影坐标系是两种常用的坐标系统&#xff0c;它们各自有着独特的特性和应用场景。 0.1 地理坐标系 地理坐标系(Geographic Coordinate System&#xff0c; 简称 GCS)是以地球椭球体面为参考面&#xff0c;以法线为依据&#xff0c;用经纬度表示地…

双指针| Java | (hot100) 力扣283, 11, 15, 42做题总结

leetcode 11 盛最多水的容器 双层for循环暴力 超出时间限制 class Solution {public int maxArea(int[] height) {int h0;int v0;for(int i0; i<height.length; i) {for(int ji1; j<height.length; j) {h Math.min(height[i],height[j]);v Math.max(v, h*(j-i));}}…

【原创公式】【完全二叉树】叶结点的计算【数据结构】

完全二叉树叶结点的计算 【铺垫】1叶结点即度为0的结点 2完全二叉树中度为1的结点只可能有0或1个 3完全二叉树的设叶结点仅可能出现在最后2层 设有完全二叉树T 【区分】第k层有a个叶结点≠第k层有a个结点 &#xff08;1&#xff09;第k层有a个叶结点&#xff1a;T的形态不唯一&…

Mac电脑虚拟机安装win11教程

Mac分享吧 文章目录 效果一、准备工作二、安装步骤方法1&#xff1a;使用虚拟机自带的win11系统&#xff0c;选中系统软件--继续--安装&#xff0c;即可完成win11安装方法2&#xff1a;通过下载好的镜像安装Windows11系统。选择镜像文件位置&#xff0c;安装&#xff0c;配置1…

MySQL进阶-MySQL管理

系统数据库 常用工具 mysql mysqladmin mysqlbinlog mysqlshow mysqldump mysqlimport/source

数据预处理和探索性数据分析(上)

目录 数据预处理 数据清洗 处理缺失值&#xff1a; 异常值检测与处理&#xff1a; 类别特征编码&#xff1a; 特征工程 创建新特征&#xff1a; 特征缩放&#xff1a; 探索性数据分析 (EDA) 使用Matplotlib进行可视化 绘制直方图&#xff1a; 绘制箱线图&#xff1…

this内存原理,成员变量和局部变量的区别

this的作用&#xff1a;区分局部变量和成员变量 this的本质&#xff1a;所在方法调用者的地址值 内存分布&#xff0c;this会保存地址 this.name name 等号的右边触发就近原则接收形参 把接收到的形参赋值给成员变量的name 成员变量&#xff0c;类方法外的变量&#xff0c…