第一章 C++语言简介-04737-C++程序设计【自考笔记】

考核目标

1.熟悉C++的基本程序结构

2.自主学习并熟练掌握一种C++的集成开发环境Dev C++ 5.11的使用方法,见教材附录。

3.初步理解面向对象程序设计的思想

第一节  C++语言的发展简史

C++是由贝尔实验室1979年在C语言的基础上开发成功的。

C++兼容C语言,用C语言写的程序基本上可以不加修改地用于C++

C++对C的“增强”表现在两个方面:

(1).在原来面向过程的机制基础上,增强了C语言对类型的处理。

(2).增加了面向对象的机制。

C++语言是一种编译式(写完之后要编译成可执行文件再运行)、通用的(通用性很强,适用于很多不同的操作系统)、大小写敏感的编程语言,完全支持面向对象的开发模式。

第二节 C++语言的特点

一.基本的输入/输出

#include<iostream>

using namespace std;

int main()
{ int a[10];
for(int i=0;i<10;i++)
    cin>>a[i];
for (int i=0;i<10;i++)
    cout<<a[i]<<" ";
cout<<endl;

}

 C++环境:vscode里安装C/C++拓展、+GCC and Mingw-64 on Windows(编译工具)、配置好系统PATH、--->GCC \G++\GDB

部署好环境之后,可以直接在终端中使用命令行编译源码,编译完之后会在同一目录下生成exe文件,直接执行exe文件即可。注意的是:C的编译命令行是用的gcc ,有些情况下C++的某些命令与C是相同的,所以可以用GCC编译,但尽管 GCC 可以编译 C++ 代码,但默认情况下它不会自动链接 C++ 标准库(重点是那些不同于C的地方)。这是因为 GCC 主要是作为 C 语言编译器设计的。对于 C++ 程序,应使用 G++ 编译器,后者会自动处理 C++ 标准库的链接。

基本所有的C++程序在最开始必须要有这两条命令??↓

说明:

①标准输入:cin>>变量1>>变量2>>…>>变量n;

②)标准输出:cout<<表达式1<<表达式2<<…<<表达式n;

③使用标准输入cin及标准输出cout前,要在程序的最前面包含:

#include<iostream>//包含头文件:输入输出流

using namespace std;//使用标准命名空间?

④换行操作:用语句cout<<endl;或cout<<“\n”

⑤当连续从键盘读取想要的数据时,以空格、制表符(Tab〉键或〈Enter〉键作为分隔符。如果第一个字符是空格、〈Tab〉键或〈Enter〉键,则cin会将其忽略并清除掉,继续读取下一个字符
用户自己定义的类型的数据,不能直接用“>>”和“<<”进入输入/输出,必须对“>>”和“<<”进行运算符重载后才可以使用。

头指令?没有分号就是伪指令

分号:

cin   --->从键盘上输入,输入流

cout<<  --->输出,cout<<end 1?? 换行符

二.头文件和命名空间

头文件
前面例题中 #include<iostream>
每个C++程序由头文件定义文件组成。头文件作为一种包含功能函数、数据接口声明的载体文件,主要用于保存程序的声明,而定义文件用于保存程序的实现。头文件是用户应用程序和函数库之间的桥梁和纽带。编译时,编译器通过头文件找到对应的函数库,进而把已引用函数的实际内容导出来代替原有函数,然后再进行翻译。

常用的头文件:
标准输入输出流:<iostream>
标准文件流:<fstream>
标准字符串处理函数:<string>
标准数学函数:<cmath>
除了可以使用系统提供的头文件外,程序员还可以定义自己的头文件。

命名空间
一个大型的程序不同模块中出现的标识符之间有可能发生重名现象,这就会引发错误。C++中为了避免名字定义冲突,特别引入了“命名空间”的定义,即namespace。命名空间的作用是为了消除同名引起的歧义。
在程序中使用标准程序库中的标识符时,要写语句“using namespace std;

三.强制类型转换运算符

当不同类型的量进行混合算术运算时,系统自动进行合理的类型转换,也可以强制转换类型

1.将一种数据类型转换成另一种数据类型

stati_cast<类型名>(表达式)
说明:staticast---可以省略不写
oneint2=static cast<int>(oneDouble);

oneint2=int(oneDouble);

oneint2=(int)oneDouble;//圆括号

oneint2=oneDouble //自动类型转换

2.const_cast<类型名>(表达式)
功能:将常量指针转化成非常量的指针,并且仍然指问原来的对象;或是将常量引用转换成非常量的引用,并且仍然指向原来的对象。
例:

int a=10,*q;const int ca=30;
const int *p=&a;//不能使用常量指针p修改a的值

g=const_cast<int *>(p)//不能q=p

*q=20//变量a的值变为20,不能形成*p=20

p=&ca;//ca的值不能修改

q=const_cast<int *>(p) //不能g=p

*q=40//*q的值为40,*p的值变成40

//变量ca的仍然是30

四.函数参数的默认值

◆C++中,可以在声明函数时为形参指定默认值。函数参数的默认值,在C语言里没有这个.

【例1-3】定义带默认值的函数
 

#include<iostream>
using namespace std;
void func(int a=11,int b=22,int c=33)
{ cout<<"a="<<a<<"b="<<b<<"c="<<c<<endl;}
int main()
{
func();
func(55);
func(77,99);
func(8,88,888);
retun 0:
}

◆C++语言规定,定义函数时,只能为函数最后面的连续若干个参数设置默认值,且在调用处也只能缺省后面的连续若干个实参。
例:判断以下函数声明正确与否 //注意不是定义
void df1(int a=2,double b=3.0);//正确
void df2(int a,double b=3.0);//正确
void df3(int a=2, double b);
void f1(int a,int b=2,int c=3);//正确
void f2(int a=1,int b,int c=3);
void f3(int a=1,int b=2,int c) ;

◆C++语言规定,在函数调用处只能缺省后面的连续若干个实参,而且所有缺省的实参必须已经有默认值。

例:函数调用示例
函数声明:void func(int a,int b=2,int c=3)
函数调用:func(1,22,33);
func(); //错误
func(10,20);
func(5,,9); //错误

C++语言规定,指定默认值时不仅可以用常数,还可以用任何有定义的表达式作为参数的默认值。例:假设给出如下的函数及变量声明:
int Max(int m,int n)
int a, b;
void func2(int x,int y=MAX(a, b),int z=a-b){...}
调用 func2(4);等价于func2(4,MAX(a,b),a-b);

        func2(4,9);等价于func2(4,9,a-b);

        func2(4,,10);错误

注意:函数参数的默认值可以写在声明函数的地方,也可以写在定义函数的地方,但不能在两个地方都写。函数声明表示这么个函数了,函数定义就是具体实现了。

函数声明:
int fun(int a, int b);
函数定义:
int fun(int a,int b)
{int c;
c=a+b;
return c;}

五.引用和函数参数的传递

1.引用:相当于给变量起了一个别名。别名的地址与引用变量的地址是一样的。程序中使用哪个名字都是允许的。

“引用”的定义格式:
        类型名 &引用名=同类型的变量名;

例:int x=10;int &a=x   //a就是x的一个引用,可以有多个引用

注意:

对象在引用前必须先初始化;
②声明中符号“&”的位置无关紧要
如int& a=x;int &a=x;int &a=x;等效

常引用的格式:
const 类型名 &引用名=同类型的变量名;

例:int x=10;
int &a=x; //a就是x的一个普通引用
const int &b=x; //b就是x的一个常引用
a=20; //则x=20,b=20
x=30; //则a=30,b=30
b=40: //错误
注意:不能通过常引用去修改其引用的变量的值

2.引用在函数中使用
引用作为函数的参数数
在函数在C++中,函数调用时参数的传递有两种方式:传值传引用传引用是传递对象的首地址值形参的改变就意味着实参的改变

#include <iostream>
using namespace std;

void SVal(int a, int b)
{
    int tmp;
    tmp = a; a = b; b = tmp;
    cout << "在SVal()函数中 :\t\ta=" << a << ",b=" << b << endl;
    return;
}

void SRef(int &a, int &b)
{
    int tmp;
    tmp = a; a = b; b = tmp;
    cout << "在SRef()函数中:\t\ta =" << a << ",b=" << b << endl;
    return;
}

int main()
{
    int a = 10, b = 20;
    cout << "数据交换前:\t\ta=" << a << ",b=" << b << endl << endl;
    SVal(a, b);
    cout << "调用SVal()后:\t\ta=" << a << ",b=" << b << endl << endl;

    a = 10; b = 20;
    SRef(a, b);
    cout << "调用SRef()后:\t\ta=" << a << ",b=" << b << endl;
    return 0;
}

 执行结果:

数据交换前:             a=10,b=20

在SVal()函数中 :                a=20,b=10
调用SVal()后:           a=10,b=20

在SRef()函数中:         a =20,b=10
调用SRef()后:           a=20,b=10

 ◆引用作为函数返回值

返回引用的函数原型的格式如下:
        数据类型&函数名(参数列表);

【例1-7】引用作为函数返回值

#include <iostream>
using namespace std;

int oneX=10,
int oneY=20;
int& refValue(int&x)//函数返回值是引用
{ return x;}

六.const与指针共同使用

当const与指针共同使用时,其书写的位置不同,语句含义也不同

1)如果唯一的const位于符号*的左侧,表示指针所指数据是常量数据不能通过本指针改变,但可以通过其他方式进行修改;指针本身是变量,可以指向其他的内存单元。

例:    int a1=10,a2=20,*pa1=&a1;
        *pa1=30;//正确,a1变成10

        const int *pa2=&a2;//pa2所指的是常量,pa2是变

        *pa2=40;//错误
        pa2=&a1; //正确

2)如果唯一的const位于符号*的右侧,表示指针本身是常量,不能让该指针指向其他内存地址;指针所指的数据可以通过本指针进行修改。

例:   int a1=10,a2=20:
        int * const pa2=&a2;//指针变量pa2是常量

        pa2=&a1;// 错误

        *pa2=40;//正确

3)在符号*的左右各有一个const时,表示指针和指针所指数据都是常量,既不能让指针指向其他地址,也不能通过指针修改所指向的内容。

例: int a1=10,a2=20:
const int * const pa1=&a1;//数据和指针都是常量

pa1=&a2; // 错误

*pa1=30//错误

int const * const pa2=&a2;//数据和指针都是常量

pa2=&a1;// 错误

*pa2=40 //错误

记住const的修饰规则:const修饰其左侧的内容;如果const是本行的第一个标识符,则它修饰其右侧的内容。

const int *pa2=&a2;//pa2所指的是常量

int*const pa2=&a2;//指针变量pa2是常量

const int*const pa1=&a1;//数据和指针都是常量

int const * const pa2=&a2;//数据和指针都是常量 

七.内联函数

对于需要频繁调用,且代码量少的函数,可以将其定义为内联函数。编译时,编译程序将整个函数体的代码复制到调用该函数的位置。执行效率高一些。
定义内联函数的格式如下:
        inline返回值类型函数名(形参表)
        {函数体}

如果函数体中有循环语句和switch语句则通常不定义为内联函数。

八.函数的重载

函数重载:C++允许为同一个函数定义几个版本,从而使一个函数名具有多种功能,这称为函数重载。只要分别为不同参数编制相应的函数体,就可以实现各自的功能。
例:函数重载的例子1
 

#include <iostream>
using namespace std;

// 声明2个整型参数的函数原型
int max(int, int);
// 声明3个整型参数的函数原型
int max(int, int, int);

int main() {
    cout << max(36, 25) << "," << max(25, 39, 35) << endl;
}

// 定义2个整型参数的函数
int max(int m1, int m2) {
    return (m1 > m2) ? m1 : m2;
}

// 定义3个整型参数的函数
int max(int m1, int m2, int m3) {
    int t = max(m1, m2);
    return max(t, m3);
}

实现函数的重载必须满足下列条件之一:

  • 参数表中对应的参数类型不同;
  • 参数表中参数个数不同;
  • 参数表中不同类型参数的次序不同。

注意:

1)两个函数的名字和参数表都是一样的,仅仅是返回值类型不同(返回值类型相同不相同都不重要),则这两个函数不是重载的。

例:错误的重载函数
float add(int,float);
int add(int,float);  //错误! 

2)函数的参数采用引用的,不能区分函数,则这两个函数不是重载的。
例:错误的重载函数

void print(double);

void print(double &)//错误!
3)函数调用可能会引发二义性,不能采用函数重载。

例:若定义了重载函数Sum(),如下所示:

int Sum(int a, int b, int c = 0);

int Sum(int a, int b);
则函数调用语句:Sum(l2);//调用会产生二义性

九.指针和动态内存分配

1.指针:即指针变量,该变量存储的是一个地址,是该指针所指对象的首地址。普通变量里存的是数,指针变量存的是地址。

int a =100,*pa=&a;
int s[10],ps=s;//指针ps指向数组s的首地址

2.动态内存分配

动态分配内存的一般格式为:

指针名=new 类型名;//分配

delete 指针名;//释放

对于delete 释放内存空间,c++里有严格的要求,当不再使用这个空间时,必须使用delete释放空间。若使用new运算符动态分配了一个数组,那么释放该数组时,语句如下:delete[]指针。

#include <iostream>

using namespace std;

int main()
{

double *p;//声明double型指针
p=new double[3];//分配3个double型数据的存储空间
for(int i = 0;i<3;i++)
cin>>*(p+i);
for(int j=0;j<3;j++)
cout<<*(p+j)<<" ";

delete []p;//释放空间

}

十.用string对象处理字符串

c语言用字符数组来处理字符串,例如:char name[]="C++程序";

c语言里没有string这个数据类型,c++中扩充了这个类型来处理字符串。

1.声明string对象

例如: 

string str1; //声明string对象str1,值为空
string city="Beijing";//声明string对象并初始化
string str2=city;//使用字符串变量进行初始化
char name[]="C++程序";
string str3=name; //使用字符数组对string变量进行初始化
string citysf[]={"Beijing","Shanghai","Tianjing"};//声明string对象数组,每个数组元素都是字符串

说明:

1)使用string对象,必须#include<string>;

2) string对象储存的是字符串的首地址,非字符串本身;sizeof(string)在32位的Dev C++中是4,在64位的Dev C++中是8。

2.string对象的操作

  • string对象可以使用cin和cout进行输入和输出
  • string s1,s2;
    cin>>s1>>s2;
    cout<<s1<<","H<<s2<<endl
  •  string对象之间可以互相赋值,也可以用字符串常量和字符数组的名字对string对象进行赋值。
  • string s1,s2="OK";
    s1="China";
    s2=s1;//赋值后s2的内容与s1相同
  • string对象之间可以用>、>=、==、<=、<、!=运算符进行比较。大小的判定标准是按照字典序进行的,并且是大小写相关的。 
  • bool b;//C++新增了bool类型,该类型只有两个取值1或0,1表示”真“,0表示"假"
    string s1="China",s2="OK";
    b=s1>s2;//变量b的值位0,O在C后面,所以O比C大
  • 使用运算符"+"对字符串进行连接
  • string s1="China",s2="OK",s3=" ";
    s1=s1+s3+s2;//连接后s1的内容 "China OK"

3.string类中的常用成员函数

略... 

#include <iostream>
#include<string.h>
using namespace std;

int main()
{

string str;
//empty()判断当前字符串是否为空
if(str.empty())
//length()返回当前字符串的长度
cout<<"str is NULL."<<",length="<<str.length()<<endl;
else
cout<<"str is not NULL."<<endl;
//append(const char*S)将字符串s连接到当前字符串的结尾处
str=str.append("abcdefg");
//size() 返回当前字符串的大小
cout<<"str is"<<str<<",size="<<str.size()<<endl;
cout<<"length="<<str.length()<<endl;
const char*p=str.c_str();//p指向了字符串str c_str()返回一个指向字符串的指针,字符串内容与本string串相同,用于将string 转换为const char*
cout<<"p="<<p<<endl;
//find(char ch,size type index) 返回字符ch在字符串中第一次出现的位置(从index开始查找),如果没有找到就返回-1
cout<<"find: "<<str.find("de",0)<<endl;//从str的第0查找字符串"de",成功,返回3
cout<<"find: "<<str.find("de",4)<<endl;//查找失败,返回-1对应的无符号数
//insert(int p ,const string &S);在P位置插入字符串S
string str1=str.insert(4,"123");//从str的第四位置插入"123"
cout<<str1<<endl;

return 0;

}

第三节 C++语言的程序结构

  • C++程序以.cpp作为文件扩展名(C语言中是.c),C语言里由若干个函数构成,C++是若干个类和若干个函数构成。
  • 程序中有且仅有一个主函数main(),程序从主函数的开始处执行,在主函数结束。程序的结束通常是遇到了以下两种情形之一:
    • 1)在主函数中遇到了return语句。
    • 2)执行到主函数的最后面的括号。
  • 主函数中可以调用程序中定义的其他函数,但其他函数不能调用主函数,其他函数直接可以相互调用。
  • C++程序中注释有两种形式:
    • 1)从/*开始,到*/结束,如:/*.......*/
    • 2)从//直到行尾,如:  //.......
  • C++的格式和C一样,都很自由,一行可以写几条语句,但也要注意错落有致,增加可读性。

猜你喜欢

转载自blog.csdn.net/stan_ko/article/details/136843048