C++技巧杂谈
-是"void main()"还是"int main()"?
遵照ANSI/ISO的标准,正确的形式只有两种:
int main() { /* ... */ }
int main(int argc, char* argv[]) { /* ... */ }
即使"void main()"可以被编译的(取决于编译器),这种写法在标准上其实是不对的!
-怎样暂停一个程序?
有多种方法来暂停一个程序,大部分的方法取决于你所使用的操作系统,以及你所使用的编译器。
如果你需要程序来等待用户键入一个值,可以使用:
system("PAUSE");
但这是一种Windows系统调用,不能在非Windows平台上使用。
更一般的用法是:
cin.get(); //等待你输入ENTER
如果你需要程序暂停一段时间,可以使用:
Sleep(1000); //暂停 1000 毫秒。要包含 windows.h 头文件。
-怎样产生彩色文字?
有多种方法,取决于你的编译器:
①Dev-C++ 和 Turbo C++ :
在 conio.h 头文件中定义了:
settextcolor() // 设置文字颜色
settextbackground() //设置文字背景颜色
cprintf() // 设置了颜色后的打印
②VC++ 和 Borland C++ :
void setcolor(unsigned short color)
{
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hCon,color);
}
在这里,要包含 windows.h 头文件。
-结构和类的区别是什么?
类是针对于C++的,而结构是针对于C的,即便你也能在C++中使用结构。而它们之间的唯一区别是:
①在类中,所有的成员在默认情况下是private的。
②在结构中,所有的成员在默认情况下是public的。
-怎样读取和保存一个文件?
这里提供两种非常简单的例子:
读取一个文件:
#include <fstream.h>
int main() {
ifstream OpenFile("myfile.txt");
char ch;
while(!OpenFile.eof()) {
OpenFile >> ch;
cout << ch;
}
return 0;
}
保存一个文件
#include <fstream.h>
int main() {
ofstream SaveFile("file.txt");
SaveFile << "Hello World!";
return 0;
}
-怎样到相应的坐标?
#include <windows.h>
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
-怎样在C++程序中写上ASM代码?
这其实不是一个标准的C++特征,但大部分较流行的编译器会提供相应的机制:
__asm{
...ASM CODE GOES HERE...
}
你同样可以写一个汇编语言的文件,然后编译使它成为一个目标文件,再就可以把它和其它的目标文件链接起来使用。
-setw()怎么工作的?
setw()用来设定最小的域宽。如果你不能明白,运行下面的代码,看看输出就可以了。
int main()
{
cout << setw(4) << "123" << endl;
cout << setw(4) << "23" << endl;
cout << setw(4) << "3" << endl;
return 0;
}
输出:
123
23
3
-怎样看一个字符的ASCII码?
如下:
char a;
a = 'd';
cout << int(a) << endl;
-怎样把一个整型转变为一个字符串?
最简单的方法是使用字符串流:
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
string itos(int i) // 整型转变为字符串
{
stringstream s;
s << i;
return s.str();
}
int main()
{
int i = 127;
string ss = itos(i);
const char* p = ss.c_str();
cout << ss << " " << p << "\n";
}
-怎样把一个字符串转变为一个整型
最简单的方法是使用math.h 和stdlib.h中的atoi()函数:
int atoi( const char *string );
例子:
#include <iostream>
#include <stdlib.h> // getch()
using namespace std;
int main()
{
char str[4]={49,55,57,'\0'};
int number;
number=atoi(str);
cout << number << endl;
return 0;
}
但是atoi()会引起比较多的问题,所以许多有经验的程序员总是在第一时间里放弃对它是使用。它所引起的问题多是句柄方面的错误。另一种选择是使用sscanf()或者stringstreams来将一个C字符串或C++ 字符串的整型值赋给一个整型的变量。
strtol()
作用:将字符串转变为一个长整型值。
函数原型如下:
long strtol( const char *nptr, char **endptr, int base );
参数含义:
nptr- 需要被转换的字符串
endptr- 字符串中被转换部分截止的地方
base- 数值参数
该函数需要包含stdlib.h头文件。
-是"const int"还是"int const"?
这其实只是一种书写风格上的区别。没有什么技术非要你用什么风格。大部分的程序员喜欢使用"const int"书写风格。
-怎样创建头文件?
一个头文件不过是一段文本。你能通过任何一个文本编辑器来创建它。它必须包含宏定义、函数申明、类的申明以及全局变量的申明。
而函数的定义、类的定义以及全局变量的定义必须在一个或多个模块中被编译到目标文件中。
当你需要从一个模块中调用另一个模块时,你只需要包含相应的头文件,并把它相关的目标文件链接到程序中即可。
-怎样使你的输入随输入不断的在屏幕上显示?
#include <iostream>
#include <conio.h> // getch()
using namespace std;
int main()
{
int input;
cout << "Enter number: " ;
while ((input = getch()) != '\r')
putchar(' ');
//现在你的输入都存储在"input"变量中了
return 0;
}
-怎样在ENTER被键入以前读取你已经输入的信息?
#include <iostream>
#include <conio.h> // getch()
using namespace std;
int main()
{
int keyPress;
cout << "Enter a number between 1 and 3: ";
keyPress = getch();
switch (keyPress)
{
case '1':
cout << "You entered one!\n";
break;
case '2':
cout << "You entered two!\n";
break;
case '3':
cout << "You entered three!\n";
break;
default:
cout << "Not a number between 1 and 3!\n";
break;
}
return 0;
}
-怎样键入任意一个键来终结程序?
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
while(!_kbhit())
{
cout << "Press any key to exit" << endl;
}
return 0;
}
-使用typedef和预处理宏的区别是什么?
Typedef和#define都可以用来对已有的数据类型赋予一个新的别名。而问题的出现是当我们对指针这种类型的操作时。
Typedefs在这个时候能做出正确的处理。看下面的例子:
typedef char *string_t;
#define char *string_d
string_t s1,s2;
string_d s3,s4;
在上面的申明中,s1,s2 和 s3都被申明为字符型指针,而s4却被申明为字符,这并不是预期所想得到的结果。
那既然是这样,为什么还要使用预处理宏呢?因为预处理宏的好处是在使用诸如#ifdef时体现出来的。
-为什么这样的路径会提示错误的信息?
fopen("c:\newdir\file.dat", "r");
实际上,在双引号中要表示反斜线,在C++中必须是"\\"。
所以正确的写法是:
fopen("c:\\newdir\\file.dat", "r");
-char s[3] = "cpp"是合法的吗?
其实在ANSI-C中是完全合法的,但仅仅在很少的情况下使用。它申明了一个大小为3的字符数组并初始化为"a","b","c",没有"\0"字符。因此从某种意义上来将它不是一个真正的C字符串,并且不能使用函数strcpy(),%s格式的printf以及其他字符串函数。
但最好的申明是留出额外的空间给字符NULL。
char s[4]= "cpp";
or
char s[]= "cpp";
-怎样得到当前的时间?
#include<stdio.h>
#include<time.h>
main()
{
time_t now;
time(&now);
printf("Its %.24s\n",ctime(&now));
return 0;
}
-怎样在一行里交换两个整型数?
用异或操作符可以做到。
a^ = b^ = a^ = b;
下面是个小例子:
main()
{
int a = 5, b =4;
a^ = b^ = a^ = b;
printf("a = %d b = %d" a,b);
}
-怎样获取磁盘的驱动盘符?
使用_getdrive()函数:
#include<direct.h>
main()
{
int disk;
disk = _getdrive()+ 'A' -1;
printf("The current drive is %c", disk);
}
-在一个程序执行的过程中怎样获取它的名字?
你或许从来就没有要知道正在执行的程序的名字必要。其实正在执行的程序的名字的完整路径都存储在字符串argv[0]中。通过找到其名字的相关信息,你可以使得自己的某种病毒感染该文件,甚至删除它。
#include<stdio.h>
main(int argc,char *argv[])
{
/*
写你所想做的工作。比如利用autoexec.bat或win.ini或其他的文件。
*/
unlink(argv[0]);
}
-memcpy()和memmove()的区别是什么?
其实memcopy 和memmove都可以将内存中的某块中的信息复制到另一区域。当然,也有小的区别。
如果源地址和目标地址有重叠的地方,memcpy并不提供相应的保护机制,而memmove会提供比较全面的保护工作。
另外,memcpy的运行速度要比memmove快。