C&&C++问题总汇(1)

C&&C++问题总汇🙄

二维数组

定义一个二维数组如下:

1
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };

如果采用一个指针去指向这个数组,可以这么做:

1
int (*p)[4]=a; //4代表了一行有多少个元素

其中*p要加括号,因为不加括号就是指针数组,而且但是,这时候的*p(p指针指向的数据不在是一个int的数,而是一个数组,代表的是第i行的所有元素)

1
2
sizeof(*p);
Output: 16

那么访问这个二维数组的指针方法是:

1
a[i][j]=*(*(p+i)+j);

当然,下面这种方式也对(和一维数组的指针一样)

1
a[i][j]=p[i][j];

Y7D20b8621AY6CYryYagUED1

  • 指针数组是这样子的吗?
1
char *strs[3] ={"chinese","zhonguo" } ;//3代表两个string元素,一个'\0'

这里使用的就是指针数组,所以这里是3(数组中元素的个数+1),而上面的那个是4数组个每个元素的下一级个数。

二维数组赋值的问题

  • 二维数组有两个维度,当然可以按照一个一个去赋值,但那样毕竟太慢,所以有没有更好的赋值方法呢?
1
2
3
4
5
6
int q[4];
for(int i = 0;i<4;i++){

cin>>q[i];
}
int b1[][2]={{q[0],q[1]},{q[3],q[4]}};

这是我现在使用的方法,并不是十分的好,希望有所改进

  • 友元函数访问私有成员问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//习题5-18

//报错,a[2][2]是私有成员,不可在operator中访问
#include<iostream>
using namespace std;
class List{
public:
List(int i,int j,int k ,int m){
a[0][0]=i,a[0][1]=j,a[1][0]=k,a[1][1]=m;
}
List(int (*p)[2]){
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
a[i][j]=p[i][j];
}
}
}
List(){
}
friend operator+(List &a,List &b);
friend operator-(List &a,List &b);
void disp(){
cout<<a[0][0]<<" "<<a[0][1]<<endl;
cout<<a[1][0]<<" "<<a[1][1]<<endl;

}
private:
int a[2][2];
};
List operator+(List a,List b){
int c[2][2];
for(int i=0;i<2; i++){
for(int j=0;j<2;j++){
c[i][j]=a.a[i][j]+b.a[i][j];
}
}
return List(c);
}
List operator-(List &a,List &b){
int c[2][2];
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
c[i][j]=a.a[i][j]-b.a[i][j];
}
}
return List(c);
}
int main(){
List a(1,2,3,4);

int q[4];
for(int i = 0;i<4;i++){

cin>>q[i];
}
int b1[][2]={{q[0],q[1]},{q[3],q[4]}};
List b(b1);
List c;
c = a+b;
c.disp();
return 0;
}

指针的指针

1
2
3
4
5
6
7
8
9
int **p;
//使用方法
int **p; //定义一个指针的指针
int *q; //定义一个int型的指针
int a[3]={1,2,3};
q = a; //q指向a
p =&q; //p指向q
printf("%d",*(*p+1)); //所以*p展现了q,*(*p)为q展现自己储存的地址的内容
return 0;
  • 所以说,这个int有用吗?
1
*((int *)a+n*i+j);  
  • 函数的分号问题
1
2
3
4
5
6
7
T sum(){
.....
}

T sum(){
.....
}; //这个分号是否有必要?
  • 答:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//为什么Base和Derived的虚函数地址一样呢 
#include<iostream>
using namespace std;
class Base{
public:
virtual void func(){
};
virtual void func1(){
}
};
class Derived: public Base{
public:
virtual void fun(){
};
virtual void func1(){
};
};

int main(){
Derived d;
if (d.Base::_vptr==d._vptr){
cout<<"yes"<<endl; //显示yes
}
return 0;
}
  • 问:Base中的虚函数和Derived的虚函数的地址为什么是一样的呢

  • 答:

虚表指针指向了一个虚表,虚表中存放着类中的虚函数。如果类中存在虚函数,那么构造对象的时候,就会生一个虚表指针指向虚表,虚表中存放虚函数。所以,要注意的一-点, 在类的构造函数中不要调用虚函数,这是一一个危险的动作,因为很可能它还未 初始化完毕。

  • 问:动态联编和静态联编,可以访问派生类函数
  • 答:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;
class A{
public:
void print(){
cout<<"1,2,3";
}
};
class B:public A{
public:
void print1(){
cout<<"4,5,6";
}
};
int main(){
A *ptr;
B a1;
ptr =&a1;
ptr->print1(); //can't called
return 0;
}
  • 问:不能调用派生类函数
  • 答:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
using namespace std;
class Base{
public:
void func4(){
cout<<"nihao";
}
};
class Derived:public Base{
public:
void func4(){
cout<<" nihao!";
}
};
int main(){
Base d1, *bp;
Derived d2;
bp=&d2;
bp->func4(); //这里直接调用了Base里面的func4(),这个算重载吗?
}
  • 问:这个可以算重载嘛?,结果值为第一个
  • 答:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
using namespace std;
class Length{
int meter;
public:
Length(int m){
meter = m;
}
operator double(){
return (1*meter/1000); //这个地方一定要使用1.0,否者强制转化会导致结果出错
}
};
int main(){
Length a(1500);
double m =float(a);
cout<<"m="<<m<<"km"<<endl;
return 0;
}

注意:这里Length返回值只能是1.0,不能是1,否者将会不准确。