C++ sprintf s(archiveName,"archive.out");怎么写成C#?

我采用的是C#开发的一个windows应用程序(pipe_server_csharp)作为服务器端,而MFC开发的应用程序(NamedPipeClient_vc)作为客户端。客户端和服务器端要进行频繁的大量的通信,常见的是文本信息和曲线数据,例如,一共有10条曲线,每条曲线有1000000条double数据。
服务器端:
服务器端是用在VS2005中用C#开发的一个名为pipe_server_csharp的应用程序,只有一个名为frmServer的主界面。
由于管道的相关API函数都是属于kernel32.dll函数,C#中不能直接调用,所以必须将所要用到的API函数全部封装在一个类NamedPipeNative中。 至于如何调用这些API函数,有兴趣的朋友可以上网搜索,或者看我的另一篇文章《C#中怎么调用命名管道的WinAPI》。
NamedPipeNative类中几个主要函数如下(大家可以对比这些重写的API函数和原来的函数有什么变化):
[DllImport(&kernel32.dll&,&SetLastError=true)]
public&static&extern&IntPtr&CreateNamedPipe
String&lpName,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// pipe name
uint&dwOpenMode,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// pipe open mode
uint&dwPipeMode,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// pipe-specific modes
uint&nMaxInstances,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// maximum number of instances
uint&nOutBufferSize,&&&&&&&&&&&&&&&&&&&&&&&&&&&// output buffer size
uint&nInBufferSize,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// input buffer size
uint&nDefaultTimeOut,&&&&&&&&&&&&&&&&&&&&&&&&&&// time-out interval
IntPtr&pipeSecurityDescriptor&&&&&&&&// SD
[DllImport(&kernel32.dll&,&SetLastError=true)]
public&static&extern&bool&ConnectNamedPipe
IntPtr&hHandle,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// handle to named pipe
Overlapped&lpOverlapped&&&&&&&&&&&&&&&&&&&// overlapped structure
[DllImport(&kernel32.dll&,&SetLastError=true)]
public&static&extern&IntPtr&CreateFile
String&lpFileName,&&&&&&&&&&&&&&&&&&&&&&&&&&// file name
uint&dwDesiredAccess,&&&&&&&&&&&&&&&&&&&&&&&// access mode
uint&dwShareMode,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// share mode
SecurityAttributes&attr,&&&&&&&&&&&&&&&&&&// SD
uint&dwCreationDisposition,&&&&&&&&&&// how to create
uint&dwFlagsAndAttributes,&&&&&&&&&&&// file attributes
uint&hTemplateFile);&&&&&&&&&&&&&&&&&&&&&&// handle to template file
[DllImport(&kernel32.dll&,&SetLastError=true)]
public&static&extern&bool&ReadFile
IntPtr&hHandle,&&&&// handle to file
byte[]&lpBuffer,// data buffer字节流
uint&nNumberOfBytesToRead,// number of bytes to read
byte[]&lpNumberOfBytesRead,// number of bytes read
uint&lpOverlapped// overlapped buffer
[DllImport(&kernel32.dll&,&SetLastError=true)]
public&static&extern&bool&WriteFile
IntPtr&hHandle,&&&&// handle to file
byte[]&lpBuffer,// data buffer字节流
uint&nNumberOfBytesToWrite,&// number of bytes to write
byte[]&lpNumberOfBytesWritten,&&&// number of bytes written
uint&lpOverlapped&// overlapped buffer
还有其他一些常量:
public&const&uint&PIPE_ACCESS_DUPLEX&= 0x;
public&const&uint&PIPE_ACCESS_OUTBOUND&= 0x;
public&const&uint&PIPE_TYPE_BYTE&= 0x;
public&const&uint&PIPE_TYPE_MESSAGE&= 0x;
在此不一一列举了。
封装之后,在C#中就可以直接调用这些函数和常量了。
另外,创建了一个类CMyPipe,封装了服务器管道的属性和方法,如创建管道,读写数据等:
namespace&pipe_server_csharp
&&&&public&class&CMyPipe
&&&&&&&&private&string&m_PipeN//管道名全称
&&&&&&&&public&string&PipeName
&&&&&&&&&&&&get&{&return&m_PipeN }
&&&&&&&&&&&&set&{&m_PipeName&=&value; }
&&&&&&&&private&IntPtr&m_HP//管道句柄
&&&&&&&&public&IntPtr&HPipe
&&&&&&&&&&&&get&{&return&m_HP }
&&&&&&&&&&&&set&{&m_HPipe&=&value; }
&&&&&&&&public&CMyPipe()//无参构造函数
&&&&&&&&&&&&m_HPipe&= (IntPtr)NamedPipeNative.INVALID_HANDLE_VALUE;
&&&&&&&&&&&&m_PipeName&=&&\\\\.\\pipe\\robinTest&;
&&&&&&&&public&CMyPipe(string&pipeName)//有参构造函数
&&&&&&&&&&&&m_HPipe&= (IntPtr)NamedPipeNative.INVALID_HANDLE_VALUE;
&&&&&&&&&&&&m_PipeName&=&pipeN
&&&&&&&&~CMyPipe()//析构函数
&&&&&&&&&&&&Dispose();
&&&&&&&&public&void&Dispose()
&&&&&&&&&&&&lock&(this)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if&(m_HPipe&!= (IntPtr)NamedPipeNative.INVALID_HANDLE_VALUE)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&NamedPipeNative.CloseHandle(m_HPipe);
&&&&&&&&&&&&&&&&&&&&m_HPipe&= (IntPtr)NamedPipeNative.INVALID_HANDLE_VALUE;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&public&void&CreatePipe()//创建管道
&&&&&&&&&&&&m_HPipe&=&NamedPipeNative.CreateNamedPipe(m_PipeName,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&NamedPipeNative.PIPE_ACCESS_DUPLEX,&&&&&&&&&//&数据双工通信
&&&&&&&&&&&&&&&&&&&&&&&&&&&&NamedPipeNative.&PIPE_TYPE_MESSAGE&|NamedPipeNative.PIPE_WAIT,&&&&&&&&&&&&&&&&&&&&&&&&&&&100,&&&&&&&&&&&&&&&&&&&&&&&&&//&最大实例个数
&&&&&&&&&&&&&&&&&&&&&&&&&&&&128,&&&&&&&&&&&&&&&&&&&&&&&&&&&//&流出数据缓冲大小
&&&&&&&&&&&&&&&&&&&&&&&&&&&&128,&&&&&&&&&&&&&&&&&&&&&&&&&&&//&流入数据缓冲大小
&&&&&&&&&&&&&&&&&&&&&&&&&&&&150,&&&&&&&&&&&&&&&&&&&&&&&&&//&超时,毫秒
&&&&&&&&&&&&&&&&&&&&&&&&&&&&IntPtr.Zero&&&&&&&&&&&&&&&&&&//&安全信息
&&&&&&&&&&&&&&&&&&&&&&&&&&&&);
&&&&&&&&&&&&if&(m_HPipe.ToInt32() ==&NamedPipeNative.INVALID_HANDLE_VALUE)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&frmServer.ActivityRef.AppendText(&创建命名管道失败&&);
&&&&&&&&&&&&&&&&frmServer.ActivityRef.AppendText(Environment.NewLine);
&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&}
&&&&&&&&&&&&frmServer.ActivityRef.AppendText(&创建命名管道完毕&&);
&&&&&&&&&&&&frmServer.ActivityRef.AppendText(Environment.NewLine);&&&&&&&&&&
&&&&&&&&public&void&ReadCurveData()//读取曲线数据
&&&&&&&&&&&&int&nCurvesToRead&= 0;
&&&&&&&&&&&&nCurvesToRead&=&ReadInt(HPipe);//先读取需要读取的曲线条数,如
&&&&&&&&&&&&frmServer.CurveDataList.Clear();
&&&&&&&&&&&&for&(int&j&= 1;&j&&=&nCurvesToR&j++)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&string&curveName&=&ReadString(HPipe);//读取该曲线名称
&&&&&&&&&&&&&&&&int&nCount&= 0;
&&&&&&&&&&&&&&&&nCount&=&ReadInt(HPipe);//读取该曲线的数据总数(数组大小)
&&&&&&&&&&&&&&&&double[]&readData&=&new&double[nCount];
&&&&&&&&&&&&&&&&for&(int&i&= 0;&i&&&nC&i++)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&readData[i] =&ReadDouble(HPipe);//顺序读取曲线的数据
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&CCurve&newCurve&=&new&CCurve();
&&&&&&&&&&&&&&&&newCurve.CurveName&=&curveN
&&&&&&&&&&&&&&&&newCurve.CurveData&=&readD
&&&&&&&&&&&&&&&&frmServer.CurveDataList.Add(newCurve);
&&&&&&&&&&&&}
&&&&&&&&public&void&ReadTextInfo()//读取文本信息
&&&&&&&&&&&&string&textInfo&=&ReadString(HPipe);//读取该曲线名称
&&&&&&&&&&&&frmServer.ActivityRef.AppendText(textInfo&+&Environment.NewLine);
&&&&&&&&&&&&frmServer.ActivityRef.AppendText(Environment.NewLine);
&&&&&&&&public&void&ReadData()
&&&&&&&&&&&&//read data
&&&&&&&&&&&&int&flag&= -1;
&&&&&&&&&&&&flag&=&ReadInt(HPipe);//获取当前要读取的数据的信息
&&&&&&&&&&&&if&(flag&== 0)//flag==0表示读取曲线数据
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&ReadCurveData();
&&&&&&&&&&&&}
&&&&&&&&&&&&else&if&(flag&== 1)//flag==1表示读取文本信息
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&ReadTextInfo();
&&&&&&&&&&&&}
//写字符串,由于字符串的大小不同,所以先将字符串的大小写入,然后写字符串内容,对应的,
//在c++端,读字符串时先读取字符数组大小,从而给字符数组开辟相应的空间,然后读取字符串内容。
&&&&&&&&public&bool&WriteString(IntPtr&HPipe,&string&str)
&&&&&&&&&&&&byte[]&Val&=&System.Text.Encoding.UTF8.GetBytes(str);
&&&&&&&&&&&&byte[]&dwBytesWrite&=&new&byte[4];
&&&&&&&&&&&&int&len&=&Val.L
&&&&&&&&&&&&byte[]&lenBytes&=&System.BitConverter.GetBytes(len);
&&&&&&&&&&&&if&(NamedPipeNative.WriteFile(HPipe,&lenBytes, 4,&dwBytesWrite, 0))
&&&&&&&&&&&&&&&&return&(NamedPipeNative.WriteFile(HPipe,&Val, (uint)len,&dwBytesWrite, 0));
&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&return&false;
&&&&&&&&public&string&ReadString(IntPtr&HPipe)
&&&&&&&&&&&&string&Val&=&&&;
&&&&&&&&&&&&byte[]&bytes&=&ReadBytes(HPipe);
&&&&&&&&&&&&if&(bytes&!=&null)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Val&=&System.Text.Encoding.UTF8.GetString(bytes);
&&&&&&&&&&&&}
&&&&&&&&&&&&return&V
&&&&&&&&public&byte[]&ReadBytes(IntPtr&HPipe)
&&&&&&&&&&&&//传字节流
&&&&&&&&&&&&byte[]&szMsg&=&null;
&&&&&&&&&&&&byte[]&dwBytesRead&=&new&byte[4];
&&&&&&&&&&&&byte[]&lenBytes&=&new&byte[4];
&&&&&&&&&&&&int&
&&&&&&&&&&&&if&(NamedPipeNative.ReadFile(HPipe,&lenBytes, 4,&dwBytesRead, 0))//先读大小
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&len&=&System.BitConverter.ToInt32(lenBytes, 0);
&&&&&&&&&&&&&&&&szMsg&=&new&byte[len];
&&&&&&&&&&&&&&&&if&(!NamedPipeNative.ReadFile(HPipe,&szMsg, (uint)len,&dwBytesRead, 0))
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//frmServer.ActivityRef.AppendText(&读取数据失败&);
&&&&&&&&&&&&&&&&&&&&return&null;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&return&szM
&&&&&&&&public&float&ReadFloat(IntPtr&HPipe)
&&&&&&&&&&&&float&Val&= 0;
&&&&&&&&&&&&byte[]&bytes&=&new&byte[4]; //单精度需4个字节存储
&&&&&&&&&&&&byte[]&dwBytesRead&=&new&byte[4];
&&&&&&&&&&&&if&(!NamedPipeNative.ReadFile(HPipe,&bytes, 4,&dwBytesRead, 0))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//frmServer.ActivityRef.AppendText(&读取数据失败&);
&&&&&&&&&&&&&&&&return&0;
&&&&&&&&&&&&}
&&&&&&&&&&&&Val&=&System.BitConverter.ToSingle(bytes, 0);
&&&&&&&&&&&&return&V
&&&&&&&&public&double&ReadDouble(IntPtr&HPipe)
&&&&&&&&&&&&double&Val&= 0;
&&&&&&&&&&&&byte[]&bytes&=&new&byte[8]; //双精度需8个字节存储
&&&&&&&&&&&&byte[]&dwBytesRead&=&new&byte[4];
&&&&&&&&&&&&if&(!NamedPipeNative.ReadFile(HPipe,&bytes, 8,&dwBytesRead, 0))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//frmServer.ActivityRef.AppendText(&读取数据失败&);
&&&&&&&&&&&&&&&&return&0;
&&&&&&&&&&&&}
&&&&&&&&&&&&Val&=&System.BitConverter.ToDouble(bytes, 0);
&&&&&&&&&&&&return&V
&&&&&&&&public&int&ReadInt(IntPtr&HPipe)
&&&&&&&&&&&&int&Val&= 0;
&&&&&&&&&&&&byte[]&bytes&=&new&byte[4]; //整型需4个字节存储
&&&&&&&&&&&&byte[]&dwBytesRead&=&new&byte[4];
&&&&&&&&&&&&if&(!NamedPipeNative.ReadFile(HPipe,&bytes, 4,&dwBytesRead, 0))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//frmServer.ActivityRef.AppendText(&读取数据失败&);
&&&&&&&&&&&&&&&&return&0;
&&&&&&&&&&&&}
&&&&&&&&&&&&Val&=&System.BitConverter.ToInt32(bytes, 0);
&&&&&&&&&&&&return&V
主程序,读取和显示通信信息:
&&&&public&partial&class&frmServer&:&Form
&&&&&&&&public&static&System.Windows.Forms.TextBox&ActivityR//显示信息&&&&&&
&&&&&&&&public&static&ArrayList&CurveDataList&=&new&ArrayList();//存储数据
&&&&&&&&public&static&string&PipeName&=&&robinTest&;
&&&&&&&&public&static&string&ServeName&=&&.&;
&&&&&&&&public&static&string&FullPipeName&=&&\\\\&+ServeName+&\\pipe\\&+PipeN//管道全名
&&&&&&&&public&static&CMyPipe&TheP//管道实例
&&&&&&&&private&Thread&hT//线程
&&&&&&&&public&frmServer()
&&&&&&&&&&&&InitializeComponent();
&&&&&&&&&&&&frmServer.ActivityRef&=&this.txtM
&&&&&&&&&&&&Control.CheckForIllegalCrossThreadCalls&=&false;//不捕获线程错误调用,这样线程就可以别的线程中创建的东西,这样做也会破坏了线程的安全
&&&&&&&&&&&&ThePipe&=&new&CMyPipe(FullPipeName);
&&&&&&&&&&&&ThePipe.CreatePipe();//创建管道
&&&&&&&&&&&&hThread&=&new&Thread(new&ThreadStart(PipeProcess));
&&&&&&&&&&&&hThread.IsBackground&=&true;
&&&&&&&&&&&&hThread.Name&=&&Main Pipe Thread&;
&&&&&&&&&&&&hThread.Start();//&启动线程.监听管道,进行通信
&&&&&&&&&&&&Thread.Sleep(1000);
&&&&&&&&public&void&PipeProcess()
&&&&&&&&&&&&bool&ret&=&false;
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&while&(true)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&ret&=&NamedPipeNative.ConnectNamedPipe(ThePipe.HPipe,&null);//连接到管道
&&&&&&&&&&&&&&&&&&&&if&(!ret)
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&if&(NamedPipeNative.GetLastError() ==&NamedPipeNative.ERROR_PIPE_CONNECTED)&&//&客户还在连接中
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&frmServer.ActivityRef.AppendText(&连接正常,客户还在连接中……&&+Environment.NewLine);//此处会出错,因为线程调用的问题
&&&&&&&&&&&&&&&&&&&&&&&&&&&&ret&=&true;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&if&(NamedPipeNative.GetLastError() ==&NamedPipeNative.ERROR_NO_DATA)&&&&&&&&&//客户已经关闭
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&frmServer.ActivityRef.AppendText(&客户已经关闭,等待客户…………&&+Environment.NewLine);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&NamedPipeNative.DisconnectNamedPipe(ThePipe.HPipe);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&continue;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&frmServer.ActivityRef.AppendText(&有客户接入&&+Environment.NewLine);&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&ThePipe.ReadData();//读取数据
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&catch&(Exception&ex)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&MessageBox.Show(ex.ToString());
&&&&&&&&&&&&}
&&&&&&&&&&&&finally
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&frmServer.ActivityRef.AppendText(&线程退出!&);
&&&&&&&&&&&&}
  客户机端:
客户端是在VS6.0中用MFC开发的一个单界面应用程序,名为NamedPipeClient_vc。在vc6.0中可以直接调用API函数,不需要封装。
当然,按照惯例,还是将客户端的命名管道相关的属性和方法封装成类CMyPipe,如下:
CString PipeName = &robinTest&;
CString ServerName = &.&;
CString FullPipeName=&\\\\&+ServerName+&\\pipe\\&+PipeN
CMyPipe::CMyPipe()
&&&&&&&m_pThread=NULL;
CMyPipe::~CMyPipe()
&&&&&&&if(m_pThread)
&&&&&&&&&&&&&&if(TerminateThread(m_pThread-&m_hThread,0))
&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&if(m_pThread)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&delete&&&&&&m_pT
&&&&&&&&&&&&&&&&&&&&&m_pThread = NULL;
&&&&&&&&&&&&&&}
//客户端和服务器端建立连接
void CMyPipe::ClientCreateFile()
&&&&&&&BOOL ret = ::WaitNamedPipe(FullPipeName, 5000);
&&&&&&&if (!ret)
&&&&&&&&&&&&&&//ClientMsg=&管道忙或者没有启动……\n&;
&&&&&&&&&&&&&&
&&&&&&&m_hPipe&&= ::CreateFile(FullPipeName,
&&&&&&&&&&&&&&GENERIC_READ|GENERIC_WRITE,
&&&&&&&&&&&&&&FILE_SHARE_READ|FILE_SHARE_WRITE,
&&&&&&&&&&&&&&NULL,
&&&&&&&&&&&&&&OPEN_EXISTING,
&&&&&&&&&&&&&&FILE_ATTRIBUTE_NORMAL,
&&&&&&&&&&&&&&NULL);
&&&&if (m_hPipe == INVALID_HANDLE_VALUE)
&&&&&&&&&&&&&
&&&&&&&&char szErr[256] = &&;
&&&&&&&&DWORD dwErr = GetLastError();
&&&&&&&&&&&&&&sprintf(szErr, &%l&, dwErr);
&&&&&&&&//ClientMsg=szE
&&&&&&&//ClientMsg=&打开管道了\n&;
//写字符串
void CMyPipe::WriteString(char *szMsg)
&&&&&&&DWORD&&dwSize = strlen(szMsg)+1, dwBytesWritten = 0;
&&&&&&&BOOL ret =WriteFile(m_hPipe, &dwSize, 4, &dwBytesWritten, NULL);
&&&&&&&if (ret)
&&&&&&&&&&&&&&BOOL ret2=WriteFile(m_hPipe, szMsg, dwSize, &dwBytesWritten, NULL);
//写单精度
void CMyPipe::WriteFloat(float szMsg)
&&&&&&&DWORD&&dwSize = 4, dwBytesWritten = 0;
&&&&&&&BOOL ret=WriteFile(m_hPipe, &szMsg, dwSize, &dwBytesWritten, NULL);
//写双精度
void CMyPipe::WriteDouble(double szMsg)
&&&&&&&DWORD&&dwSize = 8, dwBytesWritten = 0;
&&&&&&&BOOL ret=WriteFile(m_hPipe, &szMsg, dwSize, &dwBytesWritten, NULL);
void CMyPipe::WriteInt(int szMsg)
&&&&&&&DWORD&&dwSize = 4, dwBytesWritten = 0;
&&&&&&&BOOL ret=WriteFile(m_hPipe, &szMsg, dwSize, &dwBytesWritten, NULL);
void CMyPipe::ClosePipe()
&&&&&&&CloseHandle(m_hPipe);
//读字符串
char * CMyPipe::ReadString()
&&&&&&&char *readS
&&&&&&&DWORD&&drSize=0, dwBytesRead = 0;
&&&&&&&BOOL ret =ReadFile(m_hPipe, &drSize, 4, &dwBytesRead, NULL);
&&&&&&&if (ret)
&&&&&&&&&&&&&&readStr=new char[drSize];
&&&&&&&&&&&&&&BOOL ret2=ReadFile(m_hPipe, readStr, drSize, &dwBytesRead, NULL);
&&&&&&&return readS
int CMyPipe::ReadInt()
&&&&&&&int intRead=0;
&&&&&&&DWORD&&drSize=4, dwBytesRead = 0;
&&&&&&&BOOL ret =ReadFile(m_hPipe, &intRead, drSize, &dwBytesRead, NULL);
&&&&&&&return intR
float CMyPipe::ReadFloat()
&&&&&&&float floatRead=0;
&&&&&&&DWORD&&drSize=4, dwBytesRead = 0;
&&&&&&&BOOL ret =ReadFile(m_hPipe, &floatRead, drSize, &dwBytesRead, NULL);
&&&&&&&return floatR
double CMyPipe::ReadDouble()
&&&&&&&double floatRead=0;
&&&&&&&DWORD&&drSize=8, dwBytesRead = 0;
&&&&&&&BOOL ret =ReadFile(m_hPipe, &floatRead, drSize, &dwBytesRead, NULL);
&&&&&&&return floatR
而主程序NamedPipeClient_vcDlg.cpp如下:
CMyPipe theP
//连接服务器管道
void CNamedPipeClient_vcDlg::OnOpen()
&&&&&&&// TODO: Add your control notification handler code here
&&&&&&&thePipe.ClientCreateFile();
//发送数据
void CNamedPipeClient_vcDlg::OnWrite()
&&&&&&&// TODO: Add your control notification handler code here
&&&&&&&WriteData();
//关闭管道
void CNamedPipeClient_vcDlg::OnClose()
&&&&&&&// TODO: Add your control notification handler code here
&&&&&&&thePipe.ClosePipe();
//写曲线数据(注意写入的顺序,读的时候也要按照这个顺序)
void CNamedPipeClient_vcDlg::WriteCurveData()
&&&&&&&int nCurvesToWrite=10;
&&&&&&&thePipe.WriteInt(nCurvesToWrite);//先写入要传递的曲线总条数
&&&&&&&for (int j = 1; j &= nCurvesToW j++)
&&&&&&&&&&&&&&char *curveName= &curve&;//
&&&&&&&&&&&&&&thePipe.WriteString(curveName);//写该曲线名称
&&&&&&&&&&&&&&int nCount = 10000;//该曲线的数据总数(数组大小)
&&&&&&&&&&&&&&thePipe.WriteInt(nCount);
&&&&&&&&&&&&&&double *writeData=new double[nCount];
&&&&&&&&&&&&&&for (int i = 0; i & nC i++)
&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&writeData[i]=i;//给每个曲线数据赋初值
&&&&&&&&&&&&&&&&&&&&&thePipe.WriteDouble(writeData[i]);//顺序写曲线的数据
&&&&&&&&&&&&&&}
//写文本信息
void CNamedPipeClient_vcDlg::WriteTextInfo(char *textInfo)
&&&&&&&thePipe.WriteString(textInfo);
void CNamedPipeClient_vcDlg::WriteData()
&&&&&&&int flag=1;//传递的信息的标识,0表示曲线数据,1表示文本信息
&&&&&&&if (flag==0)
&&&&&&&&&&&&&&thePipe.WriteInt(flag);
&&&&&&&&&&&&&&WriteCurveData();
&&&&&&&else if (flag==1)
&&&&&&&&&&&&&&thePipe.WriteInt(flag);
&&&&&&&&&&&&&&char * charWrite=&hedafasfddsafdsafdsafdsafdsafsafdsafdsafdsafsaaaa&;
&&&&&&&&&&&&&&WriteTextInfo(charWrite);
/xiongxuanwen/archive//1992389.html
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7232次
排名:千里之外
转载:32篇
(2)(1)(16)(1)(5)(6)(4)(3)(2)1.求下面函数的返回值(微软)
int&func(x)
int&countx&=&0;
countx&++;
x&=&x&(x-1);
假定。&答案:
思路:将转化为进制,看含有的的个数。
2.&什么是“引用”?申明和使用“引用”要注意哪些问题?
答:引用就是某个目标变量的“别名”,对引用的操作与对变量直接操作效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。
3.&将“引用”作为函数参数有哪些特点?
()传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
()使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
()使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用指针变量名的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。
4.&在什么时候需要使用“常引用”? 
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:类型标识符&引用名目标变量名;
const&int&&ra=a;
ra=1;&//错误
a=1;&//正确
string&foo(&);
void&bar(string&&&s);
那么下面的表达式将是非法的:
bar(foo(&));
bar(&hello&world&);
原因在于和串都会产生一个临时对象,而在中,这些临时对象都是类型的。因此上面的表达式就是试图将一个类型的对象转换为非类型,这是非法的。
引用型参数应该在能被定义为的情况下,尽量定义为。
5.&将“引用”作为函数返回值类型的格式、好处和需要遵守的规则
格式:类型标识符&函数名(形参列表及类型说明)函数体&
好处:在内存中不产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。因为随着该局部变量生存期的结束,相应的引用也会失效,产生
注意事项:
()不能返回局部变量的引用。这条可以参照的。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了无所指的引用,程序会进入未知状态。
()不能返回函数内部分配的内存的引用。这条可以参照的。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由分配)就无法释放,造成。
()可以返回类成员的引用,但最好是。这条原则可以参照的。主要原因是当对象的属性是与某种业务规则()相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。
()流操作符重载返回值申明为“引用”的作用:
流操作符和,这两个操作符常常希望被连续使用,例如: 因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括:返回一个流对象和返回一个流对象指针。但是对于返回一个流对象,程序必须重新(拷贝)构造一个新的流对象,也就是说,连续的两个操作符实际上是针对不同对象的!这无法让人接受。对于返回一个流指针则不能连续使用操作符。因此,返回一个流对象引用是惟一选择。这个唯一选择很关键,它说明了引用的重要性以及无可替代性,也许这就是语言中引入引用这个概念的原因吧。赋值操作符。这个操作符象流操作符一样,是可以连续使用的,例如:或者赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。
int&&put(int&n);
int&vals[10];
int&error=-1;
void&main()
put(0)=10;&//以函数值作为左值,等价于
put(9)=20;&//以函数值作为左值,等价于
cout&&vals[0];
cout&&vals[9];
int&&put(int&n)
if&(n&=0&&&&n&=9&)&return&vals[n];
else&{&cout&&&subscript&error&;&return&&}
()在另外的一些操作符中,却千万不能返回引用:四则运算符。它们不能返回引用,的详细的讨论了这个问题。主要原因是这四个操作符没有,因此,它们必须构造一个对象作为返回值,可选的方案包括:返回一个对象、返回一个局部变量的引用,返回一个分配的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则,第、两个方案都被否决了。静态对象的引用又因为会永远为而导致错误。所以可选的只剩下返回一个对象了。
6.&“引用”与多态的关系?
引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。
Class&A;&Class&B&:&Class&A{...};&B&b;&A&&ref&=&b;
7.&“引用”与指针的区别是什么?
指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。此外,就是上面提到的对函数传和的区别。
8.&什么时候需要“引用”?
流操作符和、赋值操作符的返回值、拷贝构造函数的参数、赋值操作符的参数、其它情况都推荐使用引用。
以上&参考:
9.&结构与联合有何区别?
1.&结构和联合都是由多个不同的数据类型成员组成但在任何同一时刻联合中只存放了一个被选中的成员(所有成员共用一块地址空间)而结构的所有成员都存在(不同成员的存放地址不同)。&
2.&对于联合的不同成员赋值将会对其它成员重写原来成员的值就不存在了而对于结构的不同成员赋值是互不影响的。
10.&写出下面关于“联合”的题目的输出?
char&x[2];
void&main()
a.x[0]&=&10;
a.x[1]&=&1;
printf(&%d&,a.i);
答案:低位低地址,高位高地址,内存占用情况是)
union{&/*定义一个联合
struct{&/*在联合中定义一个结构
number.i=0x4241;&/*联合成员赋值
printf(&%c%c\n&,&number.half.first,&mumber.half.second);
number.half.first='a';&/*联合中结构成员赋值
number.half.second='b';
printf(&%x\n&,&number.i);
答案:&对应是低位;对应是高位)
6261&(number.i和共用一块地址空间)
11.&已知的函数原型:其中是目的字符串,是源字符串。不调用的字符串库函数,请编写函数&。
char&*strcpy(char&*strDest,&const&char&*strSrc)
if&(&strDest&==&NULL&||&strSrc&==&NULL)
return&NULL&;
if&(&strDest&==&strSrc)
return&strDest&;
char&*tempptr&=&strDest&;
while(&(*strDest++&=&*strSrc++)&!=&‘\0’)
return&tempptr&;
12.&已知类定义如下:
class&String
String(const&char&*str&=&NULL);&//&通用构造函数
String(const&String&&another);&//&拷贝构造函数
~&String();&//&析构函数
String&&&operater&=(const&String&&rhs);&//&赋值函数
char&*m_&//&用于保存字符串
尝试写出类的成员函数实现。
String::String(const&char&*str)
if&(&str&==&NULL&)&//strlen在参数为时会抛异常才会有这步判断
m_data&=&new&char[1]&;
m_data[0]&=&'\0'&;
m_data&=&new&char[strlen(str)&+&1];
strcpy(m_data,str);
String::String(const&String&&another)
m_data&=&new&char[strlen(another.m_data)&+&1];
strcpy(m_data,other.m_data);
String&&String::operator&=(const&String&&rhs)
if&(&this&==&&rhs)
return&*this&;
delete&[]m_&//删除原来的数据,新开一块内存
m_data&=&new&char[strlen(rhs.m_data)&+&1];
strcpy(m_data,rhs.m_data);
return&*this&;
String::~String()
delete&[]m_data&;
13.&.h头文件中的的作用?
答:防止该头文件被重复引用。
14.&#与&#的区别?
答:前者是从的路径寻找和引用,而后者是从当前工作路径搜寻并引用。
15.在程序中调用被编译器编译后的函数,为什么要加“”?
首先,作为是语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字声明。例如,如果模块欲引用该模块中定义的全局变量和函数时只需包含模块的头文件即可。这样,模块中调用模块中的函数时,在编译阶段,模块虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块编译生成的目标代码中找到此函数
extern&&C&是连接申明被修饰的变量和函数是按照语言方式编译和连接的来看看中对类似的函数是怎样编译的:
作为一种面向对象的语言,支持函数重载,而过程式语言则不支持。函数被编译后在符号库中的名字与语言的不同。例如,假设某个函数的原型为:
void&foo(&int&x,&int&y&);  
该函数被编译器编译后在符号库中的名字为,而编译器则会产生像之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“”)。
_foo_int_int&这样的名字包含了函数名、函数参数数量及类型信息,就是靠这种机制来实现函数重载的。例如,在中,函数与编译生成的符号是不相同的,后者为。
同样地,中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。
未加声明时的连接方式
假设在中,模块的头文件如下:
//&模块头文件 
#ifndef&MODULE_A_H
#define&MODULE_A_H
int&foo(&int&x,&int&y&);
在模块中引用该函数:
//&模块实现文件 
实际上,在连接阶段,连接器会从模块生成的目标文件中寻找这样的符号!
加声明后的编译和连接方式
加声明后,模块的头文件变为:
//&模块头文件 
#ifndef&MODULE_A_H
#define&MODULE_A_H
extern&&C&&int&foo(&int&x,&int&y&);
在模块的实现文件中仍然调用,其结果是:
()模块编译生成的目标代码时,没有对其名字进行特殊处理,采用了语言的方式;
()连接器在为模块的目标代码寻找调用时,寻找的是未经修改的符号名。
如果在模块中函数声明了为类型,而模块中包含的是,则模块找不到模块中的函数;反之亦然。
所以,可以用一句话概括“”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):实现与及其它语言的混合编程。  
明白了中的设立动机,我们下面来具体分析通常的使用技巧:
extern&&C&的惯用法
()在中引用语言中的函数和变量,在包含语言头文件(假设为)时,需进行下列处理:
extern&&C&
而在语言的头文件中,对其外部函数只能指定为类型,语言中不支持声明,在文件中包含了时会出现编译语法错误。
C++引用函数例子工程中包含的三个文件的源代码如下:
/*&c语言头文件:
#ifndef&C_EXAMPLE_H
#define&C_EXAMPLE_H
extern&int&add(int&x,int&y);
/*&c语言实现文件:
int&add(&int&x,&int&y&)
return&x&+&y;
//&c++实现文件,调用:
extern&&C&
int&main(int&argc,&char*&argv[])
如果调用一个语言编写的时,当包括的头文件或声明接口函数时,应加。
()在中引用语言中的函数和变量时,的头文件需添加,但是在语言中不能直接引用声明了的该头文件,应该仅将文件中将中定义的函数声明为类型。
C引用函数例子工程中包含的三个文件的源代码如下:
//C++头文件&
#ifndef&CPP_EXAMPLE_H
#define&CPP_EXAMPLE_H
extern&&C&&int&add(&int&x,&int&y&);
//C++实现文件&
int&add(&int&x,&int&y&)
return&x&+&y;
/*&C实现文件&
/*&这样会编译出错:#
extern&int&add(&int&x,&int&y&);
int&main(&int&argc,&char*&argv[]&)
add(&2,&3&);
15题目的解答请参考《中“”含义深层探索》注解。
16.&关联、聚合以及组合的区别?
涉及到中的一些概念:关联是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;聚合表示的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表示聚合关系:
从实现的角度讲,聚合可以表示为
class&A&{...}&class&B&{&A*&a;&.....}
而组合表示的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系:
实现的形式是
class&A{...}&class&B{&A&a;&...}
参考文章:
&&&&&&&&&&2)&
17.面向对象的三个基本特征,并简单叙述之?
1.&封装:将客观事物抽象成类,每个类对自身的数据和方法实行
2.&继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合接口继承以及纯虚函数)构成了功能复用的两种方式。
3.&多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
18.&重载(和重写,有的书也叫做“覆盖”)的区别?
常考的题目。从定义上来说:
重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
重写:是指子类重新定义复类虚函数的方法。
从实现原理上来说:
重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:和。那么编译器做过修饰后的函数名称可能是这样的:、。对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!
重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。
19.&多态的作用?
主要是两个:
隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。
20.&Ado与的相同与不同?
除了“能够让应用程序处理存储于中的数据“这一基本相似点外,两者没有太多共同之处。但是使用接口并基于微软的技术,而拥有自己的接口并且基于微软的体系架构。众所周知体系不同于体系,接口也就完全不同于和接口,这也就是说和是两种数据访问方式。提供对的支持。
21.&new&delete&与的联系与区别
答案:都是在堆上进行动态的内存操作。用函数需要指定内存分配的字节数并且不能初始化对象,会自动调用对象的构造函数。会调用对象的,而不会调用对象的
22.&#define&DOUBLE(x)&x+x&,;&是多少?
答案:为。
23.&有哪几种情况只能用而不能用
答案:当类中含有、成员变量;基类的构造函数都需要初始化表。
24.&C++是不是类型安全的?
答案:不是。两个不同类型的指针之间可以强制转换(用。是类型安全的。
25.&main&函数执行以前,还会执行什么代码?
答案:全局对象的构造函数会在函数之前执行。
26.&描述内存分配方式以及它们的区别
1)&从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,变量。
2)&在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3)&从堆上分配,亦称动态内存分配。程序在运行的时候用或申请任意多少的内存,程序员自己负责在何时用或释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
27.struct&和&的区别
答案:的成员默认是公有的,而类的成员默认是私有的。和&在其他方面是功能相当的。
从感情上讲,大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的)时,你也许应该使用&关键字,否则,你应该使用&关键字。&
28.当一个类中没有声明任何成员变量与成员函数这时的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。()
答案:肯定不是零。举个反例,如果是零的话,声明一个对象数组,而每一个对象占用的空间是零,这时就没办法区分…了。
29.&在汇编下,逻辑地址和物理地址是怎样转换的?()
答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址通用寄存器内地址,就得到了真正要访问的地址。
30.&比较中的种类型转换方式?
重点是和的区别和应用。
31.分别写出指针类型的变量与“零”的比较语句。
BOOL&:&if&(&!a&)&or&if(a)
int&:&if&(&a&==&0)
float&:&const&EXPRESSION&EXP&=&0.000001
if&(&a&&&EXP&&&&a&&-EXP)
pointer&:&if&(&a&!=&NULL)&or&if(a&==&NULL)
32.请说出与相比,有何优点?
答案:)&常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
2)&有些集成化的调试工具可以对常量进行调试,但是不能对宏常量进行调试。
33.简述数组与指针的区别?
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
(1)修改内容上的差别
char&a[]&=&“hello”;
a[0]&=&‘X’;
char&*p&=&“”注意指向常量字符串
p[0]&=&‘’编译器不能发现该错误,运行时错误
(2)&用运算符可以计算出数组的容量(字节数)。为指针得到的是一个指针变量的字节数,而不是所指的内存容量。语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
char&a[]&=&&hello&world&;
char&*p&=&a;
cout&&&sizeof(a)&&&&&//&12&字节
cout&&&sizeof(p)&&&&&//&4&字节
计算数组和指针的内存容量
void&Func(char&a[100])
cout&&&sizeof(a)&&&&&//&4&字节而不是字节
34.类成员函数的重载、覆盖和隐藏区别?
a.成员函数被重载的特征:
()相同的范围(在同一个类中);
()函数名字相同;
()参数不同;
()关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
()不同的范围(分别位于派生类与基类);
()函数名字相同;
()参数相同;
()基类函数必须有关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
()如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无关键字,基类的函数将被隐藏(注意别与重载混淆)。
()如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
35.&There&are&two&int&variables:&a&and&b,&don’t&use&“if”,&“?&:”,&“switch”or&other&judgement&statements,&find&out&the&biggest&one&of&the&two&numbers.
36.&如何打印出当前源文件的文件名以及源文件的当前行号?
cout&&&&__FILE__&;
cout&&__LINE__&;
__FILE__和是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。
37.&main&主函数执行完毕后,是否可能会再执行一段代码,给出说明?
答案:可以,可以用注册一个函数,它会在之后执行
void&main(&void&)
String&str(&zhanglin&);
_onexit(&fn1&);
_onexit(&fn2&);
_onexit(&fn3&);
_onexit(&fn4&);
printf(&&This&is&executed&first.\n&&);
printf(&&next.\n&&);
printf(&&executed&&&);
printf(&&is&&&);
printf(&&This&&&);
The&_onexit&function&is&passed&the&address&of&a&function&(func)&to&be&called&when&the&program&terminates&normally.&Successive&calls&to&_onexit&create&a&register&of&functions&that&are&executed&in&LIFO&(last-in-first-out)&order.&The&functions&passed&to&_onexit&cannot&take&parameters.
38.&如何判断一段程序是由编译程序还是由编译程序编译的?
#ifdef&__cplusplus
cout&&&c++&;
cout&&&c&;
39.文件中有一组整数,要求排序后输出到另一个文件中
using&namespace&
void&Order(vector&int&&&data)&//bubble&sort
int&count&=&data.size()&;
int&tag&=&false&;&//&设置是否需要继续冒泡的标志位
for&(&int&i&=&0&;&i&&&count&;&i++)
for&(&int&j&=&0&;&j&&&count&-&i&-&1&;&j++)
if&(&data[j]&&&data[j+1])
tag&=&true&;
int&temp&=&data[j]&;
data[j]&=&data[j+1]&;
data[j+1]&=&temp&;
if&(&!tag&)
void&main(&void&)
vector&int&
ifstream&in(&c:\\data.txt&);
cout&&&file&error!&;
while&(!in.eof())
data.push_back(temp);
in.close();&//关闭输入文件流
Order(data);
ofstream&out(&c:\\result.txt&);
if&(&!out)
cout&&&file&error!&;
for&(&i&=&0&;&i&&&data.size()&;&i++)
out&&data[i]&&&&&;
out.close();&//关闭输出文件流
40.&链表题:一个链表的结点结构
struct&Node
int&data&;
Node&*next&;
typedef&struct&Node&Node&;
(1)已知链表的头结点写一个函数把这个链表逆序&
Node&*&ReverseList(Node&*head)&//链表逆序
if&(&head&==&NULL&||&head-&next&==&NULL&)
Node&*p1&=&head&;
Node&*p2&=&p1-&next&;
Node&*p3&=&p2-&next&;
p1-&next&=&NULL&;
while&(&p3&!=&NULL&)
p2-&next&=&p1&;
p3&=&p3-&next&;
p2-&next&=&p1&;
head&=&p2&;
return&head&;
(2)已知两个链表和各自有序,请把它们合并成一个链表依然有序。保留所有结点,即便大小相同)
Node&*&Merge(Node&*head1&,&Node&*head2)
if&(&head1&==&NULL)
return&head2&;
if&(&head2&==&NULL)
return&head1&;
Node&*head&=&NULL&;
Node&*p1&=&NULL;
Node&*p2&=&NULL;
if&(&head1-&data&&&head2-&data&)
head&=&head1&;
p1&=&head1-&
p2&=&head2&;
head&=&head2&;
p2&=&head2-&next&;
p1&=&head1&;
Node&*pcurrent&=&head&;
while&(&p1&!=&NULL&&&&p2&!=&NULL)
if&(&p1-&data&&=&p2-&data&)
pcurrent-&next&=&p1&;
pcurrent&=&p1&;
p1&=&p1-&next&;
pcurrent-&next&=&p2&;
pcurrent&=&p2&;
p2&=&p2-&next&;
if&(&p1&!=&NULL&)
pcurrent-&next&=&p1&;
if&(&p2&!=&NULL&)
pcurrent-&next&=&p2&;
return&head&;
(3)已知两个链表和各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。&
Node&*&MergeRecursive(Node&*head1&,&Node&*head2)
if&(&head1&==&NULL&)
return&head2&;
if&(&head2&==&NULL)
return&head1&;
Node&*head&=&NULL&;
if&(&head1-&data&&&head2-&data&)
head&=&head1&;
head-&next&=&MergeRecursive(head1-&next,head2);
head&=&head2&;
head-&next&=&MergeRecursive(head1,head2-&next);
return&head&;
41.&分析一下这段程序的输出&
cout&&&default&constructor&&&
cout&&&destructed&&&
B(int&i):data(i)&//B(int)&works&as&a&converter&(&int&-&&instance&of&B)
cout&&&constructed&by&parameter&&&&&&data&&&
B&Play(&B&b)
return&b&;
(1)&results:
int&main(int&argc,&char*&argv[])&constructed&by&parameter&5
{&destructed&B(5)形参析构
B&t1&=&Play(5);&B&t2&=&Play(t1);& &形参析构
return&0;              & 注意顺序!
}&destructed&t1
(2)&results:
int&main(int&argc,&char*&argv[])&constructed&by&parameter&5
{&destructed&B(5)形参析构
B&t1&=&Play(5);&B&t2&=&Play(10);& &
return&0;              &形参析构
}&destructed&t2 注意顺序!
destructed&t1
42.&写一个函数找出一个整数数组中,第二大的数&()
const&int&MINNUMBER&=&-32767&;
int&find_sec_max(&int&data[]&,&int&count)
int&maxnumber&=&data[0]&;
int&sec_max&=&MINNUMBER&;
for&(&int&i&=&1&;&i&&&count&;&i++)
if&(&data[i]&&&maxnumber&)
sec_max&=&maxnumber&;
maxnumber&=&data[i]&;
if&(&data[i]&&&sec_max&)
sec_max&=&data[i]&;
return&sec_max&;
43.&写一个在一个字符串中寻找一个子串第一个位置的函数。
KMP算法效率最好,时间复杂度是O。
44.&多重继承的内存分配问题:
那么的内存结构大致是怎么样的?
这个是的不同的实现其细节可能不同。
如果不考虑有虚函数、虚继承的话就相当简单;否则的话,相当复杂。
可以参考《深入探索对象模型》,或者:
http://blog.csdn.net/wfwd/archive//763797.aspx
45.&如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针)
struct&node&{&char&&node*&}
bool&check(const&node*&head)&{}&//return&false&:&无环;有环
一种()的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
bool&check(const&node*&head)
if(head==NULL)&return&
node&*low=head,&*fast=head-&
while(fast!=NULL&&&&fast-&next!=NULL)
fast=fast-&next-&
if(low==fast)&return&
46、一个学生的信息是:姓名,学号,性别,年龄等信息,用一个链表,把这些学生信息连在一起,&给出一个在些链表中删除学生年龄等于的学生信息。
struct&stu{
char&name[20];
struct&stu&*&
struct&stu&*creatlist(int&n)
//h为头结点,为前一结点,为当前结点
struct&stu&*h,*p,*s;
h&=&(struct&stu&*)malloc(sizeof(struct&stu));
h-&next&=&NULL;
for(i=0;i&n;i++)
s&=&(struct&stu&*)malloc(sizeof(struct&stu));
p-&next&=&s;
printf(&Please&input&the&information&of&the&student:&name&sex&no&age&n&);
scanf(&%s&%c&%d&%d&,s-&name,&s-&sex,&s-&no,&s-&age);
s-&next&=&NULL;
访问固定的内存位置()&
47.&嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为的整型变量的值为。编译器是一个纯粹的编译器。写代码去完成这一任务。
这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换()为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下:&
ptr&=&(int&*)0x67a9;&
*ptr&=&0xaa55;
一个较晦涩的方法是:&
*(int&*&const)(0x67a9)&=&0xaa55;
即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。
48.&中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准支持中断。具代表事实是,产生了一个新的关键字。下面的代码就使用了关键字去定义了一个中断服务子程序,请评论一下这段代码的。
__interrupt&double&compute_area&(double&radius)&
double&area&=&PI&*&radius&*&&
printf(&&Area&=&%f&,&area);&
这个函数有太多的错误了,以至让人不知从何说起了:&
1).&ISR&不能返回一个值。如果你不懂这个,那么你不会被雇用的。&
2).&ISR&不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。&
3).&在许多的处理器编译器中,浮点一般都是不可重入的。有些处理器编译器需要让额处的寄存器入栈,有些处理器编译器就是不允许在中做浮点运算。此外,应该是短而有效率的,在中做浮点运算是不明智的。&
4).&与第三点一脉相承,经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。
代码例子()
49&.&下面的代码输出是什么,为什么?
void&foo(void)&
unsigned&int&a&=&6;&
int&b&=&-20;&
(a+b&&&6)&puts(&&&6&)&:&puts(&&=&6&);&
这个问题测试你是否懂得语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是“”。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。&因此变成了一个非常大的正整数,所以该表达式计算出的结果大于。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。
50.&评价下面的代码片断:
unsigned&int&zero&=&0;&
unsigned&int&compzero&=&0xFFFF;&
对于一个型不是位的处理器为说,上面的代码是不正确的。应编写如下:
unsigned&int&compzero&=&~0;
这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里,好的嵌入式程序员非常准确地明白硬件的细节和它的局限,然而机程序往往把硬件作为一个无法避免的烦恼。&
到了这个阶段,应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好,那么这个测试就在这里结束了。但如果显然应试者做得不错,那么我就扔出下面的追加问题,这些问题是比较难的,我想仅仅非常优秀的应试者能做得不错。提出这些问题,我希望更多看到应试者应付问题的方法,而不是答案。不管如何,你就当是这个娱乐吧…
动态内存分配()
51.&尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆()中动态分配内存的过程的。那么嵌入式系统中,动态分配内存可能发生的问题是什么?
这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。这个主题已经在杂志中被广泛地讨论过了(主要是&他的解释远远超过我这里能提到的任何解释),所有回过头看一下这些杂志吧!让应试者进入一种虚假的安全感觉后,我拿出这么一个小节目:下面的代码片段的输出是什么,为什么?
if&((ptr&=&(char&*)malloc(0))&==&NULL)&
puts(&Got&a&null&pointer&);&
puts(&Got&a&valid&pointer&);&
这是一个有趣的问题。最近在我的一个同事不经意把值传给了函数,得到了一个合法的指针之后,我才想到这个问题。这就是上面的代码,该代码的输出是“”。我用这个来开始讨论这样的一问题,看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要,但解决问题的方法和你做决定的基本原理更重要些。
52.&Typedef&在语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子:&
#define&dPS&struct&s&*&
typedef&struct&s&*&tPS;&
以上两种情况的意图都是要定义和&作为一个指向结构指针。哪种方法更好呢?(如果有的话)为什么?&
这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:更好。思考下面的例子:&
dPS&p1,p2;&
tPS&p3,p4;
第一个扩展为&
struct&s&*&p1,&p2;
上面的代码定义为一个指向结构的指,为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了和两个指针。
晦涩的语法
53.&C语言同意一些令人震惊的结构下面的结构是合法的吗,如果是它做些什么?&
int&a&=&5,&b&=&7,&c;&
c&=&a+++b;
这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成:&
c&=&a++&+&b;&
因此这段代码持行后。&
如果你知道答案,或猜出正确答案,做得好。如果你不知道答案,我也不把这个当作问题。我发现这个问题的最大好处是这是一个关于代码编写风格,代码的可读性,代码的可修改性的好的话题
What&will&print&out?&
char&*p1=“name”;&
char&*p2;&
p2=(char*)malloc(20);&
memset&(p2,&0,&20);&
while(*p2++&=&*p1++);&
printf(“%sn”,p2);&
Answer:empty&string.&
What&will&be&printed&as&the&result&of&the&operation&below:
int&x=20,y=35;&
x=y++&+&x++;&
y=&++y&+&++x;&
printf(“%d%dn”,x,y);&
Answer&:&5794&
What&will&be&printed&as&the&result&of&the&operation&below:
printf(“%d,%d,%dn”,x,x&&&2,x&&2);&
Answer:&5,20,1&
What&will&be&printed&as&the&result&of&the&operation&below:
#define&swap(a,b)&a=a+b;b=a-b;a=a-b;&
void&main()
int&x=5,&y=10;&
swap&(x,y);&
printf(“%d&%dn”,x,y);&
swap2(x,y);&
printf(“%d&%dn”,x,y);&
int&swap2(int&a,&int&b)&
return&0;&
Answer:&10,&5
What&will&be&printed&as&the&result&of&the&operation&below:
char&*ptr&=&”&Cisco&Systems”;&
*ptr++;&printf(“%sn”,ptr);&
ptr++;&
printf(“%sn”,ptr);&
Answer:Cisco&Systems
isco&systems&
What&will&be&printed&as&the&result&of&the&operation&below:
char&s1[]=“Cisco”;&
char&s2[]=&“systems”;&
printf(“%s”,s1);&
Answer:&Cisco&
What&will&be&printed&as&the&result&of&the&operation&below:
char&*p1;&
char&*p2;&
p1=(char&*)malloc(25);&
p2=(char&*)malloc(25);&
strcpy(p1,”Cisco”);&
strcpy(p2,“systems”);&
strcat(p1,p2);&
printf(“%s”,p1);&
Answer:&Ciscosystems&
The&following&variable&is&available&in&file1.c,&who&can&access&it?:
static&int&
Answer:&all&the&functions&in&the&file1.c&can&access&the&variable.&
WHat&will&be&the&result&of&the&following&code?
#define&TRUE&0&//&some&code&
while(TRUE)&
//&some&code&
Answer:&This&will&not&go&into&the&loop&as&TRUE&is&defined&as&0.&
What&will&be&printed&as&the&result&of&the&operation&below:
int&modifyvalue()&
return(x+=10);&
int&changevalue(int&x)&
return(x+=1);&
void&main()
int&x=10;&
x++;&
changevalue(x);&
x++;&
modifyvalue();&
printf(&First&output:%dn&,x);&
x++;&
changevalue(x);&
printf(&Second&output:%dn&,x);&
modifyvalue();&
printf(&Third&output:%dn&,x);&
Answer:&12&,&13&,&13&
What&will&be&printed&as&the&result&of&the&operation&below:
int&x=10,&y=15;&
x&=&x++;&
y&=&++y;&
printf(“%d&%dn”,x,y);&
Answer:&11,&16&
What&will&be&printed&as&the&result&of&the&operation&below:
printf(“Cisco&Systemsn”);&
printf(“Cisco&Systemsn”);&
Answer:&Two&lines&with&“Cisco&Systems”&will&be&printed.&
/*****************************************************************************/
1.&多态类中的虚函数表是,还是时建立的
2.将一个&的文件,逆序存储到另一个文件,就是前一个文件的最后一个&
字符存到新文件的第一个字符,以此类推。
3.main主函数执行完毕后,是否可能会再执行一段代码
4.一个父类写了一个函数,如果子类覆盖它的函数不加也能实现多态
在子类的空间里,有没有父类的这个函数,或者父类的私有变量
5.给一个字符串、例如&“”要求返回“”因为“”连续重复出现且最长。
&&用++语言写一函数完成该算法,给出复杂度
6.对序列、、、、、、。。。。&&是数列
&&2、、、是质数数列,因为他们与自己前面的数列都互质
给出,返回第小的质数
7.101个硬币真、假,真假区别在于重量。请用无砝码天平称两次给出真币重还是假币重的结论。
8.完成字符串拷贝可以使用&、及&函数,请问这些函数有什么区别,你喜欢使用哪个,为什么?
9.变量的声明和定义有什么区别?
10.请写出下面代码在&位平台上的运行结果,并说明&的性质:
#include&&stdio.h&
#include&&stdlib.h&
int&main(void)
&&&&&&&&char&a[30];
&&&&&&&&char&*b&=&(char&*)malloc(20&*&sizeof(char));
&&&&&&&&printf(&%d\n&,&sizeof(a));
&&&&&&&&printf(&%d\n&,&sizeof(b));
&&&&&&&&printf(&%d\n&,&sizeof(a[3]));
&&&&&&&&printf(&%d\n&,&sizeof(b+3));
&&&&&&&&printf(&%d\n&,&sizeof(*(b+4)));
&&&&&&&&return&0&;
12.请完成以下题目。注意,请勿直接调用&函数库中的函数实现。
&&&a)请编写一个&函数,该函数给出一个字节中被置&的位的个数,并请
&&&&&给出该题的至少一个不同解法。
&&&b)请编写一个&函数,该函数将给定的一个字符串转换成整数。
&&&c)请编写一个&函数,该函数将给定的一个整数转换成字符串。
&&&d)请编写一个&函数,该函数将一个字符串逆序。
&&&e)请编写一个&函数,该函数在给定的内存区域搜索给定的字符,并返回
&&&&&该字符所在位置索引值。
&&&f)请编写一个&函数,该函数在一个字符串中找到可能的最长的子字符串,
&&&&&该字符串是由同一字符组成的。
给出演示上述函数功能的一个简单程序,并请编写对应的&文件
13.我们需要编写一个图形相关的应用程序,需要处理大量图形信息,
图形有矩形,正方形,圆形&等种类,应用
需要计算这些图形的面积,并且可能需要在某个设备上进行显示使用在标准
输出上打印信息的方式做为示意。
&&&&a)请用面向对象的方法对以上应用进行设计,编写可能需要的类
&&&&b)请给出实现以上应用功能的示例性代码,从某处获取图形信息,
&&&&&&并且进行计算和绘制
&&&&c)如果你的继承自,请给出理由,如果不是,
&&&&&&请给出理由,并且请比较两种方式的优劣
&&&&d)请问你所编写的类,在如下代码中会有何表现,请解释
&&&&void&test_rectangle_area(Rectangle&&r)
&&&&&&&&r.set_width(10);
&&&&&&&&r.set_height(15);
&&&&&&&&assert(r.area()&==&150);
14.假设现有一个单向的链表,但是只知道只有一个指向该节点的指针,并且假设这个节点不是尾节点,试编程实现删除此节点。
15.写一个程序,把一个以内的自然数分解因数。(自然数分解因数就是将一个自然数分解为几个素数的乘积,提示由于该数不是很大所以可以将质数保存在数组中以加快计算速度
16.编写一个的分配、释放的函数,为-之间的自然数。
17.分别实现和
18.Consider&the&following&code:
#include&&stdio.h&
#include&&string.h&
int&main(int&argc,&char&*argv[])&{
int&i&=&1;
char&buf[4];
strcpy(buf,&&AAAA&);
printf(&%d\n&,&i);
a)&When&compiled&and&executed&on&x86,&why&does&this&program&usually&not&
output&what&the&programmer&intended?
b)&Name&several&ways&in&which&the&security&problem&that&causes&this&
program&not&to&output&what&the&programmer&intended&can&be&prevented&
WITHOUT&changing&the&code.
19.&说出结果
int&w=1,x=2,y=3,z=4;
m=(w&x)?w:x;
m=(m&y)?m:y;
m=(m&2)?m:z;
printf(&m=%d&,m);&
20.说出结果
#include&&stdio.h&
&&&&FILE&*
&&&&int&i,a[4]={1,2,3,4},b;
&&&&fp=fopen(&data.dat&,&wb&);//这里帮忙解释一下
&&&&for(i=0;i&4;i++)
&&&&fwrite(&a[i],sizeof(int),1,fp);//这里也帮忙看一下
&&&&fclose(fp);
&&&&fp=fopen(&data.dat&,&rb&);
&&&&fseek(fp,-2L*sizeof(int),SEEK_END);//还有这里
&&&&fread(&b,sizeof(int),1,fp);//这里还有也看一下
&&&&fclose(fp);
&&&&printf(&b=%d\n&,b);&
21.有双向循环链表结点:
typedef&struct&node
&&struct&node&*front,*
有两个双向循环链表,,知道其头指针为:,请写一函数将两上链表中值相同的结点删除
char&*&GetStr()
tmp&=&&123&
void&main()
printf(&%s&,&GetStr());
会输出吗?创建在堆上还是栈上呢?的空间是什么时候释放的?
23.字符指针、浮点数指针、以及函数指针这三种类型的变量哪个占用的内存最大?为什么?&
类从派生,那么…试问该表达是否合法?为什么?
如果中定义并实现虚函数,中也实现该函数,那么上述变量将调用哪个类里面的函数?如果不是虚函数,情况又如何?为什么?
char&**p,&a[16][8];&&问:是否会导致程序在以后出现问题?为什么?
如下所述的和语句哪个的效率高?为什么?
在同一个进程中,一个模块是否可以通过指针操作破坏其它模块的内存,为什么?
应用程序在运行时的内存包括代码区和数据区,其中数据区又包括哪些部分?
24.Assignment&2:&Picture&Processing
Use&C++,&Java,&or&similar&languages&or/and&any&middleware&such&as&EJB&and&J2EE&to&process&a&&picture&with&a&high&resolution&(3&Mega&Pixels&for&example).&Use&some&methodologies&to&degrade&&the&resolution&of&the&picture&to&make&it&quicker&for&browsing.&Then&divide&the&degraded&&picture&into&9&sectors&equally.&Click&any&of&the&9&sectors&will&result&a&detailed&picture&for&&this&sector&with&the&same&resolution&as&that&of&the&original&picture.&This&assignment&is&&designed&for&you&to&demonstrate&your&ability&to&handle&pictures.&
25.用实现一个个字节的高低位交换
26.要开辟内存来做缓冲大小自定但这四个缓冲的大小要一样并且是连续的
27.有一浮点型数组用语言写一函数实现对浮点数组进行降序排序并输出结果要求要以数组作为函数的入口建议用冒泡排序法
#include&&string.h&
#include&&stdio.h&
class&Base
Base(char&*&className)
name&=&new&char[strlen(className)];
strcpy(name,&className);
char&*&copyName()
char&newname&[256];
strcpy(newname,&name);
char&*&getName()
static&void&print(Base&base)
printf(&name:&%s\n&&,&base.name);
class&Subclass&:&public&Base
Subclass(char&*&className)&:&Base(className)
int&main()
Base&*&pBase&=&new&Subclass(&test&);
Base::print(*pBase);
printf(&name:&%s\n&,&pBase-&getName());
printf(&new&name:&%s\n&,&pBase-&copyName());
29.编写一个函数,函数接收一个字符串是由十六进制数组成的一组字符串函数的功能是把接到的这组字符串转换成十进制数字并将十进制数字返回
30.编写一个函数将一条字符串分成两部分,将前半部分按码升序排序,后半部分不变,(如果字符串是奇数则中间的字符不变,)最后再将前后两部分交换,然后将该字符串输出,测试字符串“”
Void&test1()
&&&&char&string[10];
&&&&char*&str1=&&;
strcpy(string,&str1);
Void&test2()
&&&&char&string[10],&str1[10];
for(I=0;&I&10;I++)
&&&&&&&&str1[i]&='a';
strcpy(string,&str1);
Void&test3(char*&str1)
&&&&char&string[10];
&&&&if(strlen(str1)&=10)
&&&&strcpy(string,&str1);
32.&&&&找错
#define&MAX_SRM&256
DSN&get_SRM_no()
&&&&&&&&static&int&SRM_
&&&&&&&&int&I;
&&&&&&&&for(I=0;I{
SRM_no&%=&MAX_SRM;
if(MY_SRM.state==IDLE)
if(I&=MAX_SRM)
return&(NULL_SRM);
return&SRM_
33.&&&&写出程序运行结果
int&sum(int&a)
&&&&&&&&auto&int&c=0;
&&&&&&&&static&int&b=3;
return(a+b+C);
void&main()
&&&&&&&&int&I;
for(I=0;I&5;I++)
&&&&printf(&%d,&,&sum(a));
int&func(int&a)
&&&&int&b;
&&&&switch(a)
&&&&&&&&case&1:&30;
&&&&&&&&case&2:&20;
&&&&&&&&case&3:&16;
&&&&&&&&default:&0
a[0]=0;&a[1]=1;&a[2]=2;
int&*p,&*q;
36.&定义&则变量占有的内存空间为:
37.编写一个函数,要求输入年月日时分秒,输出该年月日时分秒的下一秒。如输入年月日时分秒,则输出年月日时分秒。
38.写一个函数,判断一个型的整数是否是的幂,即是否可以表示成的形式(不可以用循环)
我只知道是用递推,大概写了一下,如下:
int&IsTwoPow(int&s)
&&if(s==1)return&FALSE;
&&if(s&1)IsTwoPow(s);
&&return&(s==1)?TRUE:FALSE;//大概是这个意思,但是这一句似乎不该这么返回!
39&A,从一堆玻璃球(共个)里向外拿球,规则如下:
&&(1)A先拿,然后一人一次交替着拿;
()每次只能拿个或个或个;
()谁拿最后一个球,谁就是最后的失败者;
&&问,谁将是失败者?写出你的判断步骤。
40.已知:无序数组,折半查找,各元素值唯一。
函数原型是:
array是数组,在里面用折半查找的方法找等于的值,找到返回否则,是元素个数
41.统计一个字符串中字符出现的次数
42.100位以上的超大整数的加法(主要考虑数据结构和加法的实现)。
43.对如下电文:给出编码。
44.int&(*&(*f)(int,&int))(int)表示什么含义?
45.x=x+1,,,为这三个语句的效率排序。并说明为什么。
46.中缀表达式&的后缀形式是什么?
47.struct&S1
sizeof(S1)&=&?
virtual&~X();
void&myMemberFunc();
static&void&myStaticFunc();
virtual&void&myVirtualFunc();
sizeof(X)&=&?
48.找出两个字符串中最大子字符串如的最大子串为
49.有一百个整数其中有负数找出连续三个数之和最大的部分
50.写一程序实现快速排序假设数据输入为一文件
快速算法描述如下&
Algorithm&Partition&
Input:&sequence&a0,&...,&an-1&with&n&elements&
Output:&permutation&of&the&sequence&such&that&all&elements&a0,&...,&aj&are&less&than&or&equal&to&all
elements&ai,&...,&an-1&(i&&&j)&
choose&the&element&in&the&middle&of&the&sequence&as&comparison&element&x&
let&i&=&0&and&j&=&n-1&
&&&&search&the&first&element&ai&which&is&greater&than&or&equal&to&x&
&&&&search&the&last&element&aj&which&is&less&than&or&equal&to&x&
&&&&if&ij&
&&&&exchange&ai&and&aj&
&&&&let&i&=&i+1&and&j&=&j-1&
After&partitioning&the&sequence,&Quicksort&treats&the&two&parts&recursively&by&the&same&procedure.
The&recursion&ends&whenever&a&part&consists&of&one&element&only.&
51.写一算法检测单向链表中是否存在环
要求算法复杂度是并只使用常数空间
注意,你只知道一个指向单向链表头的指针。链表的长度是不定的,而且环出现的地方也是不定的,环有可能在头,有可能在中间。而且要求是检测不能破坏环的结构
52.设下列函数已经通过了调试
bool&Sort_Array(ArrayType&*&Pinputarray,&ArrayType&*&Poutarray);
该函数在内存中排序,能把字节数最大为字节的类型的数组排序。其中是一个
预定义的数组类型(细节无关紧要),,分别为排序前的指针和排序后的指针。
请用语言的伪码风格设计一个算法,他调用上面给出的函数完成下列从输入到输出的任务:
输入:排序前的大文件,名称为,其内容为用分号分隔的类型的数组元素,可装满个字节的数组。
输出:排序后的大文件。
53.用最有效率的方法算出乘以等於几?
1.错误的转义字符是&c&
C.'\0'&D.'\''
2.若数组名作实参而指针变量作形参,函数调用实参传给形参的是&d&
A.数组的长度&数组第一个元素的值
C.数组所有元素的值&数组第一个元素的地址
3.变量的指针含意是指变量的&b&
A.值&地址
C.存储&名字
5.某文件中定义的静态全局变量或称静态外部变量其作用域是&d&
A.只限某个函数&本文件
C.跨文件&不限制作用域
1.&解二次方程
int&Quadratic(&double&a,double&b,double&c,double&&x1,double&&x2);
返回值:解的个数
2.&最大公约数
DWORD&Divisor(&DWORD&dwFirst,&DWORD&dwSecond&);
返回值:最大公约数
3.&根据蒙特卡洛算法计算圆周率
double&PI(&DOWRD&dwCount/*测试次数;
返回值:
4.&无符号整数乘法,乘数为,结果为
提示:整数分解为相乘
void&Multiply(&DWORD&dwFirst,&DWORD&dwSecond,&DWORD&&dwHigh,&DWORD&&dwLower&);
5.&链表排序从小到大
节点定义为:
struct&Node{
&&struct&Node*&pN
最后一个节点的
Node*&SortChain(&Node*&pHead&);
返回值:链表头
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:579451次
积分:5210
积分:5210
排名:第4481名
转载:282篇
评论:45条
(7)(1)(2)(30)(10)(7)(11)(34)(24)(2)(5)(4)(2)(10)(3)(1)(2)(12)(23)(12)(5)(16)(30)(12)(1)(9)(6)(2)

我要回帖

更多关于 archive name 的文章

 

随机推荐