1
for (int i=0; i <10; i++)
{
printf("%d/n",i);
scanf("%c",&a);
}
想控制输入10个字符,为什么循环两次才运行一次scanf()?
有一次循环是处理回车这个字符的
前面输入的换行符也被当做输入了
for (int i=0; i <10; i++)
{
printf("%d/n",i);
fflush(stdin); //当输入是用来清空缓冲!输出是用来写入!
scanf("%c",&a);
}
在第一次执行scanf的时候,你输入一个字符,按一下回车。
于是,输入缓存区中,有了两个字符: 一个是你输入的,一个是换行符。
而此时,scanf("%c")只取走了第一个字符。
当第二次运行scanf的时候,它发现,缓存区中,还有一个“回车”,于是,它就直接拿来用了。
2 std:string如何实现与LPTSTR的相互转换
string str="fdsjl";
LPSTR str1=str.c_str();
LPTSTR lp=_T("ddd");
char *a=new char[10];
WideCharToMultiByte(CP_OEMCP,NULL,lp,-1,a,6,NULL,FALSE);
string str(a);
先转化成char* 然后再转换成string
3 关于输入结束
输入缓冲是行缓冲。当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin.get() 就会检测输入缓冲区中是否有了可读的数据。cin.get() 还会对键盘上是否有作为流结束标志的 Ctrl+Z 或者 Ctrl+D 键按下作出检查,其检查的方式有两种:阻塞式以及非阻塞式。
阻塞式检查方式指的是只有在回车键按下之后才对此前是否有 Ctrl+Z 组合键按下进行检查,非阻塞式样指的是按下 Ctrl+D 之后立即响应的方式。如果在按 Ctrl+D 之前已经从键盘输入了字符,则 Ctrl+D的作用就相当于回车,即把这些字符送到输入缓冲区供读取使用,此时Ctrl+D不再起流结束符的作用。如果按 Ctrl+D 之前没有任何键盘输入,则 Ctrl+D 就是流结束的信号。
Windows系统中一般采用阻塞式检查 Ctrl+Z、Unix/Linux系统下一般采用非阻塞式的检查 Ctrl+D。楼主是在Windows系统下,因此使用阻塞式的 Ctrl+Z 来标识流的结束。
这种阻塞式的方式有一个特点:只有按下回车之后才有可能检测在此之前是否有Ctrl+Z按下。还有一个特点就是:如果输入缓冲区中有可读的数据则不会检测Ctrl+Z(因为有要读的数据,还不能认为到了流的末尾)。还有一点需要知道:Ctrl+Z产生的不是一个普通的ASCII码值,也就是说它产生的不是一个字符,所以不会跟其它从键盘上输入的字符一样能够存放在输入缓冲区。明白了这几点之后就可以来解释楼主提出的问题了。
从键盘上输入abcd^z 加 回车之后在Windows系统上是这样处理的:由于回车的作用,前面的 abcd 等字符被送到输入缓冲区(注意:上面说过了,^z不会产生字符,所以更不会存储到输入缓冲区,缓冲区中没有 ^z 的存在)。这时,cin.get() 检测到输入缓冲区中已经有数据存在(因此不再检查是否有 ^z 的输入),于是从缓冲中读取相应的数据。如果都读取完了,则输入缓冲区重新变为空,cin.get() 等待新的输入。可见,尽管有 ^z 按下,但是由于在此之前还有其它输入字符(abcd),所以流也不会结束。
因此,输入流结束的条件就是:^z 之前不能有任何字符输入(回车除外),否则 ^z 起不到流结束的作用。
4 对于fstream 如果新建文件,必须以输出方式打开,而且不能加上输入方式!cin默认会略过回车。getchar不会略过回车。将回车读取了
5 常量折叠
就是编译器优化后,在编译时期用常量的具体取值代替所有用到常量的地方, 就是编译优化后,
对于常量数据,
就没有对应的变量存在了,
直接就是操作这个常量数值
比如:
const int X = 5;
那么 Y = 2*X
在优化后是 2*5, 没有这个 X 的存在
比如
//请教下大家
#include <iostream>
using namespace std;
int main()
{
const int i = 0;
int *pi = (int *) &i;
printf("&i=%p pi=%p/n",&i,pi);
//cout < <i < <endl;
*pi = 100;
cout < <i < <endl;
cout < <*pi < <endl;
//&i,pi是一样的,为什么i和*pi的结果不一样
return 0;
}
6 写函数找出一个字符串中出现频率最高的字符(如果最高频率相同的有多个字符,取最先遇见的那个字符)
1 可以利用map函数
2 可以利用哈希原理
char afun(const char *str)
{
int temp[255]={};
char freqChar=0;;
int freqMax=0;
const char *p=str;
while(*p!='/0')
{
temp[*p]++;
if(temp[*p]>freqMax)
{
freqMax=temp[*p];
freqChar=*p;
}
p++;
}
return freqChar;
}
memcpy拷贝块内存,效率会很高
不同的类有不同的虚表,一个类只有一个虚表,该类的所有对象共用 。
7使用LPTSTR要包含windows.h
7 求N的N次方(不用循环)
理解:
N^N=10^(N log(N))
设N*log(N)的整数部分为intpart,分数部分为fractpart,
则N^N = 10^(intpart + fractpart) = 10^intpart * 10^fractpart.
其中10^intpart肯定为10的倍数,不影响结果,可忽略。
所以:
10^fractpart的最高位即为结果。
8 ExitProcess不负责任何对象的析构,exit只负责析构全局对象,return 0可以析构局部对象并调用exit,因此能析构全部对象
9 Note that the preincrement operator (prefix ++) is used here. This is because it might have better
performance than the postincrement operator. The latter involves a temporary object because it
must return the old position of the iterator. For this reason, it generally is best to prefer ++pos
over pos++.
10 因为c++语言标准关于这个问题的阐述非常清楚:当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将是不可确定的。实际运行时经常发生的是,派生类的析构函数永远不会被调用。”
11 有虚函数的类不能调用memset清0,这样会毁掉虚函数表指针的