C++笔记|第1课|关于C++的几个基本问题

C++笔记 第1课 关于C++的几个基本问题

“C语言功能强大,希望大家进一步巩固所学过的C语言内容,这是下一步学习C++的基础。”——老师

C++历史

1979年,刚从英国剑桥大学(CU)获得博士学位的29岁丹麦人Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)。进入美国AT&T公司Bell(新泽西)实验室,开始在C语言的基础上研制C++,1983年研制出了C++的雏形。

最初1980年被称为:带类的C(C with Class),1983 年正式命名为C++。从1989年开始C++的标准化工作, 1994年推出了ANSI C++标准

2011年9月ISO批准的最新C++标准是: C++11 (ISO/IEC 14882:2011)

C++简介

C++被称为面向对象的程序设计语言 OOPL (Object-Oriented Programming Language)

C是C++的子集,C++保持了C的原始思想。

C++在C的关键字的基础上增加了:catch, class, const, delete, friend, inline, new, operator, private, protected, public, template, this, throw, try, typeid, virtual, volatile 等关键字。

C++在C语言中增加的最重要的机制有三个:

  • 类 (class)
  • 函数重载 (function overloading)
  • 操作符重载 (operator overloading)

基本数据类型

新类型:bool(布尔量) 取值只有两个:true/false
给bool赋值别的数,都将强制转换成true(不为0时)或false(为0时)
bool型占1个字节,等同于char

输入/输出

#include <iostream>
using namespace std;

原来C语言的stdio.h, string.h, math.h等文件引用仍可使
用,但需要去掉文件名后缀.h ,前面加上c:

#include <cstring>
#include <cmath>

对于一般的输入输出操作上面两种写法没有本质区别, 但文件操作将会有较大差别。

常用的I/O流类库操纵符(函数):

  • setw(int) 设置随后(一个)输出内容的场宽,不够自动突破
  • setprecision(int) 设置随后输出的(一个)浮点数的位数(不包括小数点)——注意:是总位数
  • hex 随后所有的整型数值采用十六进制输出
  • oct 随后所有的整数值采用八进制输出
  • dec 随后所有的整数值采用十进制输出
  • endl 回车符
    要想使用setw和setprecision, 还必须引用 iomanip.h 程序开始处加:#include <iomanip.h>#include <iomanip>
#include <iostream> 
#include <iomanip> 
using namespace std;
void main(void)
{
int i=33, j=35, k=12345; float f=3.14159f;
cout << setw(10) << i << setw(8)<< j <<endl;
cout << setw(3) << k <<endl; // 场宽不足,自动突破
cout << hex << i <<setw(3) << j <<endl; // 用十六进制输出整数 
cout << i <<setw(3) <<j <<endl;
cout << oct << i <<setw(j/8) << j <<endl; // 用八进制输出整数
cout << setw(12) << setprecision(5) << f << endl;
cout << setw(4)<<setprecision(6)<<f<<endl; //场宽不足,自动突破
cout << setprecision(4) << f << endl; // 未定场宽,按照实际宽度输出 
cout << setprecision(1) << f << endl;
cout << setprecision(2) << 314.159 << endl; }
//运行结果
        33      35
12345
21 23
21 23
41  43
      3.1416 //这里总位数5位
3.14159
3.142
3 //保留到一位,相当于取整(只针对0.0~9.9)
3.1e+02
Press any key to continue . . .
char s1[20], s2[20], s3[20];
cin >> s1 >> s2 >> s3;
// 等同于 scanf("%s%s%s", s1, s2, s3);
cout << s1 << s2 << s3 << endl;
// 若从键盘上输入:How are you?
// 输出结果是: Howareyou? 整行输入字符串:
cin.getline(s1, N, 结束符); // '\n' 为默认结束符,这里可以缺省参数
cin.get(s2, N, 结束符); // 一次连续读入多个(包括空格)字符,直到读满N-1个,或遇到 结束符
// getline读取但不存结束符,get既不读取也不存结束符

内联函数

为提高执行效率,C++增加了内联函数。与宏定义define类似,编译器将出现函数名的位置用函数体代码进行替换,即所谓在线化,这样省去了函数调用的参数入栈、退栈、跳转等所花费的时间。内联函数比define方便,功能也更强,不只是简单的字符串的替换,全面考虑了类型匹配问题。

声明为内联函数:在函数前加inline

内联函数的书写有一些限制(但没有统一的明确规定,由各家的编译器的聪明程度决定):
• 内联函数中可以定义变量,可以使用循环语句、分支语句等;
• 但内联函数不能直接递归或间接递归;
• 其它使编译器不能把函数调用在线化的情形。
凡是编译器没法把函数调用在线化的内联函数, 编译器都会自动忽略inline,把它当做一般函数来调用,inline也就自动失效了。

动态内存分配

C++用new和delete动态分配和释放内存,等同于C的malloc和free函数,但new和delete功能更强大

int *p=new int(10); //赋值
delete p;
int *pt=new int[10]; //数组
delete []pt;
int (*ptt)[10]=new int[8][10]; //分配80个int单元// pt是一个二维动态数组,ptt[0][0]~ptt[7][9]
delete []ptt;
int **q=new int *[10];
delete []q;

引用

C++提供了引用机制来传递变量地址。

在函数头部要传递地址的形参名前加&,而函数调用方式不变。
这样在被调用函数中对声明传递变量地址的变量的赋值操作,实际上是直接对调用函数中相应变量的操作。

#include <iostream>
using namespace std;
void swap(int &a, int &b) // 引用声明传递a,b变量的地址 
{ 
    int t=a;
    a=b; 
    b=t; 
}
void main()
{ 
    int i=3, j=5;
    swap(i, j); //交换i, j的值
    cout << i <<'\t'<< j<<endl ;
}
// 输出结果 : 5  3 
// a和b的值已经交换

引用方式(传变量地址)除了能简化程序书写,还能提高程序的执行效率,因为当传递的是结构体(对象)时,只需传递其地址,让函数直接访问,而不必按照C语言传值的方式将结构体(对象)复制到函数的形参表中。

后面会看到:对于类的复制构造函数来说,这种引用方式(传变量地址)的机制,不是可有可无,而是必须的。

函数返回值也可以返回引用,这样也只需传递所返回量的地址,让调用函数直接访问,而不必按照C语言传值的方式将返回量复制后传递返回。但不能返回局部变量的引用。

using namespace std;
const int &max(int &a, const int &b) 
{ 
    return a>b? a:b;// 返回的是a或b也就是i或j的地址 
}
void main()
{ 
    int i=3, j=5, k;
    k=max(i, j); //取i, j的值
    cout << k <<endl ; 
}

引用(reference)是一种特殊类型的变量,可以认为是给一个变量起别名。

int i, j;
int &r=i; // 变量引用,r和i是同一个内存单元
// r不能再改变引用,可以认为r是i的别名
i=10;
j=r; // 等价于i=20

类型修饰符 const

const是类型修饰符,在所定义的变量类型前面或后面出现,使之成为不可修改的量,即常量。

例如,int const a=1;const int a=1; 使变量a成为不可修改的量,等同于C的常量,但 const比C语言的常量功能更强,因为const是带类型的。

const经常用于函数参数说明,防止在函数中无意破 坏参数的值或所指内容。
例如,strcpy(char *str2, const char *str1); 是将字符串str1复制到str2。将参数str1定义为const,就是防止在strcpy函数中破坏str1所指的字符串。

尤其是在C++引入传地址的引用机制后,const用来保证在函数中不会修改相应参数变量的值或所指内容

常对象
除了定义时一次性赋初值,不能再改变它的值,从而共用时起到保护作用。
const STU a={"Zhang San", 'm', 2019000001};

常数据成员

struct STU
{
    char name[10];
    char gender;
    static int const sno=1;//静态常数据成员 
    //static与const同时出现
}

常指针
STU *const p=&a,只能在初始化时赋值

指向常对象的指针
常指针STU *const p和普通指针STU *p都不能指向常对象

const STU *p = &a;该指针指向a。该指针可以被修改
结论:指向常对象的指针不是常指针,可以被修改,也可以指 向普通对象。

指向常对象的常指针
const STU * const p = &a;初始化时指向a,不能被修改

作用域与可见性

C++引入了作用域操作符 (scope operator)‘::’,使我们可以同时访问同名的局部变量(max)和全局变量(::max)

#include <iostream>
using namespace std;
const int max=10000;
void main( ) // 从键盘上读入10个数,求最大值max输出,但最大不超过10000 
{ 
    int max, i,j;
    cin >> max;
    for (j=1; j<10;j++) 
    {
        cin >> i;
        if (i>max) max = i;
        if (max > ::max) max = ::max; 
    }
    cout << max<<endl; 
}
//若max大于外部变量max的值,则取外部常量max的值, 这种做法通常用来防止数组越界或溢出。

缺省参数

这样函数调用时可以从右边开始省略一个或多个参数。
在函数声明中可以为一个或多个参数指定缺省值,这样函数调用时可以从右边开始省略一个或多个参数。

void delay(int day=1, int month=3, int year=2019)
{............}

数据抽象

将数据类型与操作分开,被称为数据抽象

T abs(T i)
{ returni<0?–i:i; }

对象

将一个(组)变量,以及作用于这些变量的一个(组)函数封装为一个单元,这个单元就被称为对象。

类是同类对象的抽象(共同特性的描述),对象是类的实例化。

对象具有封闭性,可以自己控制外界对它的访问权限,从而严格控制外界对其中被封装变量的访问。

发布了10 篇原创文章 · 获赞 0 · 访问量 188

猜你喜欢

转载自blog.csdn.net/qq_45379253/article/details/104868460