计算机项目部第一次培训总结

此次部门培训的内容是codeblocks的分步调试的相关操作,探究递归的思想,回顾数组与字符串知识。开始初步了解指针及相关操作,最后的时间引入了面向对象编程的思想,引申出类与对象的基本概念。
*计项部的小狗熊们要认真看哟 *

一、cb的分布调试

一串小代码:

//输入一个数,输出这个数到1之间的数
#include <iostream>
#include <stdio.h>
using namespace std;

void test(int n){
    if(n==0)
        return ;
    cout<<n<<" ";
    test(n-1);
}
int main(void){
    int n;
    cin>>n;
    test(n);
    return 0;
}

调试
快捷栏红圈标示,如果没有,在view下找到Toolbars,把那些东西勾选对号即可。

首先把光标放在int n上,然后按F4(因为版本的不同,有些同学的cb是ctrl shift F7),或者

表示 run to cursor
然后按F7即可单步执行,或者

表示next line(下一步)
这里需要输入n的值

下面是一个test函数,如果再按F7,就会直接到return 0,如果想看test函数的执行过程,两个方法:
①设置断点(F5)

为了方便查看相关变量的变化,我们可以打开watches,下图中的红圈,点击选择watches即可。

②step into ,step out
这个step into可以跳入函数,如果想跳出则点击step out就行了。
退出调试

二、递归思想

1、基本思想
所谓递归,就是有去有回
递归的基本思想,是把规模较大的一个问题,分解成规模较小的多个子问题去解决,而每一个子问题又可以继续拆分成多个更小的子问题。
最重要的一点就是假设子问题已经解决了,现在要基于已经解决的子问题来解决当前问题;或者说,必须先解决子问题,再基于子问题来解决当前问题。

或者可以这么理解:递归解决的是有依赖顺序关系的多个问题。
我们假设一个抽象问题有两个时间点要素:开始处理,结束处理
那么递归处理的顺序就是,先开始处理的问题,最后才能结束处理。
假设如下问题的依赖关系:
【A】----依赖---->【B】----依赖---->【C】
我们的终极目的是要解决问题A,
那么三个问题的处理顺序如下:
开始处理问题A;
由于A依赖B,因此开始处理问题B;
由于B依赖C,开始处理问题C;
结束处理问题C;
结束处理问题B;
结束处理问题A。

2、广义递归
从函数调用看广义递归
对于软件来说,函数的调用关系就是一个广义递归的过程,如下,

func_A()
{
func_B();
}
func_B()
{
func_C();
}
func_C()
{
/////
}

调用函数A;
调用函数B;
调用函数C;
函数C返回;
函数B返回;
函数A返回;

3、狭义递归
有一种特例,就是处理问题A/B/C的方法是一样的,这就是产生了狭义的“递归函数“,即函数内又调用函数自身。
从上述分析看,递归对问题的处理顺序,是遵循了先入后出(也就是先开始的问题最后结束)的规律。
先入后出?
没错,广义递归问题的处理,需要用栈来解决。经典的例子就是函数调用,就是依靠栈来实现的。
在这里插入图片描述
4、递归与栈

  • 在入栈之前,通常需要完成三件事。
    1、将所有的实参、返回地址等信息传递给被调函数保存
     2、为被调函数的局部变量分配存储区
     3、将控制转移到北调函数入口。

-当 一个函数完成之后会进行出栈操作,出栈之前同样要完成三件事。
1、保存被调函数的计算结果。
  2、释放被调函数的数据区。
  3、依照被调函数保存的返回地址将控制转移到调用函数
测试代码

#include <stdio.h>
void recurrence(int num)
{
        if ( num < 0 )
        return;
       printf("%d\n", num);
       recurrence(num - 1); 
    printf("%d\n", num);
}
 int main(void) 
{ 
       recurrence(5); return 0; 
}

图解
在这里插入图片描述

三、数据及字符串回顾

题目检测:
复习相关知识后)
有一个3*4矩阵,请你编写程序早找出每一行中最大值一次输出来
(用函数和指针相关知识解决)

四、神奇的指针

1、对指针变量的类型说明包括三个内容:
(1)指针类型说明,即定义变量为一个指针变量;
(2)指针变量名
(3)变量值(指针)所指向的变量的数据类型。
其一般形式为: 类型说明符 *变量名;

2、其中,表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型。

例如: int *p1;表示p1是一个指针变量,它的值是某个整型变量的地址。 或者说p1指向一个整型变量。至于p1究竟指向哪一个整型变量, 应由向p1赋予的地址来决定。
应该注意的是,一个指针变量只能指向同类型的变量(基类型),如P3 只能指向浮点变量,不能时而指向一个浮点变量, 时而又指向一个字符变量

3、取地址运算符&

取地址运算符&是单目运算符,其结合性为自右至左,其功能是取变量的地址。在scanf函数及前面介绍指针变量赋值中,我们已经了解并使用了&运算符。

4、取内容运算符*
取内容运算符是单目运算符,其结合性为自右至左,用来表示指针变量所指的变量。在运算符之后跟的变量必须是指针变量。需要注意的是指针运算符和指针变量说明中的指针说明符 不是一回事。在指针变量说明中,“”是类型说明符,表示其后的变量是指针类型。而表达式中出现的“”则是一个运算符用以表示指针变量所指的变量。

感受代码:

int main()
{
    int b=2,a=1,*pa,*pb;
    pa=&a;
    pb=&b;
    //pa=pb;
    cout<<a<<endl<<b<<endl;
    cout<<*pa<<endl<<*pb;
    return 0;
}

引发问题的操作:

int main(void)//危险的不合适的操作,指针变量p未赋予地址,就对其取值。
{
    int   i=10;
    int   *p;
    *p=i;
    cout<<*p;
}

指针的算术运算:

int main()//指针的算术运算
{

    int b[5]= {12,23,34,45,65};
    int *p=&b[0];
    p++;
    cout<<"*p="<<*p<<endl;
    cout<<"p="<<p<<endl;
    *p++;
    cout<<"*p="<<*p<<endl;
    cout<<"p="<<p<<endl;
    (*p)++;
    cout<<"*p="<<*p<<endl;
    cout<<"p="<<p<<endl;
    *++p;
    cout<<"*p="<<*p<<endl;
    cout<<"p="<<p<<endl;
    ++*p;
    cout<<"*p="<<*p<<endl;
    cout<<"p="<<p<<endl;
    return 0;
}

传值传址*的区别(重要):
如下三个swap只有第一个产生实际作用,因为它没有对形参(这里是指针变量)进行直接变动操作,而是利用指针变量改变了它指向的值。其余两个函数不能发挥作用,因为他们对形参进行了直接变化,这个变化不可以传递到main函数中。

int main()//指针变量做参数,交换a与b的值
{
//    void swap(int *p1,int *p2);
    void swap(int,int);
    int *pointer1,*pointer2,a,b;
    cin>>a>>b;
    pointer1 = &a;
    pointer2 = &b;
    if(a<b)
        swap(a,b);
    cout<<"max="<<a<<" "<<"min="<<b<<endl;
    return 0;
}

void swap(int *p1,int*p2)//可行的利用指针交换指向的内容,绕过了“单项传递”,达到交换值的目的
{
    int temp;
    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}


void swap(int x,int y)//暴力膜不可取,直接换是不行的,实参到形参为单项传递,形参值的变化无法传给实参
{
    int temp;
    temp = x;
    x=y;
    y= temp;
}

void swap(int *p1,int*p2)//也是不可取的,形参实参为指针变量,试图改变指针变量是无法对实参的指针变量产生影响。
{
    int *temp;
    temp = p1;
    p1 = p2;
    p2 = temp;
}

5、指针与数组:

int a[10], *pa; pa=a;  pa =&a[0]; //等价

引用一个数组元素,有3种方法:
(1)下标法: a[i]
(2)数组名地址法: *(a+i)
(3)指针法: ①指针地址法: *(pa+i) ②指针下标法: pa[i]

int main()//练习用不同的方法表示二维数组的元素
{

    int a[3][4]= {{5,6,7,8},{9,10,11,12},{13,14,15,16}};
    int i,j , (*p)[4];
    for(i=0; i<3; i++)
    {
        p=&a[i];
        cout<<(*p)[0]<<(*p)[1]<<(*p)[2]<<(*p)[3]<<'\n';
    }
    p=a;
    for(i=0; i<3; i++)
        for(j=0; j<4; j++)
        {
            cout<<*(*(p+i)+j)<<*(p[i]+j)<<*(*(a+i)+j)<<'\n';
        }

}

在这里插入图片描述**加粗样式
指针数组:

int main()//指针数组举例
{

    float a[ ] = {100,200,300,400,500};
    float *p[5] = {&a[0],&a[1],&a[2],&a[3],&a[4]};
    int i;
    for(i = 0; i < 5; i++)
        cout << *p[i] << '\t';

}

6、指针与函数:

int f1(int x,int y)//指向函数的指针举例,p指向函数的入口地址
{
    int z;
    z=(x>=y)?x:y;
    return z;
}
int f2 (int a,int b)
{
    return (a+b);
}
int  main()
{
    int (*p)(int,int);
    int c,d;
    p=f1;
    c=p(5,10);
    p=f2;
    d=p(8,10);
    cout<<c<<'\t'<<d;
}

五. 面向对象编程基本概念

1、面向过程的普遍特点对比面向对象的特点:
(面向过程)
①以功能为核心,以解决问题的过程和步骤为指导进行设计;
② 函数是构成程序的基本部分,也是软件复用的基本单位;
③ 函数之间相互独立,可以互相调用;
④ 程序结构清晰,模块化思想便于分工合作、提高开发效率;
⑤ 程序流程在编码时已经确定,用户不能更改;
⑥ 操作与数据相互分离,难以对数据和操作模块进行修改。
⑦ 设计者难以在开始就对需要解决的问题有比较全面的了解;
⑧ 难以进行程序功能扩展和维护
(面向对象)
① 强调程序中的对象以及对象之间的关系能够如实地反映问题
域中的事物及其关系。
② 整个源程序代码主要由若干个类构成;
③ 可以按需确定程序流程,通过对象之间相互发送消息建立各
对象之间的联系,完成整个程序的功能;
④ 具有抽象性、封装性、继承性和多态性的特征;
⑤ 类的大量加载会牺牲系统性能,降低运行速度。
2、面向对象基本概念
• 对象是具有一定的特征和行为的实体;
• 类是为了描述一组对象在结构和行为上的共性所创建的抽 象数据类型;是对具有相同或相似性质的对象的抽象描述;
• 类是创建对象的模板,从一个类实例化的每个对象具有相 同结构和行为;
• 一旦定义了一个类,程序员就可以从一个类创建这个类的 任意数目的对象,然后操作这些对象
3、封装
封装是将一组相关的概念聚集在一个单元内,并 且用单独的一个名字来引用。
面向对象的封装是将操作和表示状态的属性包装 在一个对象类型中,从而使状态只能通过封装体 提供的接口来访问和修改。
4、继承
继承允许在已有类的基础上定义新类(派生类),
派生类自动拥有已有类(基类)的属性和操作
5、派生类可以增加自己特有的功能,也可以修改继
承得到的功能(覆盖)。

6、多态
多态性是一种机制,指一个操作名或属性名可在多个程序 单元中定义,且在各个程序单元中有不同的实现。
• 类的多态性是指在一般类中定义的属性或行为,被特殊类 继承之后,可以具有不同的数据类型或表现出不同的行为。
• 分为两个方面:
静态多态:通过函数重载运算符重载模板实现
动态多态:通过类的继承关系虚函数机制实现。
封装和信息隐藏
类把数据和对数据的操作封装在一个结构中;
• 数据一般被限定为私有的,在类的外部只能通过公有的接 口访问私有的数据。
• 类的声明和类的实现一般放到不同的两个文件中;
• 为了隐藏实现的细节,类的实现文件以目标文件的方式提 供;
• 为了隐藏数据成员,在实现文件中定义数据结构体,在类 的声明中通过指针访问数据结构体

7、优势:
– 加强了类的安全性一致性
– 类的改变可不影响使用该类的程序的正常运行
– 对于使用者,不需要了解过多的细节就可以使用对象, 降低了操纵该类型的复杂程度;
– 对于设计者,有利于保护类的内部设计不被破坏或窃取
8、类的定义

class <类名> 
{ 
public: <数据成员或成员函数的声明>
protected: <数据成员或成员函数的声明> 
private: <数据成员或成员函数的声明> 

};
代码示例:
#include <iostream>

using namespace std;


class Rectangle
{
private:
    int left , top , right , bottom ;
public:
    Rectangle(int l, int t, int r,int b)
    {
        left=l ;
        top=t ;
        right=r ;
        bottom=b;

    }
    Rectangle()
    {
        left=0 ;
        top=0 ;
        right=0 ;
        bottom=0 ;

    }
    void print()
    {
        cout<<left<<" "<<top<<" " ;
        cout<<right<<" "<<bottom<<'\n';
    }
};
int  main()
{
    Rectangle r1(100,200,300,400);
    r1.print();
    Rectangle r2;
    r2.print();
    return 0;
}


猜你喜欢

转载自blog.csdn.net/NOTFOUND_Liu/article/details/84038014