C++菜鸟记

昨天去腾讯面试了,软件开发岗,跪了。。总结了一点,项目多也没用,关键还是要刷题,手写算法不是开玩笑的。。所以决定老老实实开始刷题,把基础打好。

1:static修饰的变量在类外初始化,const修饰的在参数列表初始化,在构造函数中需要列表初始化的有如下三种:

    带有const修饰的类成员,如const int a;

    引用成员数据,如int &p;

    带有引用的类变量

2:大端模式:数据低位放在内存高位;

    小端模式:数据低位放在内存低位;

3:

class A{
    public:
        long a;
};
class B : public A {
    public:
        long b;
};
void seta(A* data, int idx) {
    data[idx].a = 2;
}
int main(int argc, char *argv[]) {
    B data[4];
    for(int i=0; i<4; ++i){
        data[i].a = 1;
        data[i].b = 1;
        seta(data, i);
    }
    for(int i=0; i<4; ++i){
         std::cout << data[i].a << data[i].b;
    }
    return 0;
}

最后输出结果是22221111

因为类A实例化后占四个字节,类B实例化后占八个字节,执行seta(data, i);时,实参是B类型,形参是A类型,所以data被隐私转化为B类型,因此对index进行加一操作,实际上指针前进四个字节,因此四次循环下来,对data[0].a,data[0].b,data[1].a,data[1].b进行了赋2操作,虽然表面上data[idx].a = 2;像是对每个对象的a进行了赋值。其实这里的data[idx].a只是代表一个地址而已,距离data[0].a偏移4*idx字节的地址。

4:

int ia[3][3]={{1,2,3},{4,5,6},{7,8,9}};

int(*p)[3]=ia;  //p是int(*)[3]型,是一个指向具有三个元素的一维数组指针,其实就是一个行数组指针,p等价于ia,即指向指针的指针,是一个二维指针*p指向二维数组首元素。

p=&ia[2];//p指向了ia的尾行元素

5:

编程语言中的 malloc  calloc 函数和 C++  new 运算符都是在动态存储区( heap )上申请内存空间

6:在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。

7:左值VS右值

通俗讲,左值的定义就是非临时对象,那些可以在多条语句中使用的对象。所有的变量都满足这个定义,在多条代码中都可以使用,都是左值。

右值是指临时的对象,它们只在当前的语句中有效。

例如:int i= 10;//i 是左值,0是临时值所以0是右值,i可以被引用,但是0不可以。

int &r=val+1;是非法的,因为右值无法赋值给左值引用。左值只能赋值给左值引用,右值只能赋值给右值引用。

const int &r=val+1;是合法的,因为C++中临时变量默认是const属性,所以val+1可以传递给const的引用,此时r的地址和val的地址是不一样的。

当然,int &&r=val+1;是合法的,右值赋值给右值引用,此时r的地址和val的地址肯定是不一样的。

string getMem(string &s) {     
       string &rs = s;
       returnrs;
 }
  string s = "helloworld";
  string ss = getMem(s);//正确值传递,用返回值来初始化了ss
  string &rs = getMem(s);//错误,同上,右值,getMem(s)返回的是临时变量,所以是右值;
  const string &rs = getMem(s);//正确,右值用常引用来引用, 

8:

对引用求地址,就是对目标变量求地址。即引用名是目标变量名的一个别名。引用在定义上是说引用不占据任何内存空间,但是编译器在一般将其实现为const指针,即指向位置不可变的指针,所以引用实际上与一般指针同样占用内存。

9:

常量指针:指向的为不可改变的额常量;

指针常量:指针不可改变;

10:

友元类的权限和本类的权限是一样的;

类的常成员函数形式为:void function() const{}    特性:不能修改任何成员变量,只能调用常成员函数;

C++的多态性分为编译时的多态和运行时的多态,编译时的多态通过函数的重载和模板来实现,运行时的多态通过虚函数来实现;

函数模板必须由编译器根据程序员的调用类型实例化为可执行的函数;

类模板的成员函数都是函数模板,没使用过的函数模板不是不会被实例化;

预处理命令不以;结尾,所以一行只能有一个预处理命令;

int (*fun)();//定义了一个指针,该指针为函数指针,指向一个不带形参的函数的指针;

int* fun(int*);//声明了一个函数,该函数形参是int*,返回值是int*;

(int*) fun(int*);//声明了一个函数,该函数形参是int*,返回值强制转化为int*;

类的静态方法只能访问类的静态成员,因为静态成员在类实例化之前就已经存在;

strlen()函数计算到字符春中'\0'为止,不包括'\0',而sizeof()计算参数所占字节,包括'\0';

x&(x-1)是统计1的个数,x|(x+1)是统计0的个数;

11:

int arr[10];
int *p1 = arr;
int *p2 = (int*)&arr;
int (*p3)[10] = &arr;

这里arr的值和&arr的值是一样的,但是意义不同,arr代表数组首元素的地址,而&arr代表数组的地址。指针不能只看地址,还要看指向的元素的类型,p1指向的是int类型的数据,p3的类型是int (*)[10],指向的是带10个元素的行数组,将其强制转化为int*类型,就指向首元素了。

12:

int b;
const int *a=&b;
int const *a=&b;

第二行和第三行代表的意思是一样的,都是指a所指向的数据不能通过a指针来改变;

int *const a=&b;

意思是a只能指向b;

根据const在*的左边还是右边,总结:左定值,右定向。

13:

%m.ns 输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格。

14:


猜你喜欢

转载自blog.csdn.net/qq_30483585/article/details/79886403