C与C++的区别

一、三大基本特征:封装、继承、多态

封装:封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。

继承:继承是面向对象的基本特征之一,继承机制允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

多态:多态同一个行为具有多个不同表现形式或形态的能力。是指一个类实例(对象)的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

二、C++与C的区别

C语言是面向过程编程,C++是面向对象编程
1.面向过程编程就是分析出解决问题的步骤,然后把这些步骤一步一步的实现,使用的时候一个一个的依次调用就可以了。
2.面向对象编程就是把问题分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题步骤中的行为。
3.面向过程编程的性能比面向对象高,因为类调用的时候需要实例化,开销比较大,比较消耗资源。但是面向过程却没有面向对象易维护,易复用,易扩展。
4.编程的最终目的就是为了解耦和复用。由于面向对象编程有封装,继承,多态等性质,可以设计出低耦合的系统。

三、C++与Python的区别

PYTHON是一种脚本语言,是解释执行的,不需要经过编译,所以很方便快捷,且能够很好地跨平台,写一些小工具小程序特别合适。
而C++则是一种需要编译后运行语言,在特定的机器上编译后在特定的机上运行,运行效率高,安全稳定。但编译后的程序一般是不跨平台的。

四、判断Struct的字节数

一般使用sizeof判断struct所占的字节数,那么计算规则是什么呢?
关键词:
1.变量的起始地址和变量自身的字节数
2.以最大变量字节数进行字节对齐(倍数关系)。
先举个例子:
struct A
{
char a[5];
int b;
short int c;
}struct A;
在上例中,要计算 sizeof(a) 是多少?有两个原则:1)各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数 即当 A中的a占用了5个字节后,b需要占用四个字节,此时如果b直接放在a后,则b的起始地址是5,不是sizeof(int)的整数倍,所以 需要在a后面补充3个空字节,使得b的起始地址为8. 当放完b后,总空间为5+3+4 = 12. 接着放c,此时为 12 + 2 = 14.
2)为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数, 所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。 这是说A中占用最大空间的类型,就是int型了,占用了4个字节,那么规定A占用的空间必须是4的整数倍。本来计算出来占用的空间为14, 不是4的整数倍,因此需要在最后补充2个字节。最终导致A占用的空间为16个字节。

所以,来来来,下边再举个例子:
struct B
{
char *d;
short int e;
long long f;
char c[1];
}b;

void test2() {
printf("%d\n", sizeof(b));
}
对于此题,需要注意的一点是:windows系统对long long是按照8字节进行对齐的,但是Linux系统对long long则是按照4字节对齐的。

因此: d占用4字节(因为d是指针)

e占用2字节

f占用8字节,但是其起始地址为为6,不是4的整数倍(对于Linux系统),或不是8的整数倍(对于Windows系统),因此对e之后进行字节补齐,在这里不管对于Linux还是Windows都是补充2个字节,因此 f 的起始地址是8,占用8个字节。

对于c,它占用了1个字节,起始地址是16,也是1的整数倍。

最后,在c之后需要对整个B结构体占用的空间进行补齐,目前占用空间是16+1 = 17个字节。

对于Linux,按4字节补齐(long long 是按4字节补齐的),因此补充了3位空字节,最后占用空间是 17 + 3 = 20字节。

对于Windows系统,是按8字节补齐的,因此就补充了7个字节,最后占用的空间是24字节。

五、Static的作用

什么是static?
static 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。
为什么要引入static?
函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。
static的作用
第一个作用是限定作用域(隐藏);第二个作用是保持变量内容持久化;
函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值。
举个例子

#include<iostream>

using namespace std;

int main(){

    for(int i=0; i<10; ++i){
	    int a = 0;
		static int b = 0;
		cout<<"a: "<< a++ <<endl;
		cout<<"b(static): " << b++ <<endl;
	}
	return 0;
}

输出结果:
a: 0
b(static): 0
a: 0
b(static): 1
a: 0
b(static): 2
a: 0
b(static): 3
a: 0
b(static): 4
a: 0
b(static): 5
a: 0
b(static): 6
a: 0
b(static): 7
a: 0
b(static): 8
a: 0
b(static): 9

  • 在模块内的static全局变量可以被模块内所有函数访问,但不能被模块外其他函数访问
  • 在模型内的static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内。
  • 在类中的static成员变量属于整个类所有,对类的所有对象只有一份复制。即类的所有对象访问的static成员变量是同一个,而不是对象专属的。(理解这里,独此一份)
  • 在类中的static成员函数属于整个类所有,这个函数不接收this指针,因而只能访问类的static成员变量。同类的static成员变量性质一样,类的对象访问的static成员函数是同一个,不是对象专属的。
posted @ 2019-11-16 03:38  博博的Blog  阅读(218)  评论(0编辑  收藏  举报