美文网首页
C++程序设计(北京大学) 23/40

C++程序设计(北京大学) 23/40

作者: 连明堂 | 来源:发表于2018-11-11 23:49 被阅读88次

郭炜

C++语言是特别讲究效率的语言,对效率是锱铢必较的。

01 | 函数指针

函数指针,用来指向变量的地址。有起始地址(入口地址),通过函数指针调用函数体。

函数的名称和函数的指针是匹配的。

函数指针的必要性:可以对任意类型的数组进行排序。

02 | 命令行参数

03 | 位运算

按位与&

1、将某些变量中的某些位“清0”且同时保留其他位不变;也可以用来获取变量中的某一位。

n = n & 0xffffff00;

也可以写成

n&= 0xffffff00;

如果n是short类型的,则只需执行:

n &= 0xff00;

2、如何判断一个int型变量n的第7位(从右往左,从0开始数)是否是1?

只需看表达式 “n & 0x80” 的值是否等于 0x80 即可。

按位或“|”

将参与运算的两操作数各对应的二进制位进行或操作。

用来将某变量中的某些位“置1”且保留其他位不变。

按位异或“^”

两个二进制位不相同时,结果才是1,否则为0;

用来将某变量中的某些位取反,且保留其他位不变。

如果 a^b=c,那么就有 c^b=a 以及 c^a=b; (穷举法可证)

此规律可以用来进行最简单的加密和解密。

另外还有一个有意思的点,即不通过临时变量,就能交换两个变量的值:

var a = 1, b = 2
a = a^b
b = b^a
a = a^b
console.log(a, b)

// a => 2
// b => 1

按位非 “~”

是单目运算符,能将二进制为0变成1,1变成0。(就是取反)

左移运算符“<<”

a << b

的值是:将a各二进制位全部左移b位后得到的值。左移时高位丢弃,低位补0。

a 的值不因运算而改变。

9 << 4
0000 1001
1001 0000 
// 144

左移1位,就等于是乘以2,左移n位,就等于是乘以2n

右移运算符 “>>”

同理,移出最右边的位就被丢弃。 a 的值不因运算而改变。

大多数c/c++编译器规定,如果原符号位为1,则右移时高位就补充1,原符号位为0,则右移时高位就补充0。

右移1位,就等于是除以2,左移n位,就等于是除以2n,并且将结果往小里取整。

-25 >> 4 = -2
-2 >> 4  = -1
18 >> 4  = 1

所以答题,算对是很重要的,所以要小心谨慎。

答题

1、负数的二进制表示?

2、有两个int型的变量a和n(0 <= n <= 31) 32进制

要求写一个表达式,使该表达式的值和a 的第n位相同。

其实问题就是让你判断,a的n位是0还是1?

(a >> n) & 1

当 n 不等于 31时,

(a & (1 << n)) >> n

位运算很重要,它的速度非常快,能提高效率。

04 | 引用

1、某个变量的引用,等价于这个变量,相当于该变量的一个别名。

2、初始值改变,引用的值也跟着改变。

3、使用引用有3条要注意的地方:

  • 定义引用时,一定要将其初始化成引用某个变量;

  • 初始化后,它就一直引用该变量,不会再引用别的变量了(引用从一而终)。

  • 引用只能引用变量,不能引用常量和表达式。

r1引用了a
b 赋值给r1

则a = b
r1从一而终,依然是4

4、c语言中,如何编写交换两个整型变量值的函数?

把参数变成指针,把指针的内容进行交换。

5、c++,优化成了引用,引用的是指针。其实也是一回事。

void swap(int & a, int & b) {
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}
int n1, n2;
swap(n1, n2) // n1, n2的值被交换

6、引用可以作为函数的返回值

一个函数的返回值是引用。

int n = 4;
int & SetValue() { return n; }
int main() {
    SetValue() = 40;
    cout << n;
    return 0;
} // 输出:40

7、常引用

cont int & r = n;

特点,不能通过常引用去修改其引用的内容;除非进行强制类型的转换。

05 | const 关键字和常量

定义常量,const是有类型的,便于类型检查。

1、定义常量指针

不可通过常量指针修改其指向的内容。

而不是说不能修改其内容

int n, m;
const int * p = &n;
*p = 5; // 编译出错
n = 4; // ok
p = &m; // ok, 常量指针的指向可以变化

2、不能把常量指针赋值给非常量指针,反过来可以

const int * p1; int * p2;
p1 = p2 //ok
p2 = p1; // error

// 如果就是想要把一个常量指针,指向非常量指针,那就需要强制类型转换
p2 = (int * ) p1; // ok,强制类型转换

3、函数参数为常量指针时,可避免函数内部不小心改变参数指针所指地方的内容

void MyPrintf(const char * p) {
    strcpy(p, "this"); // 编译出错
    printf("%s", p) ;; //ok
}

那编译器是如何发现问题的呢?根据strcpy的参数类型的不同

06 | 动态内存分配

实际运行需要多少空间,就按照这个需要去进行空间的动态内容分配。

int * pn;
int i = 5;
pn = new int[i * 20];
pn[0] = 20;
pn[100 = 30; // 编译没问题。运行时导致数组越界

用“new”动态分配的内存空间,一定要用“delete”运算符进行释放。否则就容易特别慢,或者导致崩溃。

delete 指针; // 该指针必须指向new出来的空间

int * p = new int;
* p = 5;
delete p;
delete p; // 导致异常,一片空间不能被delete多次

如果动态分配的是数组,要加“[]”

delete [] 指针; // 该指针必须指向 new 出来的数组

int * p = new int[]/20 ;
p[0] = 1;
delete [] p;

07 | 内联函数、函数重载、函数缺省参数

1、内联函数

这样一个简单的函数,如果调用次数过多,那函数的内容的开销跟调用函数的开销差不多,就形成了浪费,所以使用内敛函数,就可以提高函数执行的效率。

2、函数重载

08 | 函数缺省参数

适应需求,当功能增加的时候,可以少改很多个缺省调用语句,可以减少程序修改量的目的,那 说明你的程序的扩展性比较好。

void func(int x1, int x2 = 2, int x3 = 3) {}

func(10); // 等效于func(10, 2, 3)
func(10, 8); // 等效于func(10, 8, 3)
func(10, , 8) // 不行,只能最右边的连续若干个参数缺省

刘家瑛

09 | 面向对象程序设计方法

结构化程序设计

1、将复杂的问题 → 层层分解/模块化 → 若干子问题

每个模块都不同的开发人员来实现,同时能他们要约定要相互的通讯,和协作接口。

2、结构化设计,就是自顶向下,逐步求精的过程。

程序 = 数据结构(变量) + 算法(函数)

3、结构化程序设计的4大囧境

理解难、修改难、差错难、重用难。

面向对象的程序设计

1、面向对象的设计方法:抽象成类、封装成方法

10 | 面向对象程序设计的发展历程

11 | 类成员的可访问范围

12 | 内联成员函数和重载成员函数

郭炜

13 | 构造函数

整型可以被自动转化为doubler类型。

带 * 的表示指针,而指针不会生成对象,所以不会调用构造函数,所以第三行只打印了2个。

14 | 复制构造函数

复制构造函数起作用的3种情况: 赋值、函数参数、return

15 | 类型转换构造函数

16 | 析构函数

为消亡构造函数,有了析构函数

先被构造的函数,会最后被析构掉。

17 | 静态成员变量和静态成员函数

静态成员:在说明前面加了static关键字的成员。

  • 普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。

  • 普通成员函数必须具体作用域某个对象,而静态成员安徽省农户并不具体作用域某个对象。

  • 因此静态成员不需要通过对象就能访问。

如何访问静态成员

1)类名::成员名

2)对象名.成员名

3)指针->成员名

4)引用.成员名

  • 静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。

  • 静态成员函数本质上是全局函数。

18 | 成员对象和封闭类的概念

19 | 友元函数

20 | this指针

this指针指向,成员函数所作用的那个对象。

21 | 常量对象、常量成员函数和常引用

22 | 运算符重载的基本概念

运算符重载
对已有的运算符赋予多重的含义

使同一运算符作用于不同类型的数据时 -> 不同类型的行为
目的

扩展C++中提供的运算符的适用范围,以用于类所表示的抽象数据类型
同一个运算符,对不同类型的操作数,所发生的行为不同。

23 | 赋值运算符的重载

赋值运算符“=”只能重载为 成员函数

重载赋值运算符的意义-浅复制和深复制

浅复制/浅拷贝

  • 执行逐个字节的复制工作

浅复制/浅拷贝的bug:

s1 = s2有个问题,当内存空间同时消亡的时候,那么(2)的内存空间就会被先后释放2次,这样会导致严重的内存错误,甚至可能引发程序的意外终止。

深复制/深拷贝:

视频链接

相关文章

  • C++程序设计(北京大学) 23/40

    郭炜 C++语言是特别讲究效率的语言,对效率是锱铢必较的。 01 | 函数指针 函数指针,用来指向变量的地址。有起...

  • 多年程序员推荐:学习C语言的书籍有哪些?

    c++程序设计教程 c++编程思想 c++大学教程 c++程序设计语言 数据结构算法与应用c++语言描述 c++标...

  • C++模板template用法

    引言 模板(Template)指C++程序设计设计语言中采用类型作为参数的程序设计,支持通用程序设计。C++ 的标...

  • 图灵计算机科学系列丛书大收集

    C/C++ [图灵程序设计丛书].C++性能优化指南[图灵程序设计丛书].嗨翻C语言 C# [图灵程序设计丛书]....

  • 计算机二级考试

    C语言程序设计、VB语言程序设计、Java语言程序设计、Access数据库程序设计、C++语言程序设计、MySQL...

  • C++ 基础

    C++基础 1、C++对C的扩展 1.1程序设计方法的发展历程 面向过程的机构化程序设计方法 设计思路– 自顶...

  • 2019-04-04 C++学习笔记之类和对象(上)

    参考资料:《21天学通C++》、《C++语言程序设计(第4版)》 面向对象程序设计的基本特点 抽象 面向对象方法中...

  • 第一周(Geek Band)

    C++程序设计(兼谈对象模型) 主要课题(since c++ 11): variadic template(可变参...

  • 曾经强大的C++语言,真的穷途末路了吗?

    C++是C语言的继承,擅长面向对象程序设计的同时,还可以进行基于过程的程序设计,因而C++就适应的问题规模而论,大...

  • GeekBand C++ week3

    一、导论 1.I和II的区别 I:C++面向对象程序设计II: C++程序设计兼谈对象模型 勿在浮沙筑高台 2.C...

网友评论

      本文标题:C++程序设计(北京大学) 23/40

      本文链接:https://www.haomeiwen.com/subject/rvzffqtx.html