文档库 最新最全的文档下载
当前位置:文档库 › 数据类型转换

数据类型转换

数据类型转换
数据类型转换

数据类型转换

各类整数之间的转换

C语言中的数分8位、16位和32位三种。属于8 位数的有:带符号

字符char,无符号字符unsigned char 。属于16位数的有:带符号整

数int,无符号整数unsigned int(或简写为unsigned),近指针。属

于32位数的有:带符号长整数long,无符号长整数 unsigned long,

远指针。

IBM PC是16位机,基本运算是16位的运算,所以,当8位数和16

位数进行比较或其它运算时,都是首先把8 位数转换成16位数。为了

便于按2的补码法则进行运算,有符号8位数在转换为16位时是在左边

添加8个符号位,无符号8位数则是在左边添加8个0。当由16位转换成

8位时,无论什么情况一律只是简单地裁取低8位,抛掉高8 位。没有

char或usigned char常数。字符常数,像"C",是转换为int以后存储

的。当字符转换为其它 16 位数(如近指针)时,是首先把字符转换为

int,然后再进行转换。

16位数与32位数之间的转换也遵守同样的规则。

注意,Turbo C中的输入/输出函数对其参数中的int和unsigned

int不加区分。例如,在printf函数中如果格式说明是%d 则对这两种

类型的参数一律按2 的补码(即按有符号数)进行解释,然后以十进制

形式输出。如果格式说明是%u、%o、%x、%X,则对这两种类型的参数

一律按二进制 (即按无符号数) 进行解释,然后以相应形式输出。在

scanf函数中,仅当输入的字符串中含有负号时,才按2的补码对输入

数进行解释。

还应注意,对于常数,如果不加L,则Turbo C一般按int型处理。

例如,语句printf("%081x",-1L),则会输出ffffffff。如果省略1,

则输出常数的低字,即ffff。如果省略L,则仍会去找1个双字,这个

双字的就是int常数-1,高字内容是不确定的,输出效果将是在4个乱

七八糟的字符之后再跟ffff。

在Turbo C的头文件value.h中,相应于3 个带符号数的最大值,

定义了3个符号常数: #define MAXSHORT 0X7FFF

#define MAXINT 0X7FFF

#define MAXLONG 0X7FFFFFFFL 在Turbo C Tools中,包括3对宏,分别把8位拆成高4位和低4位,

把16位拆成高8位和低8位,把32位拆成高16位和低16位。 uthinyb(char value) utlonyb(char value)

uthibyte(int value) utlobyte(int value)

uthiword(long value) utloword(long valueu)

在Turbo C Tools中,也包括相反的3 个宏,它们把两个4位组成

一个8位,把两个8位组成一个16位,把两个16位组成一个32位。 utnybbyt(HiNyb,LoNyb) utwdlong(HiWord,Loword)

utbyword(HiByte,LoByte)实数与整数之间的转换

Turbo C中提供了两种实数:float和 double。float 由32 位组

成,由高到低依次是:1个尾数符号位,8个偏码表示的指数位(偏值=

127),23个尾数位。double由64位组成,由高到低依次是:1 个尾数

符号位,11个偏码表示的指数位(偏值=1023), 52个尾数位。通过下

列公式,可以由尾数和指数计算出所代表的实数值: X=±1.尾数*2(指数-偏值) 下列几种情况下,此公式不成立:指数=000...0且尾数 =00...0,则X=X=±0

指数=000...0且尾数!=00...0,则X=±0.尾数*2(1-偏值)

指数=11....1且尾数 =00...0,则X=±∞

指数=11....1且尾数!=00...0,则X是一个无效数

在Turbo C的头文件value.h中,相应于实数所能达到的最大最小

值,定义了如下几个符号常数: #define MAXFLOAT 3.37E+38

#define MINFLOAT 8.43E-37

#define MAXDOUBLE 1.797693E+308

#define MINDOUBLE 2.225074E-308 实常数是按double格式存放的,如果想按float 格式存放,则必

须加后缀F,如:1.23E+4F。

当把实数强制转换为整数时,采取的是“向零靠拢的算法",如: float值: 65432.6 -65432.6 转换为long; 65432 -65432

转换为unsigned: 65432 104

如果不希望“向零靠拢”,而希望“四舍五入”,则必须由程序员自

己处理。一种办法是先加上(符号位/2),然后再进行类型转换。应该

注意的是:如果被转换的实数值超过了目标类型的表达范围,则会产

生错误。例如上面的float值-65432,6转换为unsigned int值时,由

于超过了目标范围,所产生的104就是错误的。在65432。6转换为

unsigned int的65432以后,可以用printf的%u格式输出,如果用 %d

格式输出,则会得到错误的结果。指针说明

指针是包含另一变量的地址变量。它的一般说明形式,如

int *fd,其fd是一个指向整型变量的指针。比较复杂的指针说明,

如*(*pfpi)(),可按如下几个原则来理解:以标识符为中心,一对方

括号一般表示数组,一对圆括号一般表示函数或强调某一优先顺序,

方括号对和圆括号对为同一优先级,方括号和圆括号比*号优先级高。

以下几例解释了这些原则的应用。

int *fip(),因圆括号优先级高,帮fip 先与圆括号结合,说明

fip是一个函数,这个函数返回一个指向整数的指针。 int (*pfi)(),因两对圆括号为同一优先级,故从左到右,pfi

是一个指针,这个指针指向一个函数,这个函数返回一个整数。 int *par[],因方括号比*号优先级高,故par是一个数组,这个

数组的每一个元素是指向整数的指针。

int (*ptr)[],因方括号与圆括号为同一优先级,故ptr 是一个

指针,这个指针指向一个数,这个数的每一个元素是一个整数。 int *(*pfpi)(),pfpi是一指针,这个指针指向一个函数,这个

函数返回一个提向整数的指针。指针与地址

指针在使用之前必须初始化,给指针赋地址的方法一般有如下几

种:

第一种很容易理解,通过取地址操作符取变量(包括结构变量)的

地址,如:

char_c="a", *ptr_char;

ptr_char=&c; 第二种是数组,因为不带方括号的数组名等效于数组中第一个元

素的地址,即数组名也可看作是一个指针,所以有两种办法。如: char myname[31], *ptr; ptr=myname;

或 ptr=&myname[0];

第三种是动态分配的一块内存,这时往往带有类型强制转换,但

应注意当内存不够时,可能返回一个空(NULL)指针。如: struect complex {double real, image; };

struct complex *ptr;

ptr={ struct complex *)malloc(sizeof(struct complex)); 第四种是函数,与数组名一样,函数名也可以当作一个地址,于

是可以把函数名赋给一个指向函数的指针。函数名后面跟一个带圆括

号的参数表意味着计算函数的值,但仅有一个函数名则意味着指向函

数的指针。如:

double (*fx)();

double quad_poly(double);

fx=quad_poly;指针运算

常见的指针运算有:指针加或减一个数,指针增量,指针减量,

指针比较等等。假设P是某数组第1个元素的指针,则P+N 就是这个数

组中第n 个元素的地址,每个元素占多少存储单元则由指针所指数组

的类型来确定。但有两点要注意:

第一,上面这段话是C语言对指针运算的普遍规律,但具体到种C

编译则有所不同,尤其是在80X86类型的机器上。Turbo C和

Microsoft C 6.0以前的版本把指针分为near、far、huge,

Microsoft C 6.0又增加了based。在这几种指针中,只有huge严格遵

守上面的指针运算规则,详见下一节。

第二,当指针应用于数组尤其是多维数组时,有时容易弄错,下

表说明了数组法与指针法的区别。

│ 1维│ 2维│ 3维

━━━━━━━━━━┿━━━━━┿━━━━━━━┿━━━━━━━━━━

数组说明│int x[] │int y[][] │int z[][][]

指针说明│int *xptr │int *yptr[] │int *zptr[][]

数组法表示某元素地址│&x[i] │&y[i][j] │&z[i][j][k]

指针法表示某元素地址│ptr+i │*(yptr+i)+j │*(*(zptr+i)+j)+k

数组法存取某元素│x[i] │y[i][j] │z[i][j][k]

指针法存取某元素│*(ptr+i) │*(*(yptr+i)+j)│*(*(*(zptr+i)+j)+k)指针分类

在C 语言教科书上,指针就是指针,不存在分类的问题。我们经

常说“指向整数的指针”,“指向结构的指针”,“指向函数的指针”

等等,只是说指针指向不同的目标,而不是说指针本身有什么区别。

但是,在以80X86为基础的微机上实现C 语言时,由于80X86的物理地

址空间不是线性连续的而是分段的,为了提高效率,就必须对指针加

以分类。各类指针的运算法则也不一样。Turbo C 2.0及以前的版本,

Microsoft C 6.0以前的版本,指针都是分类三类,近(near),远

(far),巨(huge)。Microsoft C 6.0版本中,出现了一种新的指外类

型,这就是基(based)指针。基指针综合实现了近和远指针的优点,

它像近指针那么小那么快,又像远指针那样可以寻址缺省数据段以外

的目标。基指针这个名字就反映了这类指针上的实现方法:它是以程

序员指定的某一地址为段基址。如果在C 源程序中使用了基指针,编

译程序一般先把所指定的段基址装在ES寄存器内。在缺省的数据段内,

程序员一般不会使用基指针。但若同时要使用多个数据段,基指则有

其明显的优点。

一、近(near)指针

近指针是用于不超过64K 字节的单个数据段或码段。对于数据指

针,在微、小和中编译模式下产生的数据指针是近指针,因为此时只

有一个不超过64K 字节的数据段。对于码(即函数指针)指针,在微、

小和紧凑编译模式下产生的码指针是近指针,因为此时只一个不超过

64K字节的码段。本章将只讨论数据指针。

近指针是16位指针,它只含有地址的偏移量部分。为了形成32位

的完整地址,编译程序一般是反近指针与程序的数据段的段地址组合

起来。因为在大部分情况下程序的数据段的段地址是装在DS寄存器内,

因此一般没有必要装载这个寄存器。此外,当用汇编语言和C 语言混

合编程时,汇编语言总是假设DS含有数据目标的地址。

虽然近指针占用空间最小,执行速度最快,但它有一个严格的限

制,即只能64K字节以内的数据,且只能存取程序的数据段内的数据。

如果在小模式下编译一个程序,而这个程序企图增量一个近指针使之

超过第65536个字节,则这个近的指针就会复位到0。下面就是这样一

个例子:

char _near *p=(char _near *)0xffff;

p++;

由于近指针的这个严重限制,所有在比较大或比较复杂的程序中,

都无法使用。二、远(far)指针

远指针不是让编译程序把程序数据段地址作为指针的段地址部分,

而是把指针的段地址与指针的偏移量直接存放在指针内。因此,远指

针是由4 个字节构成。它可以指向内存中的任一目标,可以用于任一

编译模式,尽管仅在紧凑、大和巨模式下远指针才是缺省的数据指针。

因为远指针的段地址在指针内,熟悉80X86 汇编语言的人都知道,这

意味着每次使用远指针时都需要重新装载段寄存器,这显然会降低速

度。

应该注意:尽管远指针可以寻址内存中的任一单元,但它所寻址

的目标也不能超过64K 字节。这是因为,远指针在增量或减量之类的

算术运算时,也只是偏移量部分参与运算,而段地址保持不变。因此,

当远指针增量或减量到超过64K字节段边界时就出错。例如: char far *fp=(char far *)0xb800ffff;

fp++; 在指针加1以后,fp将指向B800:0000,而不是所希望的

C800:0000。

此外,在进行指针比较时,far指针还会引起另外一些问题。far

指针是由偏移量和段地址这样一对16位数来表示的,对于某一实际内

存地址,far指针不是唯一的,例如,far指针1234:0005、1230:0045、

1200:0345、1000:2345、0900:9345等都是代表实际地址12345,这样

会引起许多麻烦。

第一,为了便于与“空”(NULL)指针(0000: 0000)进行比较,当

关系操作符“==”和“!=”用于对far 指针进行比较时,比较的是全

部32位。否则,如果只比较16位偏移量,那么任何偏移量为0 的指针

都将是“空”(NULL)指针,这显然不符合一般使用要求。但在进行这

32位比较时,不是按20位实际地址来比较,而是把段地址和偏移量当

作一个32位无符号长整数来比较。对于上面这个例子,假设这些指针

分别叫作a、b、c、d、e,尽管这5个far 指针指向的都是同一内存单

元,但下列表达式运算的结果却都为“假”,从而得出错误的结论:

if(a==b)....

if(b==c)....

if(c==d)....

if(d==e)....

if(a==c)....

if(a==d)....

第二,当用“>”、“>=”,“<”和“<=”关系操作符对指针进

行比较操作时,比较的仅仅是偏移量部分,即按无符号的16位整数进

行比较。因此,对于上面这个例子,下列表达式运算的结果将都为

“真”,也得出错误的结论:

if(e>d)....

if(d>c)....

if(c>b)....

if(b>a)....

if(e>a)....三、巨(huge)指针

只有巨指针才是一般C 语言教科书上所说的指针,它像远指针也

占4个字节。与远指针的显著差别是:当增量或减量超过64K字节段边

界时,巨指针会自动修正段基址的值。因此,巨指针不但可以寻址内

存中的任一区域,而且所寻址的数据目标可以超过64K字节。例如:

char huge *hp=(char huge *)0xb800ffff;

hp++; 在指针加1后,hp将指向C800:0000。但是,巨指针总是比较慢的,

因为编译必须生成一小段程序对指针进行32位而不是16位的加减运算。

此外,由于huge指针是规则化指针,每一个实际内存地址只一个

huge指针,所有在指针比较时不会产生错误。四、基(based)指针

前面已经说过,巨指针综合了近指针和远指针的优点。像近指针

一样,基指针只占两个字节,这两个字节是地址的偏移量。像远指针

一样,基指针可以寻址内存中的任一区域。近指针的段地址隐含地取

自程序的数据段,远指针的段地址取自指针本身,基指针的段地址取

法以及基指针的许多技术和应用问题,请见第11章。

五、各类指针之间的转换

far指针可以强制转换为near 指针,做法很简单,抛掉段地址只

保留偏移量。near指针也可以转换为far指针,Turbo C的做法是从相

应的段寄存器中取得段地址。

far指针有时也需要转换为huge 指针,以便对指针进行比较或做

其它操作。一种方法是通过下面这样一个规则化函数: void normalize(void far **p) {

*p=(void far *)(((long)*p^0xffff000f)+

(((long)*p^0x0000fff0)<<12));

}

另一种办法就是通常的强制类型转换,但强制类型转换不能自动

使转换后的结果规则化。解决的办法是使转换后的huge指针再做一次

加法。例如,设转换后的huge指针是Hp,做一次Hp+=0就使Hp 规则化

了。有返回值的函数

这类函数是最常见的函数,如返回一个字符,返回一个整数,返

回一个指针等,在函数的说明中就说明了要返回什么类型的数据。因

返回整数是最常见的,所以在这种情况下函数说明前的int可以省略。

这里要强调一点的是:函数除可以返回一些C语言标准类型的数外,

还可以返回用户自定义的数据类型,如结构、联合、枚举等。例如,

下面这个对两个字符串相加的程序就是返回一个结构。 struct string {

char str[256];

int strlen;

};

struct string concat(struct string str1,struct string str2)

{

struct string result;

int i,j;

result.str[0]='\0';

result.strlen=0;

if(str1.strlen>0){

for(i=0;i result.str[i]=str1.str[i];

result.strlen=str1.strlen;

}

if(str2.strlen>0) {

j=stre1.strlen;

for(i=0;i result.str[i+j]=str2.str[i];

result.strlen+=str1.strlen;

}

return result;

}无返回值的函数

无返回值的函数与PASCAL等其它结构化语言中的过程很相似,它

们既不返回结果,又不修改参数,而只是执行某一特定的任务。例如,

下面的清屏函数就是这样一个函数。 void clrscr(void)

{

printf("\xlb[2J");

} 既然不返回值,则调用的办法也不一样,不是把函数名放在某一

表达式内调用,而是把函数名连同其调用参数单独人微言轻一个语句。修改参数的函数由于C 语言是按传值方式把参数传递给函数的,因此,被调用的

函数不能直接改变调用函数中的变量。但有时确实需要修改调用函数

的参数,尤其在返回值多于一个的函数中必须再借用参数来返回结果。

在这些情况下,必须利用指针来从函数的参数,典型的例子是交换两

个变量的值的函数。如下所示: void swap int(int *i,int *j)

{

int temp;

temp=*i;

*i=*j;

*j=temp;

}递归函数

C 语言是支持递归调用的。显然,当一个问题蕴含递归关系且结

构比较复杂时,采用递归调用技巧将使程序变得简洁,并增加程序的

可读性。但递归调用技巧的使用是在牺牲存储空间的基础上得到的,

因为它必须在某处维护一个要处理的值的栈。同时,递归也不能提高

执行速度,只是其代码比较紧凑易读。对于像树和链表这样的递归定

义的数据结构,递归函数尤为适用。下面是用递归计算阶乘的例子。 double factorial(int n)

{

if(n>1) return factorial(n-1)*(double)n;

else return 1.0L;

}参数个数不定的函数

C语言中的某些函数,如vfprintf和vprintf,允许在一些固定参

数之后再带一些不定数目的可变参数。不但如此,C 语言还允许用户

自定义的函数也这样做。为了便于用户编程,Turbo C中提供了以

“va”开头的4个定义va_list数据类型,va_stat,va_arg和va_end

3个宏(函数)。这些定义都在头文件stdarg.h中。借助于这些宏可以

一步一步地通过整修参数表,尽管被调用函数事先不知道有多少个参

数,也不知道这些参数的类型。

为了编写具有不定数目的可变参数函数,应遵守如下几点:

第1,在C源中包含stdarg.h文件。

第2,如果函数的返回值不是int型,则在调用函数中应做如下形

式的函数说明: <类型><函数名>(<固定参数表>,....); 这个调用形式表明,参数表中至少必须有一个参数是固定的。

第3,函数应按如下形式定义: <类型><函数名>(<固定参数表>,....); 第4,定义一个表指针,其类型应是va_list,以表明它指向可变

参数表。如下所示: va_list <可变参数表指针> 第5,调用va_start,初始化表指针:va_start(<可变参数表指针>,<最后一个固定参数的名字>) 这样初始化后,表指针就指向了调用函数传来的可变参数中的第1 个

参数。

第6,调用va_arg,取可变参数: <变量>=va_arg(<可变参数表指针>,<参数的数据类型>) 第1次调用va_arg时,它返回可变参数表中的和第1个参数。随后每一

次调用,它返回表中的下一个参数。每次调用之后自动修正表指针的

值,使它指向随后的一个参数。为了正确地停止读可变参数表,应该

在调用函数可变参数表的最后放一个表结束符(例如-1 或0),在被调

用函数中再去检查这个表结束符。While 循环很适合做这件事情,如

下面的例子所示。

第7,调用va_end,返回到调用函数; va_end(<可变参数表指针>) 它帮助被调用函数正常返

回到调用函数。应在va_arg读完所有参数之

后,才调用va_end返回,否则可能会引起意想不到的结果。

下面这个例子利用一个具有可变参数表的函数,从一个数字表中

挑选值最大的那个数。 #include

#include

#define EOL -1

main()

{

int big;

void vmax(int *,char *,...);

vmax(&big,"The largest of 55,67,41 and 28 is",55,67,41,28,EOL); printf("%d\n",big);

}

void vmax(int *large,char *message,...)

{

int num;

va_list num_ptr;

va_start(num_ptr,message);

printf("%s",message);

*large=-1;

while((num=va_arg(num_ptr,int))!=EOL)

if(num>*(large)) *(large)=num;

va_end(num_ptr);

}

函数指针及其应用

函数名后面跟一对圆括号(兴许括号内还有参数),将导致去计算

这个函数。仅仅一个函数名则意味着是一个指针,是指向这个函数的

指针。函数指针有两个特殊用途,不太熟练的程序员可能很少使用函

数指针,但在某些场合下若借助于函数指针,则会使程序显得非常精

练。

第1 种用途是把函数名赋给一个指针,然后用这个指针去间接引

用函数。请看下面这个例子: #include

main()

{

double x;

const double delta=1.0;

const double first=0.0;

const double last=10.0;

double (*fx)();

double quad_poly(double);

fx=quad_poly;

x=first;

while(x<=last){

printf("f(%1f)=%1f\n",x,fx(x));

x+=delta;

}

}

double quad_poly(double x)

{

double a=1.0,b=-3.0,c=5.0;

return ((x*a)*x+b)*x+c;

}

在这个例子里,语句double(*fx)() 说明fx是一个函数指针,该

函数返回一个double型数。然后把函数名quad_poly 赋给这个指针。通过fx(x)引用这个函数,取得函数的返回值。

有时候,程序中要用到多个函数,这些函数有相同的参数要求和

相同的返回值类型。但这些函数不是同时都要用到,而是根据不同的情况每次仅调用其中的一个。比较笨拙的办法就是用switch语句去实现,虽然也还清楚,但程序显得冗长。用函数指针则显得精练多了,如下面的例子所示: #include

#include

#include

#define MAX 3

main()

{

double x;

const double delta=1.0;

const double first=0.0;

const double last=1.0;

double (*fx[MAX])();

int i;

char ch;

double quad_poly(double);

fx[0]=quad_poly;

fx[1]=sqrt;

fx[2]=log;

for(i=0;i x=first;

while(x<=last){

printf("f(%1f)=%1f\n",x,fx[i](x));

x+=delta;

}

printf("press any key to continue");

ch=getche();

clrscr();

}

}

double quad_poly(double x)

{

double a=1.0,b=-3.0,c=5.0;

return ((x*a)*x+b)*x+c;

}

在这个例子里,有三个数学函数 quad_poly, sqrt和log,它们

都只要一个dboule型参数,都返回一个double型数。程序中通过语句double (*fx[MAX])()说明fx是函数指针数组,每一个函数都返回

double型数。然后用三个函数的名字初始化这个函数指针数组,通过

fx[i](x)在每次循环中各引用一个不同的函数,取得函数的返回值。

第2 种用途是通过函数指针,把一个函数作为参数传递给另一个

函数,请看下面这个例子: #include

main()

{

double x;

const double delta=0.01;

const double first=0.0;

const double last=10.0;

double (*fx)();

double quad_poly(double);

double find_largest(double,double,double,double (*fx)());

fx=quad_poly;

printf("The largest value in the range %1f->%1f",first,last); printf("is %1f\n",find_largest(first,last,delta,fx));

}

double quad_poly(double x)

{

double a=1.0,b=-3.0,c=5.0;

return ((x*a)*x+b)*x+c;

}

double find_largest(double a,double b,double step,double (*fx)()) {

double x=a,big=(*fx)(a);

while(x<=b){

if(big<(*fx)())

big=(*fx)(x);

x+=step;

}

return big;

}

在这个例子里,函数quad_poly计算(a*x3+b*x+c)的值,参数x和

返回值教师double型数。函数find_largest根据某一计算法则求出在

某一范围内(某一步长)的最大值。不但范围和步长是由调用参数指定,

计算法则也是由调用参数指定,所有的参数返回值都是double型数。

主函数main调用find_largest求最大值,通过函数指针把函数

quad_poly人微言轻参数传给find_largest。段与偏移量

8086和80286的寄存器都是8位或16位的,而8086以及工作于实地

址方式下的80286/80386的地址空间却是20 位的。这样在寻找下一条

将执行的指令时以及当用寄存器间接寻址内存中某一数据时,16位的

指针寄存器和地址寄存器却不足以存下20位地址。为了解决这个问题,

便把20位地址分为两部分,分别称为段地址和偏移量。段地址可以是

任一16字节边界处,即段地址的末4位一定是0,不需要保存,只把高

16位存入段寄存器中。偏移量也是16位的,一方面便于寄存器间接寻

址,但另一方面也限制了每段不能超过64K 字节。考虑到程序和数据

的寻址一般都是连续的,故这种设计还是合理的。

在80X86微机中,总是有4个16位段寄存器:CS,DS,SS,ES。在

Turbo C编译产生的目标码中,一般只用到了其中的3个寄存器,CS用

来存放码的段地址,DS用来存放全局变量和静态变量所在段的段地址,

SS用来存放局部变量,参数(以及其它属于某一个函数的信息)所在段

的段地址。在Microsoft C 6.0中,ES用来存放基指针的段地址。如

果需要,在Turbo C 中,程序员可以通过伪变量_DS、_CS、_SS、_ES

取得这些段寄存器的值。

如果程序的码、数据和堆栈分别都不超过连续64K 字节,则在程

序的整修执行过程中,CS、DS和SS寄存器的值可以不变,仅仅通过对

单字偏移量的操作就可以寻址到所有的码和变量,这样速度比较快。

如果码或数据不能在边续64K 字节内放下,则必须用双字的段:偏移

量来寻址,但速度也就变慢。在所有程序中,堆栈的操作都较频繁,

所以都禁止使用双字的寻址方法,并限制堆栈不能超过64K 字节,即

不超过一段,尽管有时各个程序模块使用自己独立的堆栈。

有时,我们知道了某一个存储单元的段地址,也知道它的偏移量,

也知道它的偏移量,但这个段地址和偏移量并没有构成一个远指针。

Turbo C中提供了如下4 个宏,使得可以从这个内存单元中读(或往这

个内存单元中写)1个字节(或1个整数)。

char peekb(unsigned segment,unsigned offset)

int peek(unsigned segment,unsigned offset)

void pokeb(unsigned segment,unsigned offset,char value)

void poke(unsigned segment,unsigned offset,int value) 下面是从ROM的地址FFFF:000E 中读1个字节的例子,这个字节实

际上就是微机类型的标志字节。/* #include*/

#include

void main(){

printf("PC model=hex%x",( char ) peekb(0xffff,0x000e));

}

这4个宏以及下面将介绍的3个宏的定义都在头文件dos.h 中,但

在头文件general.h中包含有#include这样一行,所以在上面

这个例子中只写了#include。因为下面经常要用到

general.h,故单独把它列出来。

/* general.h */

#include

#include

#include

#include

#include

#include

#define boolean int

#define TRUE 1

#define FALSE 0

#define BLANK ''

#define CR 13

#define beep putchar('\a')

#define newline putchar('\n')

#define EMPTYSTR ""

#define FARNULL (void far *)NULL

#define INTA00 0x20

#define EOI 0x20

#define strempty(s) (*(s)==0)

boolean strequalsf(char *s,char *t,char **ps,char **pt);

boolean strequalsb(char *s,char *t,char **pm,char **pn);

#define strchrf strchr

char *strchrb(char *s,char *p,char c);

#define strpbrkf strpbrk

char *strstrf(char *s,char *t);

char *strstrb(char *s,char *t);

char *stralloc(char ch,unsigned N);

char *strsubst(char *s,char *a,char *b);

char *strltoa(long N,char *s,int radix);

char *strshrte(double x,char *s);

char *strultoe(unsigned long N);

char *strtomoney(double x,int code);

char *strtime(char *timestr,const struct tm *t,

boolean twentyfourhours,char separator);

char *strday(char *datestr,const struct tm *t,int format,

char separator);

#define leap(year) ((year)%4==0 && ((year)%100!=0 || (year)%400==0)) int dayofyear(int day,int month,int leapyear);

long gregorian(int day,int month,int year);

#define weekday(day,month,year) (gregorian(day,month,year)+5)%7 unsigned envseg(unsigned PSP);

char *progname(unsigned PSP);

void memrymap(void);

unsigned extmem(vid);

void ctryinfo(unsigned code,struct country *c);

void peep(void);

int retorisr(int N,char *id);

int rstorint(char *id);

有时,我们知道了段地址和偏移量,需要把它们合并成一个远指

针。Turbo C的宏MK_FP可以用来做这件事。 (void far *)MK_FP(unsgined segment,unsigned offset) Turbo C 的另外两个宏正好做相反的事情,它们从一个远指针中

分解出段地址和偏移量。 (unsigned)FP_SEG(void far *p)

(unsigned)FP_OFF(void far *p) Turbo C中还提供了其它一些手段,使得可以像汇编语言中一样,

知道了偏移量和段地址在哪一个段寄存器,就可以用如下这样的程序

来存取某一内存单元:

char peekb(unsigned segment,unsigned offset)

{

_ES=segment;

return *(unsigned char _es *)offset;

} 这个程序中用伪变量_ES把参数segment(段地址)存放到寄存器ES

中,用修饰符_es把参数offset(偏移量)强制转换为指向字符的指针,

但这个指针是相对于寄存器ES而不是缺省的DS,然后再去取1个字节。

由于这个程序(函数)的名字也是peekb,与Turbo C提供的宏同名,如

果要用用户定义的peekb,则在源程序中不应包含头文件dos.h。

C语言中的整型数据类型转换以及格式化输出问题

C语言中的整型数据类型转换以及格式化输出问题 先附上两张图片 i. Printf()函数的格式转换参数 ii. 各数据类型的长度和表示范围 首先我们来谈整型数据的转换问题,不同类型的整型数据所占的字节数不同,在转换时需要格外留心。 分为两种情况: 第一种情况为将所占字节大的类型数据转换为所占字节小的类型数据,这种情况下只需要截取合适位数的大字节的类型数据到小字节类型数据中即可,例如:unsigned short a=256;char b=a; 则b中的数据为00000000,截取了a的低八位。 第二种情况为将所占字节小的类型数据转换为所占字节大的类型数据,这种情况下需要涉及到扩展问题,所谓扩展分为两种情况,当需要扩展的小类型数据为有符号数时,即将过小数据的最高位即符号位复制到扩展的位上,比如一个char类型的数据char a=128,二进制表示10000000,则将其转换为整型数据b即int b=a,相应的b即为1….10000000,又或者一个char类型数据127,二进制表示01111111,则将其转换为整型数据b相应的b即为0…. 01111111;当需扩展的小类型数据为无符号数时,扩展位为全部为0。 另外对于同等大小的不同数据类型之间转换,则是相应的二进制码全额复制。 下面我们来讨论%d和%u的格式化输出问题 我们都知道%d表示输出十进制有符号整数,然而很少有人会注意到%d表示的格式类型其实相当于int类型,即有符号整型数据,占用4个字节,最高位表示符号位,输出的范围在-2147483648到2147483647间。 当我们在用%d输出数据是需要注意类型间的转换问题的。 不同类型的整型数据所占的字节数不同,在转换时需要格外留心,因为%d表示的4字节数

常用数据类型转换使用详解

VC常用数据类型使用转换详解 CString ,BSTR ,LPCTSTR之间关系和区别 CString是一个动态TCHAR数组,BSTR是一种专有格式的字符串(需要用系统提供的函数来操纵,LPCTSTR只是一个常量的TCHAR指针。 CString 是一个完全独立的类,动态的TCHAR数组,封装了 + 等操作符和字符串操作方法。typedef OLECHAR FAR* BSTR; typedef const char * LPCTSTR; vc++中各种字符串的表示法 首先char* 是指向ANSI字符数组的指针,其中每个字符占据8位(有效数据是除掉最高位的其他7位),这里保持了与传统的C,C++的兼容。 LP的含义是长指针(long pointer)。LPSTR是一个指向以‘/0’结尾的ANSI字符数组的指针,与char*可以互换使用,在win32中较多地使用LPSTR。 而LPCSTR中增加的‘C’的含义是“CONSTANT”(常量),表明这种数据类型的实例不能被使用它的API函数改变,除此之外,它与LPSTR是等同的。 1.LP表示长指针,在win16下有长指针(LP)和短指针(P)的区别,而在win32下是没有区别的,都是32位.所以这里的LP和P是等价的. 2.C表示const 3.T是什么东西呢,我们知道TCHAR在采用Unicode方式编译时是wchar_t,在普通时编译成char. 为了满足程序代码国际化的需要,业界推出了Unicode标准,它提供了一种简单和一致的表达字符串的方法,所有字符中的字节都是16位的值,其数量也可以满足差不多世界上所有书面语言字符的编码需求,开发程序时使用Unicode(类型为wchar_t)是一种被鼓励的做法。 LPWSTR与LPCWSTR由此产生,它们的含义类似于LPSTR与LPCSTR,只是字符数据是16位的wchar_t而不是char。 然后为了实现两种编码的通用,提出了TCHAR的定义: 如果定义_UNICODE,声明如下: typedef wchar_t TCHAR; 如果没有定义_UNICODE,则声明如下: typedef char TCHAR; LPTSTR和LPCTSTR中的含义就是每个字符是这样的TCHAR。 CString类中的字符就是被声明为TCHAR类型的,它提供了一个封装好的类供用户方便地使用。

Java中几种常用的数据类型之间转换方法

Java中几种常用的数据类型之间转换方法:1.短整型-->整型 如: short shortvar=0; int intvar=0; shortvar= (short) intvar 2.整型-->短整型 如: short shortvar=0; int intvar=0; intvar=shortvar; 3.整型->字符串型 如: int intvar=1; String stringvar; Stringvar=string.valueOf (intvar); 4.浮点型->字符串型 如: float floatvar=9.99f; String stringvar; Stringvar=String.valueOf (floatvar); 5.双精度型->字符串型 如: double doublevar=99999999.99; String stringvar; Stringvar=String.valueOf (doublevar); 6. 字符型->字符串型 如:char charvar=’a’; String stringvar;

Stringvar=String.valueOf (charvar); 7字符串型->整型、浮点型、长整型、双精度型如:String intstring=”10”; String floatstring=”10.1f”; String longstring=”99999999”; String doubleString=”99999999.9”; Int I=Integer.parseInt (intstring); Float f= Integer.parseInt (floatstring); Long lo=long. parseInt (longstring); Double d=double. parseInt (doublestring); 8字符串型->字节型、短整型 如:String s=”0”; Byte b=Integer.intValue(s); Short sh=Integer.intValue(s); 9字符串型->字符型 如: String s=”abc”; Char a=s.charAt(0); 10字符串型-->布尔型 String s=”true”; Boolean flag=Boolean.valueOf (“s”);

matlab数据类型及转换

Matlab中有15种基本数据类型,主要是整型、浮点、逻辑、字符、日期和时间、结构数组、单元格数组以及函数句柄等。 1、整型:(int8;uint8;int16;uint16;int32;uint32;int64;uint64)通过intmax(class)和intmin(class) 函数返回该类整型的最大值和最小值,例如intmax(‘int8’)=127; 2、浮点:(single;double) 浮点数:REALMAX('double')和REALMAX('single')分别返回双精度浮点和单精度浮点的最大值,REALMIN('double')和REALMIN ('single')分别返回双精度浮点和单精度浮点的最小值。 3、逻辑:(logical) Logical:下例是逻辑索引在矩阵操作中的应用,将5*5矩阵中大于0.5的元素设定为0: A = rand(5); A(A>0.5)=0; 4、字符:(char) Matlab中的输入字符需使用单引号。字符串存储为字符数组,每个元素占用一个ASCII字符。如日期字符:DateString=’9/16/2001’ 实际上是一个1行9列向量。构成矩阵或向量的行字符串长度必须相同。可以使用char函数构建字符数组,使用strcat函数连接字符。 例如,命令name = ['abc' ; 'abcd'] 将触发错误警告,因为两个字符串的长度不等,此时可以通过空字符凑齐如:name = ['abc ' ; 'abcd'],更简单的办法是使用char函数:char(‘abc’,’abcd’),Matlab自动填充空字符以使长度相等,因此字符串矩阵的列纬总是等于最长字符串的字符数. 例如size(char(‘abc’,’abcd’))返回结果[2,4],即字符串’abc’实际存在的是’abc ’,此时如需提取矩阵中的某一字符元素,需要使用deblank函数移除空格如name =char(‘abc’,’abcd’); deblank(name(1,:))。 此外,Matlab同时提供一种更灵活的单元格数组方法,使用函数cellstr可以将字符串数组转换为单元格数组: data= char(‘abc’,’abcd’) length(data(1,:)) ->? 4 cdata=cellstr(data) length(cdata{1}) ->?3 常用的字符操作函数 blanks(n) 返回n个空字符 deblank(s) 移除字符串尾部包含的空字符 (string) 将字符串作为命令执行 findstr(s1,s2) 搜索字符串 ischar(s) 判断是否字符串 isletter(s) 判断是否字母 lower(s) 转换小写 upper(s) 转换大写 strcmp(s1,s2) 比较字符串是否相同 strncmp(s1,s2,n) 比较字符串中的前n个字符是否相同 strrep(s1,s2,s3) 将s1中的字符s2替换为s3 5、日期和时间 Matlab提供三种日期格式:日期字符串如’1996-10-02’,日期序列数如729300(0000年1月1日为1)以及日期向量如1996 10 2 0 0 0,依次为年月日时分秒。 常用的日期操作函数

2.3 基本数据类型的转换

2.3基本数据类型的转换 本章目标 掌握基本数据类型间的自动转换 掌握任何基本数据类型的数据都会自动向String转换 掌握基本数据类型间的强制转换 Java的数据类型在定义时就已经确定了,因此不能随意转换成其他的数据类型,但Java允许用户有限度地做类型转换处理。数据类型的转换方式可分为“自动类型转换”及“强制类型转换”两种。 1 数据类型的自动转换 在计算机中完成一个计算时,要求参与计算的两个数值必须类型一致,如果不一致,计算机会自动将其中一个数值类型转换成另外一个数值的类型,然后完成计算。自动转换的原则如下: (1)转换前的数据类型与转换后的类型兼容。 (2)转换后的数据类型的表示范围比转换前的类型大。 例如,将short类型的变量a转换为int类型,由于short与int皆为整数类型,符合上述条件(1);而int的表示范围比short大,符合条件(2)。因此Java 会自动将原为short类型的变量a转换为int类型。 要注意的是,类型的转换只限该行语句,并不会影响原先所定义的变量的类型,而且通过自动类型的转换可以保证数据的精确度,它不会因为转换而损失数据内容。这种类型的转换方式也称为扩大转换。 范例:数据类型的转换 程序运行结果: x / y = 1.3519603 10 / 3.5 = 2.857142857142857 10 / 3 = 3 从程序的输出结果可以发现,int类型与float类型进行计算之后,输出的结

果会变成float类型,一个整型常量和一个浮点型常量进行计算之后,结果也会变为一个浮点数据,而如果两个int类型的常量进行计算,最终结果还是int类型,而其小数部分将会被忽略。 也就是说,假设有一个整数和双精度浮点数据做运算时,Java会所整数转换成双精度浮点数后再做运算,运算结果也会变成双精度浮点数。 提示:任何类型的数据都向String转型。 有一种表示字符串的数据类型String,从其定义上可以发现单词首字母大写了,所以此为一个类,属于引用数据类型,但是此类属于系统类,而且使用上有些注意事项,对于此种类型后面会有介绍,在此处所需要知道的只有以下两点: (1)String可以像普通变量那样直接通过赋值的方式进行声明。字符串是使用“””括起来的。两个字符串之间可以使用“+”进行连接。 (2)任何数据类型碰到String类型的变量或常量之后都向String类型转换。 范例:定义字符串变量 程序运行结果: str = lixinghua30 从运行结果来看,可以发现整型数据30自动转换成了字符的“30”,与字符串“lixinghua”进行了连接操作,变成了一个新的字符串“lixinghua30”。 范例:字符串常量操作的问题

java的基本数据类型有八种

java的基本数据类型有八种 各位读友大家好!你有你的木棉,我有我的文章,为了你的木棉,应读我的文章!若为比翼双飞鸟,定是人间有情人!若读此篇优秀文,必成天上比翼鸟! java的基本数据类型有八种四类八种基本数据类型1. 整型byte(1字节)short (2个字节)int(4个字节)long (8个字节)2.浮点型float(4个字节)double(8个字节)3.逻辑性boolean(八分之一个字节)4.字符型char(2个字节,一个字符能存储下一个中文汉字)基本数据类型与包装类对应关系和默认值short Short (short)0int Integer 0long Long 0Lchar Char '\u0000'(什么都没有)float Floa t0.0fdouble Double 0.0dboolean Boolean false 若某个类的某个成员是基本数据类型,即使没有初始化,java也会确保它获得一个默认值,如上所示。(这种初始化方法只是用于成员变量,不适用于局部变量)。jdk1.5支持自动拆装箱。可以将基本数据类型转换成它的包装类装箱Integer a = new Integer ();a = 100;拆箱int b = new Intger(100);一个字节等于8位,一个字节等于256个数,-128到127一个英文字母或一个阿拉伯数字就是一个字符,占用一个字节一个汉字两个字符,占用两个字节基本数据类型自动转换byte->short , char->int->longfloat->doubleint ->floatlong->double小可转大,大转小会失去精度。字符串与基本类型或其他类型间的转换⑴其它

c各种数据类型之间相互转化

⑴. char *转换到BSTR BSTR b = _com_util::ConvertStringToBSTR("数据"); SysFreeString(bstrValue); (2).BSTR转换到char* char *p=_com_util::ConvertBSTRToString(b); delete p; 12.typedef和typename要害字 这两个要害字在运用的时辰时例会令人迷惑,其实很简单,typedef是类型定义, 而typename是类型解释2009年04月20日 类型转换是将一种类型的值映射为另一种类型的值进行数据类型的转换 是在实际代码编写中经常遇到的问题,出格是字符串和其它类型的转换 1.将字符串转换为整儿 (1).转换函数 // 双精度函数 double atof( const char *string ); double _wtof( const wchar_t *string ); 自适应 TCHAR:_tstof 、_ttof VS2005:_atof_l 、_wtof_l 、_atodbl 、_atodbl_l // 整型函数 int atoi( const char *string ); _int64 _atoi64( const char *string ); int _wtoi( const wchar_t *string ); _int64 _ wtoi64( const char *string ); 自适应 TCHAR:_tstoi 、_ttoi 、_tstoi64 、_ttoi64 VS2005:_atoi_l 、_wtoi_l 、_atoi64_l 、_wtoi64_l //长整形函数 long atol( const char * string ); long _wtol(

数据类型转换

数据类型转换 一、隐式类型转换 1)简单数据类型 (1)算术运算 转换为最宽的数据类型 eg: [cpp] view plain copy #include using std::cout; using std::endl; int main(int argc, char* argv[]) { int ival = 3; double dval = 3.14159; cout << ival + dval << endl;//ival被提升为double类型 return 0; } 其运行结果: 6.14159 int main(int argc, char* argv[]) { 010D17D0 push ebp 010D17D1 mov ebp,esp 010D17D3 sub esp,0DCh 010D17D9 push ebx 010D17DA push esi 010D17DB push edi 010D17DC lea edi,[ebp-0DCh] 010D17E2 mov ecx,37h 010D17E7 mov eax,0CCCCCCCCh 010D17EC rep stos dword ptr es:[edi] int ival = 3; 010D17EE mov dword ptr [ival],3 double dval = 3.14159; 010D17F5 movsd xmm0,mmword ptr [__real@400921f9f01b866e (010D6B30h)]

010D17FD movsd mmword ptr [dval],xmm0 cout << ival + dval << endl;//ival被提升为double类型 010D1802 mov esi,esp 010D1804 push offset std::endl > (010D1064h) 010D1809 cvtsi2sd xmm0,dword ptr [ival] 010D180E addsd xmm0,mmword ptr [dval] 010D1813 mov edi,esp 010D1815 sub esp,8 010D1818 movsd mmword ptr [esp],xmm0 010D181D mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (010D90A8h)] 010D1823 call dword ptr [__imp_std::basic_ostream >::operator<< (010D90A0h)] 010D1829 cmp edi,esp 010D182B call __RTC_CheckEsp (010D111Dh) 010D1830 mov ecx,eax 010D1832 call dword ptr [__imp_std::basic_ostream >::operator<< (010D90A4h)] 010D1838 cmp esi,esp 010D183A call __RTC_CheckEsp (010D111Dh) return 0; 010D183F xor eax,eax } 010D1841 pop edi } 010D1842 pop esi 010D1843 pop ebx 010D1844 add esp,0DCh 010D184A cmp ebp,esp 010D184C call __RTC_CheckEsp (010D111Dh) 010D1851 mov esp,ebp 010D1853 pop ebp 010D1854 ret (2)赋值 转换为被赋值对象的类型,但不会改变赋值对象的数据类型。 eg: [cpp] view plain copy #include

C语言数据类型与表达式习题及答案

第一章数据类型,运算符与表达式 一.选择题 1.不合法的常量是A。 A)‘/2’B) “”C)‘’D)“483” 2. B 是C语言提供的合法的数据类型关键字。 A)Float B)signed C)integer D)Char 3.在以下各组标识符中,合法的标识符是(1)A,(2) C ,(3) D 。 (1)A)B01 B)table_1 C)0_t D)k% Int t*.1 W10 point (2)A)Fast_ B)void C)pbl D) Fast+Big abs fabs beep (3)A)xy_ B)longdouble C)*p D)CHAR 变量1 signed history Flaut 4. 不属于合法的C语言长整型常量的是 C 。 A)5876273 B)0L C)2E10 D)(long)5876273 7.下面选项中,均是合法浮点数的是 B 。 A)+1e+1 B)-0.60 C)123e D)-e3 5e-9.4 12e-4 1.2e-.4 .8e-4 03e2 -8e5 +2e-1 5.e-0 8.在C语言中,要求参加运算的数必须是整数的运算符是 C 。 A)/ B)* C)% D) = 9.在C语言中,字符型数据在内存中以 D 形式存放。 A)原码B)BCD码C)反码D)ASCII码10.下列语句中,符合语法的赋值语句是 C 。 A)a=7+b+c=a+7;B)a=7+b++=a+7; C)a=7+b,b++,a+7;D)a=7+b = c=a+7; 11. B 是非法的C语言转义字符。 A)‘\b’B)‘\0xf’C)‘\037’D)‘\’’12.对于语句:f=(3.0,4.0,5.0),(2.0,1.0,0.0);的判断中, B 是正确的。 A)语法错误B)f为5.0 C)f为0.0 D)f为2.0 13.与代数式x y u v ? ? 不等价的C语言表达式是A。 A)x*y/u*v B)x*y/u/v C)x*y/(u*v) D)x/(u*v)*y 14.在C语言中,数字029是一个 D 。 A)八进制数B)十六进制数C)十进制数D)非法数 16.对于char cx=?\039?;语句,正确的是A。 A)不合法B)cx的值是?\03? C)cx的值为四个字符D)cx的值为三个字符 17.若int k=7,x=12;则能使值为3的表达式是 D 。 A)x%=(k%=5) B)x%=(k-k%5) C)x%=k-k%5 D)(x%=k)-(k%=5) 18.为了计算s=10!(即10的阶乘),则s变量应定义为 C 。 A)int B)unsigned C)long D)以上三种类型均可

C++基本数据类型转换

atof(将字符串转换成浮点型数) 相关函数 atoi,atol,strtod,strtol,strtoul 表头文件 #include 定义函数 doubleatof(const char *nptr); 函数说明 atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。 返回值 返回转换后的浮点型数。 附加说明 atof()与使用strtod(nptr,(char**)NULL)结果相同。 范例 /* 将字符串a 与字符串b转换成数字后相加*/ #include main() { char *a=”-100.23”; char *b=”200e-2”; float c; c=atof(a)+atof(b); printf(“c=%.2f\n”,c); } 执行 c=-98.23 atoi(将字符串转换成整型数) 相关函数 atof,atol,atrtod,strtol,strtoul 表头文件 #include

定义函数 intatoi(const char *nptr); 函数说明 atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。 返回值 返回转换后的整型数。 附加说明 atoi()与使用strtol(nptr,(char**)NULL,10);结果相同。 范例 /* 将字符串a 与字符串b转换成数字后相加*/ #include mian() { char a*+=”-100”; ch ar b*+=”456”; int c; c=atoi(a)+atoi(b); printf(c=%d\n”,c); } 执行 c=356 atol(将字符串转换成长整型数) 相关函数 atof,atoi,strtod,strtol,strtoul 表头文件 #include 定义函数 longatol(const char *nptr); 函数说明 atol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。 返回值 返回转换后的长整型数。 附加说明 atol()与使用strtol(nptr,(char**)NULL,10);结果相同。 范例

数据类型转换

数据类型转换 各类整数之间的转换 C语言中的数分8位、16位和32位三种。属于8 位数的有:带符号 字符char,无符号字符unsigned char 。属于16位数的有:带符号整 数int,无符号整数unsigned int(或简写为unsigned),近指针。属 于32位数的有:带符号长整数long,无符号长整数 unsigned long, 远指针。 IBM PC是16位机,基本运算是16位的运算,所以,当8位数和16 位数进行比较或其它运算时,都是首先把8 位数转换成16位数。为了 便于按2的补码法则进行运算,有符号8位数在转换为16位时是在左边 添加8个符号位,无符号8位数则是在左边添加8个0。当由16位转换成 8位时,无论什么情况一律只是简单地裁取低8位,抛掉高8 位。没有 char或usigned char常数。字符常数,像"C",是转换为int以后存储 的。当字符转换为其它 16 位数(如近指针)时,是首先把字符转换为 int,然后再进行转换。 16位数与32位数之间的转换也遵守同样的规则。 注意,Turbo C中的输入/输出函数对其参数中的int和unsigned int不加区分。例如,在printf函数中如果格式说明是%d 则对这两种 类型的参数一律按2 的补码(即按有符号数)进行解释,然后以十进制 形式输出。如果格式说明是%u、%o、%x、%X,则对这两种类型的参数 一律按二进制 (即按无符号数) 进行解释,然后以相应形式输出。在 scanf函数中,仅当输入的字符串中含有负号时,才按2的补码对输入 数进行解释。 还应注意,对于常数,如果不加L,则Turbo C一般按int型处理。 例如,语句printf("%081x",-1L),则会输出ffffffff。如果省略1, 则输出常数的低字,即ffff。如果省略L,则仍会去找1个双字,这个 双字的就是int常数-1,高字内容是不确定的,输出效果将是在4个乱 七八糟的字符之后再跟ffff。 在Turbo C的头文件value.h中,相应于3 个带符号数的最大值, 定义了3个符号常数: #define MAXSHORT 0X7FFF #define MAXINT 0X7FFF #define MAXLONG 0X7FFFFFFFL 在Turbo C Tools中,包括3对宏,分别把8位拆成高4位和低4位, 把16位拆成高8位和低8位,把32位拆成高16位和低16位。 uthinyb(char value) utlonyb(char value) uthibyte(int value) utlobyte(int value) uthiword(long value) utloword(long valueu) 在Turbo C Tools中,也包括相反的3 个宏,它们把两个4位组成 一个8位,把两个8位组成一个16位,把两个16位组成一个32位。 utnybbyt(HiNyb,LoNyb) utwdlong(HiWord,Loword) utbyword(HiByte,LoByte)实数与整数之间的转换 Turbo C中提供了两种实数:float和 double。float 由32 位组 成,由高到低依次是:1个尾数符号位,8个偏码表示的指数位(偏值= 127),23个尾数位。double由64位组成,由高到低依次是:1 个尾数

C语言数据类型及转换

C语言的数据类型 C语言提供的数据结构,是以数据类型形式出现的。具体分类如下: 1.基本类型 分为整型、实型(又称浮点型)、字符型和枚举型四种。 2.构造类型 分为数组类型、结构类型和共用类型三种。 3.指针类型。在第9章中介绍。 4.空类型 C语言中的数据,有常量和变量之分,它们分别属于上述这些类型。 本章将介绍基本类型中的整型、实型和字符型三种数据。 2.3 常量和变量 2.3.1 常量 1.常量的概念 在程序运行过程中,其值不能被改变的量称为常量。 2.常量的分类 (1)整型常量 (2)实型常量 (3)字符常量。 (4)符号常量。 常量的类型,可通过书写形式来判别。 2.3.2 变量 1.变量的概念 在程序运行过程中,其值可以被改变的量称为变量。 2.变量的两个要素 (1)变量名。每个变量都必须有一个名字──变量名,变量命名遵循标识符命名规则。(2)变量值。在程序运行过程中,变量值存储在内存中。在程序中,通过变量名来引用变量的值。 3.标识符命名规则 (1)有效字符:只能由字母、数字和下划线组成,且以字母或下划线开头。 (2)有效长度:随系统而异,但至少前8个字符有效。如果超长,则超长部分被舍弃。 例如,由于student_name和student_number的前8个字符相同,有的系统认为这两个变量,是一回事而不加区别。 在TC V2.0中,变量名(标识符)的有效长度为1~32个字符,缺省值为32。 (3)C语言的关键字不能用作变量名。 注意:C语言对英文字母的大小敏感,即同一字母的大小写,被认为是两个不同的字符。 习惯上,变量名和函数名中的英文字母用小写,以增加可读性。 思考题:在C语言中,变量名total与变量名TOTAL、ToTaL、tOtAl等是同一个变量吗?标识符命名的良好习惯──见名知意: 所谓“见名知意”是指,通过变量名就知道变量值的含义。通常应选择能表示数据含义的英文单词(或缩写)作变量名,或汉语拼音字头作变量名。 例如,name/xm(姓名)、sex/xb(性别)、age/nl(年龄)、salary/gz(工资)。 4.变量的定义与初始化 在C语言中,要求对所有用到的变量,必须先定义、后使用;且称在定义变量的同时进行赋初值的操作为变量初始化。

Java语言基本数据类型、转换及其封装

Java语言基本数据类型、转换及其封装Java语言基本数据类型、转换及其封装 1. 逻辑类型 ·常量 true,false。 ·变量的定义 使用关键字boolean来定义逻辑变量: boolean x; boolean tom_12; 也可以一次定义几个: boolean x,tom,jiafei,漂亮 x,tom,jiafei,漂亮都是变量的名字。定义时也可以赋给初值: boolean x=true,tom=false,漂亮=true,jiafei 2.整数类型 ·常量123,6000(十进制),077(八进制),0x3ABC(十六进制)。 ·整型变量的定义分为4种: 1.int 型 使用关键字int来定义int型整形变量 int x int tom_12 也可以定义几个: int x,tom,jiafei,漂亮 x,tom,jiafei,漂亮都是名字。定义时也可以赋给初值: int x=12,tom=-1230,漂亮=9898,jiafei 对于int型变量,分配给4个字节byte,一个字节由8位(bit)组成,4个字节占32位(bit)。bit 有两状态,分别用来表示0,1。这样计算机就可以使用2进制数来存储信息了。内存是一种特殊的电子元件,如果把内存条放大到摩天大

楼那么大,那么它的基本单位——字节,就好比是大楼的房间,每个房间的结构都是完全相同的,一个字节由8个能显示两种状态的bit组成,就好比每个房间里有8个灯泡,每个灯泡有两种状态——亮灯灭灯。 对于 int x=7; 内存存储状态如下: 00000000 00000000 00000000 00000111 最高位:左边的第一位,是符号位,用来区分正数或负数,正数使用原码表示,最高位是0,负数用补码表示,最高位是1。例如: int x=-8; 内存的存储状态如下: 11111111 11111111 11111111 11111000 要得到-8的补码,首先得到7的原码,然后将7的原码中的0变成1,1变成0,就是-8的补码。 因此,int型变量的取值范围是-2^31~2^31-1。 2. byte型 使用关键字byte来定义byte型整型变量 byte x ; byte tom_12; 也可以一次定义几个: byte x,tom,jiafei,漂亮 x,tom,jiafei,漂亮都是名字。定义时也可以赋给初值: byte x=-12,tom=28,漂亮=98,jiafei 注:对于byte型变量,内存分配给1个字节,占8位,因此byte型变量的取值范围是: -2^7~2^7-1。

基本数据类型

首先为什么要有数据类型? 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。例如大胖子必须睡双人床,就给他双人床,瘦的人单人床就够了。 Java中的基本类型从概念上分为四种:整数、浮点、字符、布尔值。总共有八种,其列表如下: 名词解释: 字节(Byte)是:计算机文件大小的基本计算单位。 1个字节(Byte) = 8个位(Bit) Bit意为“位”或“比特”,是计算机运算的基础;二进制中的一位,是二进制最小信息单位.二进位可以用来表示一个简单的正/负的判断,有两种状态的开关(如电灯开关) . 简单换算结果:

1个字节(Byte) = 8个位(Bit) 2个字节(Byte) = 16个位(Bit) 4个字节(Byte) = 32个位(Bit) 8个字节(Byte) = 64个位(Bit) 在内存计算过程中,字节少的数据运算速度更快;在硬盘存储中,字节少的数据类型也可充分存入更多的数据。 Java的基本数据类型讲解如下: int:int为整数类型,在存储的时候,用4个字节存储,范围为-2,147,483,648到2,147,483,647,在变量初始化的时候,int 类型的默认值为0。 short:short也属于整数类型,在存储的时候,用2个字节存储,范围为-32,768到32,767,在变量初始化的时候,short类型的默认值为0,一般情况下,因为Java本身转型的原因,可以直接写为0。 long:long也属于整数类型,在存储的时候,用8个字节存储,范围为-9,223,372,036,854,775,808到9,223,372,036, 854,775,807,在变量初始化的时候,long类型的默认值为0L或0l,也可直接写为0。 byte:byte同样属于整数类型,在存储的时候,用1个字节来存储,范围为-128到127,在变量初始化的时候,byte类型的默认值也为0。 float:float属于浮点类型,在存储的时候,用4个字节来存储,范围为32位IEEEE 754单精度范围,在变量初始化的时候,float

JAVA中常用数据类型之间转换的方法

Java中常用数据类型之间转换的方法 Java中几种常用的数据类型之间转换方法: 1.short-->int转换 exp:short shortvar=0; int intvar=0; shortvar=(short)intvar 2.int-->short转换 exp:short shortvar=0; int intvar=0; intvar=shortvar; 3.int->String转换 exp:int intvar=1; String stringvar; Stringvar=string.valueOf(intvar); 4.float->String转换 exp:float floatvar=9.99f; String stringvar;

Stringvar=String.valueOf(floatvar); 5.double->String转换 exp double doublevar=99999999.99; String stringvar; Stringvar=String.valueOf(doublevar); 6.char->String转换 exp char charvar=’a’; String stringvar; Stringvar=String.valueOf(charvar); 7String->int、float、long、double转换Exp String intstring=”10”; String floatstring=”10.1f”; String longstring=”99999999”; String doubleString=”99999999.9”; Int I=Integer.parseInt(intstring); Float f=Integer.parseInt(floatstring); Long lo=long.parseInt(longstring); Double d=double.parseInt(doublestring); 8String->byte、short转换

C语言各种数值类型转换

C语言数据类型转换1 CString,int,string,char*之间的转换 string 转CString CString.format("%s", string.c_str()); char 转CString CString.format("%s", char*); char 转string string s(char *); string 转char * const char *p = string.c_str(); CString 转string string s(CString.GetBuffer()); 1,string -> CString CString.format("%s", string.c_str()); 用c_str()确实比data()要好. 2,char -> string string s(char *); 你的只能初始化,在不是初始化的地方最好还是用assign(). 3,CString -> string string s(CString.GetBuffer()); GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间. 《C++标准函数库》中说的 有三个函数可以将字符串的内容转换为字符数组和C—string 1.data(),返回没有”\0“的字符串数组 2,c_str(),返回有”\0“的字符串数组 3,copy() CString互转int 将字符转换为整数,可以使用atoi、_atoi64或atol。 而将数字转换为CString变量,可以使用CString的Format函数。如 CString s; int i = 64; s.Format("%d", i) Format函数的功能很强,值得你研究一下。

基本数据类型与数值表达式

基本数据类型与数值表达式 一、知识要点 计算机的基本功能是进行数据处理。在C++语言中,数据处理的基本对象是常量和变量。运算是对各种形式的数据进行处理。数据在内存中存放的情况由数据类型所决定。数据的操作要通过运算符实现,而数据和运算符共同组成了表达式。本章是对C++语言中的数据类型、运算符、表达式等内容的全面介绍,要正确理解其特点,并灵活运用,主要掌握以下的知识要点: 1.掌握常量和变量的概念。 2.掌握整型数据和实型数据、字符型数据和字符串型数据的概念和区别。 3.掌握各种类型的变量说明及其初始化。 4.掌握算术运算、关系运算、逻辑运算、赋值运算、逗号运算、条件运算等概念。 5.掌握运算符的优先级、左结合和右结合规则。 6.掌握表达式求值时的自动转换和强制类型转换。 7.掌握自加、自减运算的规则。 8.掌握常用数学函数的功能。 二、例题分析与解答 1.选择题 例题1:运算符+、=、*、>=中,优先级最高的运算符是()。 A.+ B.= C.* D.>= 答案:C 分析:根据C++语言对运算符优先级的规则,以上运算符优先级从低到高的次序为=、>=、+、*。 例题2:下列说法正确的是()。 A.cout<<”\n”是一个语句,它能在屏幕上显示”\n” B.\68代表的是字符D。

C.1E+5的写法正确,它表示余割整型常量。 D.0x10相当于020。 答案:D 分析:分号是语句的已部分,且\n是转义字符;\68代表了八进制的6、8,而八进制中没有数字8;1E+5是实型常量;十六进制的10相当于十进制的16,相当于八进制的20。 例题3:下列不合法的变量名为()。 A.int B.int1 C.name_1 D.name0 答案:A 分析:根据变量名命名要求,变量名只能由大小写字母、数字、下划线组成,且系统关键字不能作为变量名。 例题4:下面正确的为()。 A.4.1/2 B.3.2%3 C.3/2==1 结果为1 D.7/2 结果为3.5 答案:A 分析:%运算符要求式整型;关系运算值为0;两个整数相除,商为为相除后的整数部分。 例题5:已知a=4,b=6,c=8,d=9,则“(a++,b>a++&&c>d)?++d:a

相关文档