C++的格式转化和C语言不同,
static_cast
)dynamic_cast
)const_cast
)程序示例:
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo() {}
};
class Derived : public Base {
// ...
};
int main() {
// 静态强制类型转换
double myDouble = 3.14;
int myInt = static_cast<int>(myDouble);
cout << "Static Cast: " << myInt << ", Type: " << typeid(myInt).name() << endl;
// C语言旧式强制类型转换
double myOldDouble = 4.56;
int myOldInt = (int)myOldDouble;
cout << "Old-Style Cast: " << myOldInt << ", Type: " << typeid(myOldInt).name() << endl;
// 动态强制类型转换
Base* basePtr = new Derived;
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
cout << "Dynamic Cast: Successful, Type: " << typeid(*derivedPtr).name() << endl;
} else {
cout << "Dynamic Cast: Failed" << endl;
}
// 常量强制类型转换,使用 const_cast 移除 const 修饰符
const int myConstInt = 42;
int* myMutableInt = const_cast<int*>(&myConstInt);
*myMutableInt = 99;
cout << "Const Cast: " << *myMutableInt << ", Type: " << typeid(*myMutableInt).name() << endl;
return 0;
}
按行获取字符串
两者使用scanf都不加&
/***字符数组***/
//输入方式一
char ch[100] = { 0 };
cin.getline(ch, sizeof(ch));
//输入方式二
char ch2[100] = { 0 };
scanf("%s", ch2);//不加&,而%c需要加&
/***字符串***/
//输入方式一
string s1;
getline(cin,s1);
//输入方式二
string s2[100] = { 0 };
scanf("%s", s2);//不加&,而字符串指针需要加&
指针
//字符指针
char str[100]="hello";
char *ptr=str;//不是char *ptr= &str; 并且*ptr指向第一个字符元素h
//字符串指针
string s1="hello";
string *p1=&s1;//不是string *p1=s1; *p代表整个12字符串
char *p2=&s1[0];
cout<<*p1<<endl;
字符串最后一个字符为'\0'
程序示例:
#include <iostream>
using namespace std;
int main() {
/*字符数组*/
//输入方式一
char ch[100] = { 0 };
cin.getline(ch, sizeof(ch));
//字符指针
char *ptr=ch;//不是char *ptr= &ch; 并且*ptr指向第一个字符元素
for(;*ptr!='\0';ptr++){
cout<<*ptr;
}
cout<<endl;
//输入方式二
char ch2[100] = { 0 };
scanf("%s", ch2);//不加&,而%c需要加&
/*字符串*/
//输入方式一
string s1;
getline(cin,s1);
//字符串指针
string *p1=&s1;//不是string *p1=s1; *p代表整个12字符串
cout<<*p1<<endl;
//输入方式二
string s2[100] = { 0 };
scanf("%s", s2);//不加&,而字符串指针需要加&
return 0;
}
按行获取字符串:char *fgets(char *str, int n, FILE *stream);
str
是一个指向字符数组的指针,用于存储读取的字符。n
是要读取的最大字符数(包括终止符 \0
),即字符数组的大小。stream
是文件流指针,指定从哪个文件流中读取字符,通常可以是 stdin
(标准输入)、stdout
(标准输出)等。const int MaxSize=100;
char buffer[MaxSize];
fgets(buffer, sizeof(buffer), stdin);//按行获取字符串
buffer[strcspn(buffer, "\n")] = '\0';//不能是'\n'
程序示例:
#include <stdio.h>
#include <string.h>
int main() {
const int maxSize = 100;
char buffer[maxSize];
printf("Enter a line of text:\n");
fgets(buffer, sizeof(buffer), stdin);//按行获取字符串
buffer[strcspn(buffer,"\n")]='\0';//不能是'\n'
printf("You entered: %s", buffer);
return 0;
}
最好使用
int slen=s.length();
在使用slen.直接使用s.length()造成的问题会很麻烦,
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
getline(cin,s);//hello
cout<<s.length()<<endl;//5
//而使用s1.length报错
return 0;
}
字符串结束标志是'\0',若字符数组是以字符串形式输入,则结束标志也是'\0' 注意:
在C语言,结构体声明和C++不同,见😎3.2 KiKi设计类继承 解决办法:C++中设计结构体不要用typedef
/*C语言*/
typedef struct Shape{
int x,y;
}Shape;
//后续定义才能为 Shape shape;
struct Shape{
int x,y;
};
//后续定义为 struct Shape shape;
/*C++*/
typedef struct Shape{
int x,y;
}Shape;
//这样做导致声明了 Shape为全局变量,可能导致后续Shape类型出现问题
//,所以在C++尽量不要使用typedef
//上述内容等价于
struct Shape {
int x, y;
};
typedef struct Shape Shape;
struct Shape{
int x,y;
};
//后续定义为 struct Shape shape; 或者 Shape shape;
派生类的构造函数,需要保证调用基类的构造【默认调用基类无参构造,如果基类创新提供了新的有参构造,则派生类的构造易出错】,见😎3.3 牛牛的书 解决办法:最好每次提供新的构造函数时都再提供一个无参的默认构造函数。
构造函数的参数最好不要和class 的数据同名,否则需要加上this,不然出错!
#include <iostream>
using namespace std;
class Base {
private:
int x;
int y;
public:
//构造函数
Base(int x, int y) {
this->x = x;//x=x is error
this->y = y;//y=y is error
}
Base(){}
int getX() {
return x;
}
int getY() {
return y;
}
};
int main() {
int x, y;
cin >> x;
cin >> y;
Base base(x,y);
cout<<base.getX()<<" "<<base.getY()<<endl;
return 0;
}
派生类的构造函数调用前需要调用基类的构造函数,并且派生类新增数据需要加this,否则出错。
#include <iostream>
using namespace std;
class Base {
private:
int x;
int y;
public:
//构造函数
Base(int x, int y) {
this->x = x;
this->y = y;
}
Base(){}
int getX() {
return x;
}
int getY() {
return y;
}
};
class Sub : public Base {
private:
int z;
public:
//构造函数
Sub(int a, int b, int c) :Base(a, b) {//继承基类的构造
this->z=z;//必须加this,虽然基类没有z成员
}
Sub():Base(){}
int getZ() {
return z;
}
int calculate() {
return Base::getX()*Base::getY()*this->z;//调用基类数据成员需要加域 Base::
}
};
int main() {
int x, y, z;
cin >> x;
cin >> y;
cin >> z;
Sub sub(x, y, z);
cout << sub.calculate() << endl;
return 0;
}
纯虚函数:
纯虚函数本身在基类中没有具体的实现,而是在派生类中被强制要求实现。
纯虚函数的声明和定义的一般形式如下:
class AbstractBase {
public:
virtual void A() const = 0; // 纯虚函数声明,不是xx(){} const=0;
virtual ~AbstractBase() {} // 虚析构函数
};
注意:
后续派生类实现必须是
class AbstractBase {
public:
virtual void A() const = 0; // 纯虚函数声明,不是xx(){} const=0;
virtual ~AbstractBase() {} // 虚析构函数
};
class B{
public:
virtual void A() const{//virtual可以省略,const不能省略
...
}
...
}
C++使用cout<<进行输出。 添加头文件#include <iomanip> + #include <iostream> 注意
setprecision、fixed
会影响接下来的所有浮点数的输出,直到下个setprecision、fixed
出现为止。setprecision(2)表示精确2位,如 11.235 则输出 11 3.14 输出 3.1
要求精确到小数点后n位,使用cout<<fixed<<setprecision(n)<<value;
/*限定输出格式*/
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double a = 11.2345;
cout << setprecision(2) << a << endl; // 精确输出2个,这里输出11
cout << fixed<<setprecision(2) << a << endl; // 保留2位小数,输出11.23
cout << setw(8) << a << endl; // 控制输出宽度为8,右对齐(默认)
cout << right << setw(8) << a << endl; // 控制输出宽度为8,右对齐
cout << left << setw(8) << a << endl; // 控制输出宽度为8,左对齐
}
/*输出
11
11.23
11.23
11.23
11.23
*/
注意:使用new之后求数组大小
int maxSize;
cin>>maxSize;
int *a=new int[maxSize];
//求动态数组大小
int n=sizeof(a)/sizeof(a[0]);//error! n===0 sizeof(a)===8
int b[5];
int n=sizeof(b)/sizeof(b[0]);//ok
new分配的大小恒等于8
#include <iostream>
using namespace std;
//Array类
class Array{
private:
int n;
int *array;
public:
Array(int *a){
n=sizeof(a)/sizeof(a[0]);
cout<<"n="<<n<<endl;
array=new int[n];
for(int i=0;i<n;i++){
array[i]=a[i];
}
}
Array(){}
~Array(){
delete [] array;
}
};
int main(){
int maxSize;
cin>>maxSize;
int *a=new int[maxSize];
for(int i=0;i<maxSize;i++){
cin>>a[i];
}
int n=sizeof(a)/sizeof(a[0]);
cout<<"n="<<n<<endl;
Array array(a);
return 0;
}
下面的示例,两种输入都正确。
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
int *a=new int[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
delete [] a;
cout<<endl;
}
详见下面的示例
#include <iostream>
using namespace std;
//输出数组
void Disp(int *a,int n){
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}
int main(){
int a[10]={1,0,2,3,6,5,4,7,8,9};
int n=sizeof(a)/sizeof(a[0]);
Disp(a,n);
a={0,1,2,3,4,5,6,7,8,9};//报错,只能在声明+定义时这样初始化
Disp(a,n);
return 0;
}
vector的输入需要注意:详见2.3【C++】STL的基本用法
关于