工作笔记.docx
《工作笔记.docx》由会员分享,可在线阅读,更多相关《工作笔记.docx(29页珍藏版)》请在冰豆网上搜索。
![工作笔记.docx](https://file1.bdocx.com/fileroot1/2023-2/25/61e924c6-97e9-4067-a6e3-e65fa7cca766/61e924c6-97e9-4067-a6e3-e65fa7cca7661.gif)
工作笔记
工作笔记
目录
1.字符串与数字之间的转换
2.动态数组(C++)
3.C++vector
4.C/C++中的sizeof详解
5.I/O格式控制
记1(2010-2-7)
一字符串转数字
1.CRT函数(需要的头文件)
ASCIIUNICODETCHARVS2005
intatoi_wtoi_tstoi
_ttoi_atoi_l
_wtoi_l
longatol_wtol_tstoi
_ttoi_atoi_l
_wtoi_l
__int64_atoi64_wtoi64_tstoi64
_ttoi64_atoi64_l
_wtoi64_l
float_atoflt
_atoflt_l
doubleatof_wtof_tstof
_ttof_atof_l
_wtof_l
_atodbl
_atodbl_l
longdouble_atoldbl
_atoldbl_l
2.使用sscanf头文件
sscanf()从一个字符串中读进与指定格式相符的数据。
原型:
intsscanf(constchar*buffer,constchar*format[,argument]...);intscanf(constchar*format[,argument]...);其中参数buffer:
输入存储的数据;format:
格式控制字符串
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
例:
(msdn里的例子)
#include
intmain(void)
{
chartokenstring[]="151214...";
chars[81];
charc;
inti;
floatfp;
//Inputvariousdatafromtokenstring:
//max80characterstring:
sscanf(tokenstring,"%80s",s);//C4996
sscanf(tokenstring,"%c",&c);//C4996
sscanf(tokenstring,"%d",&i);//C4996将字符串转化为整数
sscanf(tokenstring,"%f",&fp);//C4996将字符串转化为浮点数
//Note:
sscanfisdeprecated;considerusingsscanf_sinstead
//Outputthedataread
printf("String=%s\n",s);
printf("Character=%c\n",c);
printf("Integer:
=%d\n",i);
printf("Real:
=%f\n",fp);
}输出结果:
String=15
Character=1
Integer:
=15
Real:
=15.000000其实sscanf很强大,功能类似于正则表达式,可以用于比较复杂的字符串处理。
当只是单纯的将字符串转化为整数建议用第一种方法。
参考SDK:
StrToInt
头文件
导入库shlwapi.lib
二数字转字符串
1.CRT函数
ASCIIUNICODETCHARVS2005
intitoa
_itoa_itow_itot
longltoa
_ltoa_ltow_ltot
__int64_i64toa_i64tow_i64tot
doublegcvt
_gcvt
_ecvt
_fcvt_wtof
_tstof
_ttof_gcvt_s
_ecvt_s
_fcvt_s
2.使用sprintf头文件
原型:
intsprintf(char*buffer,constchar*format[,argument]...);
将字符串格式化,buffer格式化输出的字符串;format格式控制字符串;返回字符串长度。
例:
(msdn例子)
//crt_sprintf.c
//compilewith:
/W3
//Thisprogramusessprintftoformatvarious
//dataandplacetheminthestringnamedbuffer.
#include
intmain(void)
{
charbuffer[200],s[]="computer",c='l';
inti=35,j;
floatfp=1.7320534f;
//Formatandprintvariousdata:
j=sprintf(buffer,"String:
%s\n",s);//C4996
j+=sprintf(buffer+j,"Character:
%c\n",c);//C4996
j+=sprintf(buffer+j,"Integer:
%d\n",i);//C4996整数转化为字符串
j+=sprintf(buffer+j,"Real:
%f\n",fp);//C4996浮点数转化为字符串
//Note:
sprintfisdeprecated;considerusingsprintf_sinstead
printf("Output:
\n%s\ncharactercount=%d\n",buffer,j);
}
输出:
String:
computer
Character:
l
Integer:
35
Real:
1.732053
charactercount=793.:
StringCbPrintf
4.MFC/ATL:
CString:
:
Format
例:
CStringstr;
str.Format(_T("Floatingpoint:
%.2f\n"),12345.12345);
_tprintf("%s",(LPCTSTR)str);
输出:
Floatingpoint:
12345.12
三补充:
1函数原型
字符串转int
intatoi(constchar*string);
_int64_atoi64(constchar*string);
int_wtoi(constwchar_t*string);
_int64_wtoi64(constchar*string);
字符串转long
longatol(constchar*string);
long_wtol(constwchar_t*string);
字符串转double
doubleatof(constchar*string);
double_wtof(constwchar_t*string);
int转字符串
cahr*_itoa(intvalue,char*string,intradix);
char*_i64toa(_int64value,char*string,intradix);
char*_ui64toa(unsigned_int64value,char*string,intradix);
wchar_t*_itow(intvalue,wchar_t*string,intradix);
wchar_t*_i64tow(_int64value,wchar_t*string,intradix);
wchar_t*_ui64tow(unsigned_int64value,wchar_t*string,intradix);
参数的意义:
value是指要转换的整数,sring是用来存放转换后结果的便利,radix是用来说明转换成几进制的数据,默认值是十进制数的。
转换的进制范围是二进制到三十六进制。
long转字符串
char*_ltoa(longvalue,char*string,intradix);
wchar_t*_ltow(longvalue,wchar_t*string,intradix);
其中,参数value为被转换的值,参数string为字符串缓冲区,radix为进制。
double转字符串
char*_fcvt(doublevalue,intcount,int*dec,int*sign);
其中参数value为双精度数,参数count为转换的小数点后面的位数,dec表示小数点的位置,sign表示符号。
2float与double的区别
单精度浮点数在机内占4个字节,用32位二进制描述。
双精度浮点数在机内占8个字节,用64位二进制描述。
浮点数在机内用指数型式表示,分解为:
数符,尾数,指数符,指数四部分。
数符占1位二进制,表示数的正负。
指数符占1位二进制,表示指数的正负。
尾数表示浮点数有效数字,0.xxxxxxx,但不存开头的0和点
指数存指数的有效数字。
指数占多少位,尾数占多少位,由计算机系统决定。
可能是数符加尾数占24位,指数符加指数占8位--float.
数符加尾数占48位,指数符加指数占16位--double.
知道了这四部分的占位,按二进制估计大小范围,再换算为十进制,就是你想知道的数值范围。
对编程人员来说,double和float的区别是double精度高,有效数字16位,float精度7位。
但double消耗内存是float的两倍,double的运算速度比float慢得多,C语言中数学函数名称double和float不同,不要写错,能用单精度时不要用双精度(以省内存,加快运算速度)。
Example:
#include
#include
main()
{
CStringstr;
str.Format(_T("#%X\n"),15);
_tprintf("%s",(LPCTSTR)str);
}
记二(2010-4-1)
2.动态数组
在C++中实现变长数组
1.变长一维数组
这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组。
实现变长数组最简单的是变长一维数组,你可以这样做:
//文件名:
array01.cpp
#include
usingnamespacestd;
intmain()
{
intlen;
cin>>len;
//用指针p指向new动态分配的长度为len*sizeof(int)的内存空间
int*p=newint[len];
...........
delete[]p;
return0;
}
注意int*p=newint[len];这一句,你不能这样做:
intp[len];
C++编译器会报错说len的大小不能确定,因为用这种形式声明数组,数组的大小需要在编译时确定。
而且这样也不行:
intp[]=newint[len];
编译器会说不能把int*型转化为int[]型,因为用new开辟了一段内存空间后会返回这段内存的首地址,所以要把这个地址赋给一个指针,所以要用int*p=newint[len];
array01.cpp实现了一个变长的一维数组,但是要养成一个好习惯,就是注意要注销指针p,使程序释放用new开辟的内存空间。
当然使用C++标准模版库(STL)中的vector(向量)也可以实现变长数组:
//文件名:
array02.cpp
#include
#include
usingnamespacestd;
intmain()
{
intlen;
cin>>len;
vectorarray(len);//声明变长数组
for(inti=0;i{
array[i]=i;
cout<}
return0;
}
这里的变长数组让我联想到了java的java.util包中的vector和C#中的ArrayList,它们也可以在各自的语言中实现变长数组。
不过C++中的vector不能像C#一样有托管的垃圾回收机制回收被占用的内存空间,但是你可以在使用完vector后调用~vector()析构函数释放内存。
2.变长n维数组
变长的n维数组实现起来有些麻烦,但是在工程与软件设计应用中常使用的是二维数组,所以在这里着重介绍变长的二维数组,变长的n维数组可以按照类似的方法实现。
首先看一个经典的用C实现变长二维数组的例子:
//文件名:
array03.c
#include
#include
voidmain()
{
intx,y,i,j;
float**a,*b;
printf("请输入你所求解的线性方程组的行数x:
x=");
scanf("%d",&x);
printf("请输入你所求解的线性方程组的列数y:
y=");
scanf("%d",&y);
a=(float**)malloc(sizeof(float*)*x);
b=(float*)malloc(sizeof(float)*x);
for(i=0;i{
*(a+i)=(float*)malloc(sizeof(float)*y);
}/*读入数据*/
printf("请按行的顺序依次输入系数的值(共%d项):
",x*y);
for(i=0;i<=x-1;i++)
for(j=0;j<=y-1;j++)scanf("%f",&a[i][j]);
printf("请按列的顺序依次输入常数的值(共%d项):
",x);
for(j=0;j<=x-1;j++)scanf("%f",&b[j]);
printf("您输入方程组的增广矩阵为:
\n");
for(i=0;i<=x-1;i++)
{
for(j=0;j<=y-1;j++)
printf("%.5f",a[i][j]);
printf("%.5f",b[i]);
printf("\n");
}
free(b);
for(i=0;ifree(*(a+i));
}
那么用C++怎样实现呢?
在C++中可以通过new和delete运算符动态开辟和释放空间,其中new与C中malloc函数的功能相似,delete与C中free函数的功能相似。
用C++实现变长二维数组时可以采用两种方法:
双指针方法和使用STL中vector(向量)的方法。
首先介绍一下双指针方法,在这里双指针就是指像指针的指针,比如你可以这样声明一个数组:
int**p=newint*[num1];
而对每一个*p(一共num1个*p)申请一组内存空间:
for(inti=0;ip[i]=newint[num2];
其中,num1是行数,num2是数组的列数。
测试的源程序如下:
//文件名:
array04.cpp
#include
#include
usingnamespacestd;
intmain()
{
intnum1,//行数
num2;//列数
cout<<"Pleaseenterthenumberforrowandcolumn:
"<cin>>num1>>num2;
//为二维数组开辟空间
int**p=newint*[num1];
for(inti=0;ip[i]=newint[num2];
for(intj=0;j{
for(intk=0;k{
p[j][k]=(j+1)*(k+1);
cout<'<}
cout<}
//释放二维数组占用的空间
for(intm=0;mdelete[]p[m];
delete[]p;
return0;
}
以下是运行结果:
Pleaseenterthenumberforrowandcolumn:
45
1:
004915F02:
004915F43:
004915F84:
004915FC5:
00491600
2:
004911804:
004911846:
004911888:
0049118C10:
00491190
3:
004911406:
004911449:
0049114812:
0049114C15:
00491150
4:
004911008:
0049110412:
0049110816:
0049110C20:
00491110
Pressanykeytocontinue
程序清单array04.cpp可以显示分配的内存空间单元的地址,大家可以看到,由于数组空间是动态分配的,数组行之间的地址空间是不连续的,因为不同行的数组元素的地址空间是用不同的new来分配的。
而每一行之中列之间的地址空间是连续的。
那么用vector(向量)怎样实现二维数组呢?
以下给出源程序:
//文件名:
array05.cpp
#include
#include
#include
usingnamespacestd;
intmain()
{
inti,
j,
m,//行数
n;//列数
cout<<"inputvalueform,n:
";
cin>>m>>n;
//注意下面这一行:
vector"之间要有空格!
否则会被认为是重载">>"。
vector>vecInt(m,vector(n));
for(i=0;ifor(j=0;jvecInt[i][j]=i*j;
for(i=0;i{
for(j=0;jcout<"<cout<}
return0;
}
以下是运行结果:
inputvalueform,n:
34
0:
004911800:
004911840:
004911880:
0049118C
0:
004911401:
004911442:
004911483:
0049114C
0:
004911002:
004911044:
004911086:
0049110C
Pressanykeytocontinue
大家可以看到,这里vector中元素的内存的地址分配也有同双指针实现的二维数组有同样的特点。
不过用vector的方法比使用双指针简单地多,分配内存空间时会更安全,数组初始化代码也更简单,所以本人建议使用STL中的vector来实现变长多维数组。
以下是一个变长三维数组:
)
//文件名:
array06.cpp
#include
#include
#include
usingnamespacestd;
intmain()
{
inti,
j,
k,
m,//一维坐标
n,//二维坐标
l;//三维坐标
cout<<"inputvalueform,n,l:
";
cin>>m>>n>>l;
vector>>vecInt(m,vector>(n,vector(l)));
for(i=0;ifor(j=0;jfor(k=0;kvecInt[i][j][k]=i+j+k;
for(i=0;i{
for(j=0;j{
for(k=0;kcout<"<cout<}
cout<}
return0;
}
运行结果:
inputvalueform,n,l:
234
0:
00492FE01:
00492FE42:
00492FE83:
00492FEC
1:
00492FA02:
00492FA43:
00492FA84:
00492FAC
2:
00492F603:
00492F644:
00492F685:
00492F6C
1:
00492EC02:
00492EC43:
0049