C语言问答进阶--3、基本数据类型

前面介绍了基本的整型变量和基本的输入输出函数,现在将进一步介绍其它基本变量类型和更多的基本函数。

常量

Q:可以直接输出常量吗?

A:当然可以。

#include "iostream.h"

int main()

{

cout<<10<<endl;

return 0;

 }

Q:包含的头文件#include "iostream.h" 我看和以前不一样了,它们有什么区别?

A:你观察地很仔细。在头文件的文件夹里,和iostream文件在一个文件夹里,iostream.h文件是以前使用的头文件,现在一般都用iostream文件和using namespace std在一起,这更标准点,这些以后也会继续介绍。

Q:C中不是可以有十六进制吗?那么也就是可以直接输出十六进制数了?

A:是的。

#include "iostream.h"

int main()

{

cout<<0x10<<endl;

return 0;

 }

Q:它为什么不是打印 0x10 呢?是按默认按十进制打印的吗?

A:是的。毕竟10进制当然是我们最熟悉的了,最常使用的了。

Q:那么如果要打印十六进制的形式,怎么办?

A:

C中可以用:

printf("%x",0x10);

C++中可以用:

cout<<hex<<0x10<<endl; 

这里的hex就是一种格式说明。

【hex】

 hex是十六进制hexadecimal的简写,表示在后面输出的数用16进制表示。

Q:关于const修饰符,有什么例子可以说吗?

A:首先介绍下这个修饰符,它是C++中出现的修饰符,C语言中并没有;如果一个变量被它修饰,那么就代表它的值不能再被改变。举例如下:

#include "iostream.h"

int main()

{

    const int ten=10;

cout<<ten<<endl;

return 0;

}

Q:那么C语言中表示常量用什么?

A:一般用宏定义#define来声明。

【#define声明常量】

C语言中用#define语句来声明变量,其实说到底,这也并不算是声明了,因为这仅仅是一种替换,把前面的标识符用后面的内容来替换。

如下:

#define  ten  10

这里就表示程序代码中所有出现了形如ten标识符的地方全部用10来替换。

具体在预处理处深入研究。

Q:const就代表着这个变量为常量了?

A:是的。你可以尝试去修改它的值,看看会发生什么。

Q:好。

#include "iostream.h"

int main()

{

    const int ten=10;

    cout<<ten<<endl;

ten+=1;

return 0;

}

出现如下编译错误:

果然常量是不可以修改的!

A:是啊。const修饰的一个好处就是表明它是常量,二就是当程序员的代码有要修改它的值的时候编译器也会提示错误。

Q:那么这里的ten是常量,那它就不是变量了?

A:呵呵。其实,它还是个变量,只不过它的变化幅度始终为0,导致它的值看起来不变。

常量是特殊的变量,正如数学里所说的,直线是特殊的曲线。

Q:如果把const看做修饰符,那么它的位置是由什么决定的?是只要放在变量类型前就可以了吗?

A:怎么会想到这个问题?

Q:英语中常有各种形容词修饰名词时的顺序问题,所以就联想到这里了。

A:哦。想得好。其实,这个问题,就像您说的那样,放在变量类型的前面就可以了;但是呢,这个又没有硬性规定是这样,正如下面,把const和int的位置互换一下得到:

#include "iostream.h"

int main()

{

    int const ten=10;

    cout<<ten<<endl;

}

编译无错,执行如下:

这么看来,编译器还是不笨的,先看到了类型为int,接着发现有const修饰,表达的就是常整型;和先发现const修饰,再看到了类型为int没什么区别。

还有如下代码:

#include "iostream.h"

void Message(const int i)

{

i++;                       

cout<<i<<endl;

}

int main()

{

   Message(3); 

   return 0;

}

出现的编译错误信息:

Message函数的参数是一个const类型的,但是在函数体内却有像自增这样修改它的值得情况,编译器首先就不会放过,程序代码的健壮性就是这样提高的。

Q:不还有个修饰符是volatile吗?它是什么用?

A:volatile的英文意为可变地、不稳定地;被它修饰的变量会向编译器提醒:它是随时可能变的,在程序中每次需要读或写此变量的值时,都从此变量的内存地址处读或写。

Q:为什么是限定为从内存地址处读或写呢?每个变量不都保存在内存中吗?

A:其实这要说到编译器的优化功能了:编译器可能把一些变量放到寄存器中,因为CPU读取寄存器中的值比从内存中读取数据的速度快多了,但是呢,有些场合下有些变量很容易被别的程序或特别事件改变,而如果一个程序一直从寄存器中读取,那么肯定会造成读取出错,而volatile的作用就在这。

整型、字符型

Q:C语言中整型数据除了可以用十进制表示、十六进制表示,还可以用别的进制表示吗?

A:当然,还可以用八进制。下面将举例说明这三种进制格式的数。

#include "stdio.h"

int main()

{

   int i=12;

   printf("%d\n",i); 

   printf("%o\n",i); 

   printf("%x\n",i); 

   return 0;

}

%d格式大家很熟悉了,它表示用十进制形式;

%o表示是八进制格式;

%x表示是十六进制格式;

Q:那么如何直接把八进制的数据赋值给整型变量呢?

A:如下:

#include <iostream>

using namespace std;

int main()

{

    int a=013;

    cout<<a<<endl;

    return 0;

}

013就是八进制的形式,毕竟要与最熟悉的十进制相区别,八进制的整数以数字0开始。

当然,如果只写一个数字0,那就优先被当作十进制的int类型来处理。

Q:那十六进制呢?

A:十六进制是以0x开头的,例如:

int i=0x12;

那么i的值就是18.

Q:那么C语言中的变量没有显式的二进制格式吗?

A:为什么你认为要有二进制格式呢?

Q:因为计算机采用的是二进制的,用二进制格式表示的数不是能更好地反应计算机处理的数据吗?

A:其实这个我也不太明白,汇编里可以有二进制格式,包括八进制、十进制、十六进制都有。也许C语言毕竟要让程序员与计算机里错综的0和1远离点,毕竟看0和1没有看十进制快,没有看十六进制更简洁点。我想是这个原因,况且十六进制可以较方便地转化成二进制形式。

Q:那么从2、8、16进制,那么为什么没有4进制?

A:这个问题,我不太明白。不过网上有关于日本一大学和松下电器公司研究的关于4进制的集成电路,据他们称,这种集成电路的芯片面积和功耗都减少了一半。好像还没有正式报道。

Q:除了int类型,还有哪些和int相近的数据类型?

A:还有如short、char、long等类型的数据,它们都是int的子集。

Q:那分别介绍下它们吧。

A:short类型是short int的缩写,这种类型的数据一般占据2个字节;取值范围为

-32768~32767.

char类型为字符类型,用它可以描述所有的大小写字母以及其它常用字符,一般为1个字节;

long类型是long int的缩写,这种类型占用的字节数一般为4个字节。

short、int、long这三种类型所占用的空间大小有如下关系:

short≤int≤long.

意思就是short类型占用空间是不大于int类型占用的空间,int类型占用的空间不大于long类型占用的空间。

在16位机器上,short类型占据16位,int类型占据16位,long一般占用32位;

而在32位机器上,short类型占据16位,int类型占据32位,long一般占用32位.

【如何得到一种数据类型占用内存空间的大小】

使用运算符sizeof,它的语法是:sizeof(类型名或变量名).

比如:sizeof(int)或sizeof(a). (这里假设a是前面已经声明的变量名)

【sizeof是函数名吗】

有人可能会认为sizeof是一个函数名,其实并非如此。

它仅仅是个运算符,可是有人会问了,运算符为什么后面用括号呢?

用括号的不是函数的“专利”吗?

C++语言中含有这样两个运算符,一个是new,一个是delete.

Q:也就是说,short sh=1;和short int sh=1;这两种声明是等同的?

long ln=1;和long int ln=1;这两种声明也是等同的?

A:是的。

Q:现在32位机器很流行,那么既然int和long占用相同空间,那么它们的取值范围也一样,那么为什么还有这两种,有一种不就够了吗?

A:应该说,这还是考虑到兼容的问题。毕竟这个世界上还有很多不同的机器。

Q:char类型的取值范围是多少?

A:-128~127.

Q:举个字符类型变量的例子。

A:

#include <iostream>

using namespace std;

int main()

{

    char ch='a';

    cout<<ch<<endl;

    return 0;

}

Q:字符类型的必须要加上单引号括起来?

A:是的。

Q:可以不加吗?

A:你可以尝试不加会有什么结果;不过,不加了,别人可能把那个值看成是变量!

Q:

#include <iostream>

using namespace std;

int main()

{

    char ch=a;

    cout<<ch<<endl;

    return 0;

}

编译出错了:

A:这就对了,字符类型数据为什么要加上单引号,就是要与普通变量区别开。再比如,字符串类型,必须加上双引号。

Q:下面的程序为什么会编译出错?

#include <iostream>

using namespace std;

int main()

{

    char ch=a;

    cout<<ch<<endl;

    return 0;

}

编译会出现不识别的字符的错误。

A:那是因为你把英文字符的单引号写成了中文状态的单引号了!

‘ 和 ' 是不一样的,在C的源代码中,这些符号必须是英文状态的符号。

Q:英文字母的ASCII码是多少?

A:在ASCII码表中,大小写字母是分别连续排列的,大写字母A的ASCII为65,小写字母a的ASCII为97.

Q:你之前说过char类型是int类型的子集,那么怎么体现出来?

A:如下代码:

#include <iostream>

using namespace std;

int main()

{

    char ch='a';

    printf("%d",ch);

    return 0;

}

首先声明的是char类型变量ch,然后用整型格式打印出来,打印出来的正是它的ASCII码。

实际上,char类型在处理时就是先被转换成int型的。

Q:听说整型数据分为有符号类型和无符号类型?

A:是的。其实上面所说的short、int、long等类型都是有符号类型的数据;

它们分别是signed short int、signed int、signed long int的缩写。如果要声明一个无符号类型的数据,那么就得使用unsigned关键字了。

Q:那么无符号类型和有符号类型有什么区别吗?

A:正如它们的名字,一个无符号,即无正负之分;而另一个,有正负之分。

Q:举个例子吧。

A:

#include <iostream>

using namespace std;

int main()

{

    int k=-1;

    printf("%d\n%u\n",k,k);

    return 0;

}

【补码】

-1的补码为全1,0的补码为全0,在一定位数的二进制补码格式中,最小的数为首位为1,其余均为0的数据;最大的数为首位为0,其余均为1的数据。

下面显示了int类型为16位的二进制的表示形式。

10000……000               -32768

10000……001

10000……010

………………

………………

11111……101               -3

11111……110               -2

11111……111               -1

00000……000               0

00000……001               1

00000……010               2

………………

………………

01111……111             32767

Q:那么无符号数存在的必要性是什么?

A:就从unsigned  int和int的区别来看,如果要表示的数据不必是负数,那么用unsigned  int就比较好;况且,unsigned  int这种类型比int类型能表达的数据范围大了一倍。

Q:要打印char类型数据用什么格式?

A:%c格式。

Q:如下代码:

#include "iostream.h"

int main()

{

   int i=1;

   char i='a';     

   cout<<i<<endl; 

   return 0;

}

它会出现编译的错误。

A:是的。编译器编译的时候会出现变量定义重复的错误,因为这个i在后面的任何位置都将具有二义性。在这里,我们来具体研究下标识符这个概念:

标识符,就是来标识一个我们要处理的数据。它当然不是随便取几个字符就可以的:毕竟现在把一个标识符就用数字1代替,显然会出现很大的混乱:

#include <iostream>

using namespace std;

int main()

{

    int 1=1;

    cout<<1<<endl;

    return 0;

}

第一个1代表我们的标识符,显然这引起了很大的混乱;编译也会出错。

因为人们一般用字母或字母的组合来当作标识,所以C语言中的标识符有如下规定:

标识符的首字符必须是英文字母(包括大小写)或下划线,其它部分必须由英文字母、下划线或数字这三种字符组成。

Q:也就是a、a1、_a、_2这些都是可以使用的标识符了?

A:是的。

Q:那么英文字母是有大小写之分的?这里A和a这两个标识符是一样的吗?

A:你自己用个程序去验证。

Q:好的。

#include <iostream>

using namespace std;

int main()

{

    int A=1;

    int a=2;

    cout<<A<<endl;

    cout<<a<<endl;

    return 0;

}

这么看来,它是区分大小写的,有一些语言中不区分大小写,还有在DOS下的命令也不区分,那么区分大小写究竟有什么好处呢?

A:应该说,区分还是不区分大小写对于程序语言来说并不是太重要;Basic语言就不区分大小写。而对于DOS下命令提示符来说,不区分大小写将更便于用户的输入。但是,区分大小写毕竟会使得代码更规范,从C到C++,再到Java、C#,它们均对标识符区分大小写。

【深入研究整型数据】

#include <stdio.h>

int main()

{

    printf("%d\n",4);

    printf("%d\n",4.6);   

return 0;

}

第一个printf将输出4,那么第二个呢?

为什么是这么一个怪数字呢?

那么编译器是如何理解把4.6这个浮点数用整数类型打印出来?

是直接取整吗?

当然不是。这个要涉及到在内存中存储这个浮点数了,它是4个字节(好像是8个字节);

但是它又被分为不同的区域,一个表示符号,一个表示阶数,一个表示小数;

或者说,浮点数是用这种方式来表示的:

当然如果硬把这个当int型变量看,没办法,只可能是转换错了。

【深入%d格式】

#include <stdio.h>

int main()

{

    int i=5;

    printf("%    d\n",i);

    return 0;

}

与以前的程序不同之处是什么呢?

%    d不同了,它中间有好多空格!

得出的结果是5之前有一个空格!为什么?

似乎只要这里的的%和d之间有1个以上的空格,那么打印出来的数5之前就会有且仅有一个空格,不知道为什么。

【%%】

#include <iostream>

using namespace std;

int main()

{

    int a=2,b=3;

    printf("%%d",a);

    return 0;

}

"%"也算是特殊字符,如果要把它打印出来,得再它前面再加个"%";

当然,前面两个%在一起配对了,后面那个符号d就和它前面的%没关系了。

【输出未赋值的变量】

#include "iostream.h"

int main()

{

    char c;

cout<<c<<endl;

return 0;

}

这会得到什么结果呢? 似乎很难确定;

声明了一个字符型的变量,然后没有给它赋值,最后要把它的值打印出来。

结果如下:

这个“ ?”是什么东西?

再看下面的:

#include "iostream.h"

int main()

{

   int i,j;

   cout<<i<<endl;

   cout<<j<<endl; 

   return 0;

}

结果呢:

这到底有没有什么规律呢?

转义字符

Q:举个转义字符的例子吧。

A:

#include "iostream.h"

int main()

{

    cout<<"Hello \041"<<endl;  

    return 0;

}

"Hello /041"后面的/041被认为是转义字符,且以0开头被认为是八进制表示,查表得到是感叹号"!"。那么为什么没把/0看成是字符串的结束而直接忽略后面的内容呢?

这里就有一个最长原则在起作用了。

转义字符一样是字符,只是对字符格式char的另外一种描述。

【转义字符/0及其组合】

#include "iostream.h"

int main()

{

    cout<<"Hello \0x"<<endl;

    return 0;

}

应该说,这个要从编译器角度说起:C编译器一般都是对代码采用最长匹配方式的,即能最长匹配编译器知道的各种模板的被采纳。而,上一个例子,因为转义字符允许以/ooo的模式(指的是:  / 符号右边可以跟上3个八进制的数字),所以会一直匹配下去;而本例,/0后面是一个字母x,无法匹配/ooo的模式,当然也不匹配/xhh的模式,所以被认为在/0的时候就会结束,而/0又是字符串的结束标志,所以后面的x也就不会被打印出来了。

A:如下是转义字符和对应字符的对应关系:

#include <iostream>

using namespace std;

int main()

{

    char c='\x41';

    cout<<c<<endl;

    char c1='\41';

    cout<<c1<<endl;

    char c2=33;

    cout<<c2<<endl;

    return 0;

}

转义字符还可以用'/xhh'和'/ooo'两种方式:

即可以用十六进制表示,那么前面得有个x标识;当然,如果不想用十六进制,也可以用八进制,那么不必要加0开头,像上面的'/41' ;然而,问题就来了,为什么不可以用十进制形式呢?笔者也不太明白,或许十六进制、八进制和二进制的转换关系较显眼点。

布尔类型

A:现在我们来研究布尔类型。

Q:那举个关于bool类型的例子吧。

A:

下面就是一个关于bool类型的例子:

#include "iostream.h"

int main()

{

   bool b=4;            

   cout<<b<<endl;

   return 0;

}

您以为会打印什么?

打印true,还是打印4?

Q:这个值非0,应该打印的是true吧。

A:你先看看结果。

Q:为什么会打印1呢?

A:

再来看看对bool类型的定义您就知道了:非0的值就表示bool类型的“真”,0就代表“假”。

当然值得一提的是: 这里非0的值当然包括了负值,也就是说您把上面的b的值改为-34(只要是个负值都可以),那么得到的依然是1;

如下:

#include "iostream.h"

int main()

{

   bool b=-34;            

   cout<<b<<endl;

   return 0;

}

结果是:

当然如下的代码就得到了0:

#include "iostream.h"

int main()

{

   bool b=0;            

   cout<<b<<endl;

   return 0;

}

Q:这是什么道理?

A:也许大家对bool(布尔)这个类型的了解还不是很深,因为实际上在最早这种类型并不是用真正的true和false来表示的;而就是用1或是0来表示的;在头文件里就是直接这么定义了:

#define true 1

#define false 0

#define bool int

看到这里,也许你更清楚计算机的二进制系统的妙用了吧。

C语言中并没有布尔类型,但是它是二进制化的“布尔类型”,只用0和1来表示是真是假;

C++中可以直接用true或false来表示。

这里还要再提的是,这种思想是很值得大家去思索的:正如二进制的产生一样;计算机使用的不是0就是1,当然真和假也就可以用0和1来代替了;

到后面还会学到NULL类型,void类型等等,NULL在头文件里就被定义成0,如下:

#define NULL 0

当然这样的想法同样是充分利用了0和1的机制方便了计算机处理。

【逻辑运算符--非】

#include "iostream.h"

int main()

{

   cout<<!10<<endl;

   cout<<!0<<endl; 

   return 0;

}

甚至你显式声明一个布尔类型为true或false,而你在打印的时候依然打印1或0.

#include "iostream.h"

int main()

{

  bool b=true,c=false;

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

  return 0;

}

实数类型

A:现在来介绍下实数类型。

Q:实数类型用什么来表示?

A:float或double.

Q:float和double有什么区别?

A:float代表单精度实数类型,而double代表双精度类型。

Q:那么单精度和双精度有什么区别?

A:正如它们的名字,double比float的精度更高,这体现在:double类型可以精确到小数点后16~17位,而float类型可以精确到小数点后面6~7位,当然这与编译器有关。

Q:float和double这两个和实数类型有什么关系?

A:float是"漂浮"的意思,在这里是"浮点"的意思,这是和"定点"对应的。定点是用来表示整数的,浮点来表示实数,这在计算机组成原理里有更深入的说明。

double只是表示在float的基础上又加了一倍,其实就是它占用的空间比float高了一倍。

float一般占用32位,而double占用64位。

【浮点和定点】

Q:那举个例子吧。

A:

#include "iostream.h"

int main()

{

  float f=.5f;

  cout<<f<<endl;

  f=2*f;

  cout<<f<<endl;  

  return 0;

}

里面的.5f的意思其实就是0.5f,后面的f的意思也就是为了表明是float类型的;

还有的表达是5.f,当然也就是5.0f的意思了;

Q:听说有一种是long double类型,它是什么?

A:

如下代码:

#include "iostream.h"

int main()

{

  long double ld=1e308;

  cout<<ld<<endl;  

  return 0;

}

执行结果是:

不过看出来了,得到的结果确实很聪明,你输入的是什么,就输出了什么;

当您输入1e309的时候,那么结果呢?

居然编译错误了: 说1e309太大了,这么看来long double没什么特殊的,和double应该是同样的取值范围。

Q:实数类型数据还可以用别的格式表示吗?

A:当然。还可以用常用的科学计数法表示。

如下例子:

#include "iostream.h"

int main()

{

    float f=2.4e3;

    cout<<f<<endl;

    return 0;

}

Q:e代表什么?

A:这里的e其实代表底数10,它后面的数为它的指数,这里的指数必须得用整数。

Q:那么e后面的数可以是任意的整数了吗?

A:不是的。

#include "iostream.h"

int main()

{

    float f=2.4e1111;

    cout<<f<<endl;

    return 0;

}

这会出现编译错误。

如下代码的执行结果很有特点:

#include "iostream.h"

int main()

{

    float f=2.4e012;

    cout<<f<<endl;

    return 0;

}

如下执行为:

#include "iostream.h"

int main()

{

    float f=2.4e12;

    cout<<f<<endl;

    return 0;

}

简单地浮点类型:

#include "iostream.h"

int main()

{

  float f=.5;

  cout<<f<<endl;  

  return 0;

}

#include "iostream.h"

int main()

{

  float f=5.;

  cout<<f<<endl; 

  return 0; 

}

如下的浮点类型为什么打印的如此简洁呢?

#include "iostream.h"

int main()

{

  float f=5.00000;

  cout<<f<<endl; 

  return 0;  

}

#include "iostream.h"

int main()

{

    float f=2.4 e3;

    cout<<f<<endl;

    return 0;

}

出现编译错误。

想想和下面的程序有什么不同。

#include "iostream.h"

int main()

{

    float f=2.4e3;

    cout<<f<<endl;

    return 0;

}

为什么下面的程序结果是不用科学计数法表示的而后面的一个就用了?

#include "iostream.h"

int main()

{

  float f=3.5e5;         

  cout<<f<<endl; 

  return 0; 

}

#include "iostream.h"

int main()

{

  float f=3.5e6;         

  cout<<f<<endl; 

  return 0; 

}

想打印精确度更高的double类型数据:

#include <iostream>

using namespace std;

int main()

{

    double d=1.56534535345456465474354645434532556546463456;

    cout<<d<<endl;

    printf("%.20f\n",d);

    printf("%.16f\n",d);

    return 0;

}

第一个格式%.20f是指此浮点数保留小数点后20位;. 的前面没有数字代表没有最大长度限制;

第二个格式类似了。

为什么第一个格式从小数点后16位之后就都是0了,原来的数可不是这样的呀!

当然,这个问题又回到前面了,计算机能保存的数据既有大小的限制又有精度的限制;而这,都与寄存器位数的有限有关。

声明的是double类型的数,一般最多能保留小数点后16~17位;

如果是float类型的数,一般最多能保留小数点后6~7位;

#include <iostream>

using namespace std;

int main()

{

    float f;

    f=5/9*2.5;

    cout<<f<<endl;

    return 0;

}

应该是多少?

这个告诉大家要警惕除法,尤其只有整数的除法,它的结果是只取整数的。

#include <iostream>

#include<iomanip>

using namespace std;

int main()

{

 long double d=10.0/3;

cout<<setw(25)<<setprecision(20)<<d<<endl;  

    return 0;

}

setw(25)是设置输出的总位数为25位,setprecision(20)是设置输出后的小数点的精度为20位。

当然,结果并没有让我们满意:它只保留了16位小数,而且最后一位还是不准确的。只是也告诉我们,计算机计算出来的浮点数,不要对它报太大的希望,它只能算近似值(当然如果得到的数可以在这个精度范围内就是准确值)。

下面是个关于double类型数据能精确到多少位小数的程序:

#include <iostream>

using namespace std;

int main()

{

    

if(2.012345678901234

   ==2.012345678901236)  

    cout<<"Equal\n";

    else

    cout<<"Not Equal\n";

    

if(2.0123456789012345

   ==2.0123456789012346)  

    cout<<"Equal\n";

    else

    cout<<"Not Equal\n";

    return 0;

}

由此,大家可以看出这个编译器能精确到double类型数据后面多少位小数了。

这里,可以得到double类型的数据精确到小数点后面15位。

【深入研究实数类型数据】

#include <stdio.h>

int main()

{

float f=17.625;

printf("%x/n",f);

    printf("%d/n",4);

    printf("%d/n",3.5);   

return 0;

}

此程序对浮点数f的%x格式无效;

#include <stdio.h>

int main()

{

float f=17.625;

int *pf=(int*)&f;

printf("%p/n",*pf);

printf("%x/n",f);

    printf("%d/n",4);

    printf("%d/n",3.5);   

return 0;

}

此程序对浮点数f的内存存储进行了打印,正与IEEE 754标准吻合。

字符串

A:如下将结束字符串类型。

也许有很多人对C语言中没有字符串类型感到很伤感,毕竟只用char数组来表示字符串还是麻烦了。

C++中加入了字符串类string.注意:它只是类名,不是像int一样的新内置类型,string不算关键字。

#include <iostream>

#include<string>

using namespace std;

int main()

{

   string s="Hello"

   cout<<s<<endl;

   return 0;

}

如下是简单的字符串连接:

#include <iostream>

#include<string>

using namespace std;

int main()

{

   string s1="Hello ",s2=" World "

   cout<<s1+s2<<endl;

   return 0;

}

两个字符串相加的意思就是连接的意思。

当然下面的是同样的道理了:

#include <iostream>

#include<string>

using namespace std;

int main()

{

   string s1="Hello ",s2=" World "

   cout<<s1+"2"<<endl;                

   return 0;

}

以前说过关于转义字符的例子,现在把转义字符和字符串放在一起:

#include <iostream>

using namespace std;

int main()

{

    cout<<"chen\b"<<endl;

    return 0;

}

/b  是个转义字符,它代表向前面退一格;但是,这和键盘上的退格键绝对不一样,它只是把光标向前移动了一位,没有删除前面的这位。

当然,如果再由此继续打印字符,那么将覆盖后面的字符。

如下:

#include <iostream>

using namespace std;

int main()

{

    cout<<"chen\bxi"<<endl;

    return 0;

}

#include <iostream>

#include<string>

using namespace std;

int main()

{

    string s="chenxi ";

    strcat(s,"Hello");    

    cout<<s<<endl;

    return 0;    

}

出现了编译的错误,这里说明了不能混用C++中的string类型和C中的字符指针。

而如下程序是可以正常编译和执行的:

#include <iostream>

#include<string>

using namespace std;

int main()

{

    char c[20]="chenxi ";

    cout<<c<<endl;

    strcat(c,"Hello");   

    cout<<c<<endl;

    return 0;    

}

nclude "iostream.h"

int main()

{

    char c="a";

    cout<<c<<endl;

    return 0;

}

编译出现错误:不能从char [2]转化成char.

当然编译就错了。

【深入string类型】

#include <iostream>

#include<string>

using namespace std;

int main()

{

    string string="chen";       

    cout<<string<<endl; 

    return 0;

}

笔者不是很理解这个程序:C++中对字符串类型的规定为什么会是这样,string好像不是个关键字,用它都可以当作字符串变量来用?

难道string是字符串类,而由它声明的只是它的对象,所以string不算是关键字?

【深入分析/n字符】

#include "iostream.h"

int main()

{

   cout<<"Hello"<<"\n";

   cout<<"CX"<<"\n"

   return 0;

}

可以看到/n 是放在双引号中当作字符串的,当然这是成立的,字符就是特殊的字符串。

#include "iostream.h"

int main()

{

   cout<<"Hello"<<'\n';

   cout<<"CX"<<'\n'

   return 0;

}

这里 /n 被放在单引号里,也就是被当作了字符,这显然是可以的。

关于标识符的最大可识别长度

笔者是个很喜欢挑战极限的人,曾经看到一本书上说:C语言的标识符的字符数不能超过1024,于是我写了个有1025个字符的变量,来打印它:

大家不要大惊小怪,下面的确实有点长~

#include "iostream.h"

int main()

{

   int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1;

   cout<<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<<endl; 

return 0;

}

那个很长的就是一个变量,只是把它赋值为1,然后打印出来!

这可是1025字节的标识符,居然也可以通过编译!

于是笔者很不满意,继续加长了这个变量的长度:

而且考虑到写两遍变量可能出现意外的错误,就用#define来规范了一下:

大约是加长到了2000个字符:

结果果然让人不可思议!

在Linking……的时候出现了问题,居然不能继续下去了(当然有时也可以继续下去并且编译通过);而且编译器给出了个提示:

identifier was truncated to '255' characters in the debug information

意思是在调试模式,标识符只取前255个字符;

哦!原来编译器是这样的!于是笔者赶紧再取一个变量,为256个字符的,然后再用cout语句输出一个只有255个字符的变量(当然是取刚刚那256字符的前255个字符),看看编译器到底会不会认为是同一个变量:如下:

#include "iostream.h"  

#define LONGIDENTIFIER aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab

void main()

{

   int LONGIDENTIFIER=1;

   cout<<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<<endl;

}

然而很可惜的是:出现了编译的错误了!说第二个变量不识别!

而当我把那个变量增加到大概2000个字符的时候,出现了如下的错误:

compiler limit : token overflowed internal buffer

呵呵~有道理!

不同格式数据的转换

三个程序是在不同情况下打印不同格式:

#include "iostream.h"

int main()

{

  int c=65;

  cout<<c<<endl;  

  return 0;

}

#include "stdio.h"

int main()

{

  char c='A';

  printf("%d\n",c);  

  return 0;

}

#include "iostream.h"

int main()

{

  char c='A';

  cout<<c<<endl;  

  return 0;

}


微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。

我是程序员小迷(致力于C、C++、Java、Kotlin、Android、iOS、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

欢迎关注。助您在编程路上越走越好!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值