C++--学习笔记011

20150507

所谓继承,就是从父辈得到的属性和行为。是通过继承对父辈的属性和行为进行进一步的细化或者扩充来形成新的类。

在c++中,我们把旧有的类称为基类或者父类,而把从基类继承产生的新类则称为派生类,也称为子类。

派生类(子类)的声明方式

class 派生类名:继承方式 基类名1,继承方式 基类名2...

{

//派生类新增加的属性;

//派生类新增加的行为;

}

;

单继承,这个派生类只有一个基类

多继承,这个派生类可以有多个基类

20150508

派生方式有3种

publi,protected,private

不同的派生方式决定了派生类如何访问从基类继承下来的成员变量和成员函数。

public方式继承,表示派生类是基类的一个子类型,在基类所有成员的访问级别在派生类中不改变。大多数情况都采用public方式继承。

20150511

private派生方式,把基类的所有公有(public)成员变成自己的私有(private)成员。这种继承方式的派生类不再直接支持基类的公有接口。

protected派生方式把基类的公有成员变成protected类型,保护基类的所有接口不被外界访问,只能由自身及自身的派生类访问。

//定义基类Human

class Human

{//人类共有的行为

public:

void walk();

void talk()

//人类共有的属性,上面的是行为,这里的属性

protected:

string m_strname;

int m_nage;

bool m_bmale;

private:

};

//以上一段结束

//下面的都是派生类

//public继承方式继承human类

//表示teacher跟human是is-a的关系

class teacher:public human

{//在子类中添加老师特有的行为,老师是human的子类

public:

void preparelesson();

void teachlesson();

void reviewhomework();

//在子类中添加老师特有的属性,上面的是行为,这里的是属性

protected:

int m_nduty;

private:

};//上面的都是teacher自己独自的东西,还没继承派生human中的行为和属性

//public继承方式继承human类

class student:public human

{//在子类中添加学生特有的行为

public:

void attendclass();

void dohomework();

//在子类中添加学生特有的属性

protected:

int m_nscore;

private:

};

//public继承方式继承student类

class pupil:public student

{//在子类中添加小学生特有的行为

public:

void attendclass();

void dohomework();

protected:

private:

};

//开始使用

///定义一个teacher对象

teacher mrchen;

//老师走进教室

//我们在teacher类中并没有定义walk()成员函数,

//这里是通过继承从基类human中得到的成员函数

mrchen.walk();

//老师开始上课

//这里调用的是teacher自己定义的成员函数

mrchen.teachlesson();

继承使用规范:

1、拥有的派生关系的两个类必须相关。

2、不能把组合当成继承

一台电脑拥有键盘,鼠标,显示器的功能,但电脑不能由键盘,鼠标,显示器派生,而应该由他们组合

//组合的例子

//键盘

class keyboard

{

public:

//接收用户键盘输入

void input();

};

//鼠标

class mouse

{

public:

//鼠标单击

void click();

};

//显示器

class monitor

{

public:

//显示画面

void display();

};

//电脑

class computer

{

//电脑的行为

//电脑的具体行为都有其各个组成部分来负责完成

public:

//用键盘,鼠标和显示器组合一台电脑

computer (keyboard* pkeyboard,

mouse* pmouse,

monitor* pmonitor)

{

m_pkeyboard=pkeyboard;

m_pmouse=pmouse;

m_pmonitor=pmonitor;

}

//键盘负责用户输入

void input()

{

m_pkeyboard->input();

}

//鼠标负责用户单机

void click()

{

m_pmouse->click();

}

//显示器负责显示画面

void display()

{

m_pmonitor->display();

}

//电脑的各个部件

private:

keyboard* m_pkeyboard;

mouse* m_pmouse;

monitor* m_pmonitor;

};

//注意:生命周期相同则采用对象;生命周期不同,则采用指针。

基类指针可以指代派生类的对象,而派生类的对象也可以当成基类对象使用。

20150512

//上车买票演示程序

//定义human类,这个类有一个成员函数buyticket()表示买票的动作

class human

{

//human类的行为

public:

//买票

void buyticket()

{

cout<<"人买票"<<endl;

}

private:

};

//从“人”派生两个类,分别表示老师和学生

class teacher:public human

{

};

class student:public human

{

};

//在主函数中模拟上车买票的场景

int _tmain(int argc,_tchar* argv[])

{

//声明一个基类的指针

human* ppassenger=null‘

//在车上来了一位老师

ppassenger=new teacher();

//老师买票

ppassenger->buyticket();

delete ppassenger;

//车上来了一位学生

ppassenger=new student();

//学生买票

ppassenger->buyticket();

delete ppassenger;

ppassenger=null;

return 0;

}

虚函数的产生

为了满足各个派生类对类的行为进行自定义的需要,c++提供了虚函数的机制,在基类的函数声明前加上virtual关键字,这个函数就成为虚函数。

工资管理系统开发:

经理和普通员工同属于员工,都是从员工派生出来的。

找到对象之后,就可以分析这些对象所拥有的属性和行为。

如果你是架构师,只要你完成了类的设计,那么你的工作就到此结束了。

如果你是程序员,你还需要将类的设计用c++语言来实现。

//开始变成

//工资计算程序

//salarysystem.h 头文件

//用于类的声明

#pragma once

//引入需要用到的头文件

#include<string>

#include<iostream>

using namespace std;

//员工类,下面是员工类的构造函数

class emplyee

{

public:

//构造函数

//根据员工的名字和入职时间构造员工对象

emplyee (string strname ,int nyears):

m_strname (strname),m_nyears(nyears) //利用构造函数参数对属性进行初始化

{};

//员工类的行为,上面是员工的构造函数,下面是员工的行为

public:

//提供一个纯虚函数作为公有接口,供外界获得员工的工资

//因为经理类和普通员工这两个派生类对工资的计算方式不同,所以这里必须提供纯虚函数供派生类对其进行自定义

virtual int getsalary()=0;

//提供一个共有接口,供外界得到员工的名字

//因为这个函数只是简单地返回一个属性值,所以把它定义在类的声明中,使其成为一个内联函数,提高性能

string getname()

{

return m_strname;

};

//员工类的属性,上面是员工的行为

//因为这些属性需要遗传给它的派生类,所以这里将其访问级别设置为protected:

protected:

//入职时间

int m_nyears;

//姓名

string m_strname;

};

//下面的都是派生类

//经理类,因为经理是员工中的一种,所以它从员工类emplyee派生

class manager : public emplyee

{

public:

//使用基类的构造函数,完成堆属性的初始化工作

manager(string strname,int nyears):emplyee(strname,nyears)

{};

public:

//对基类提供的纯虚函数进行自定义

//根据需求描述我们使用了不同的工资计算方式,利用面向队形的堕胎机制,使得同名的函数在不同的派生类中可以有不同的实现。

virtual int getsalary()

{

return 5000 * m_nyears + 10000;

}

};

//普通员工类

class worker: public emplyee

{

public:

work(string strname,int nyears):emplyee(strname,nyears)

{};

public:

//对基类的纯虚函数进行自定义

virtual int getsalary()

{

return 200 * m_nyears +2000;

}

};

完成员工类及其派生类之后,就可以在工资管理系统类salarysystem中创建对象并使用这些对象来代表员工,对工资进行管理。salarysystem实现如下:

//salarysystem.h头文件

//定义一个常量表示最大员工数

const int max_count=1000;

//工资管理系统

class salarysystem

{

public:

//构造函数和析构函数

salarysystem(void);

~salarysystem(void);

//工资管理系统行为

public:

//输入员工信息

void inputemplyee(void);

//显示员工信息

void displaysalary(void);

//计算获得平均工资

double getaversalary(void);

//工资管理系统的属性

//因为这些属性仅仅供工资管理系统系统自己使用,所以我们将其访问级别设置为private

private:

//当前员工总数

int m_count;

//用于保存所有员工对象

//这里将员工对象的指针保存到数组中,通过指针访问员工对象

emplyee* m_arremplyee[max_count];

};

#include "stdafx.h"

#include"salarysystem.h"

salarysystem::salarysystem(void) //构造函数,对类的属性进行初始化

{

m_ncount=0;   //将员工总数初始化为0

}

salarysystem::~salarysystem(void)    // 析构函数,清理资源,释放内存

{

for (int i=0;i<m_ncount;++i)   //循环遍历保存员工对象指针的数组,清理资源

{

emplyee* pemplyee=m_arremplyee[i];

delete pemplyee;  //销毁对象,释放内存

m_arremplyee[i]=null;   //将相应指针设置为null,不可访问

}

}

void salarysystem::inputemplyee(void)  //获取用户输入

{

cout<<"请输入员工信息\n"<<

"格式:员工姓名 入职时间 是否为经理级别\n"<<

"例如:chenliangqiao 4 0\n"<<

"输入end表示输入结束"<<endl;

string strname="";  //局部变量,用于接收用户输入

int nyears =0;

bool bmanager=false;

int nindex=0;

while(nindex<max_count)

{

cin.clear();//清空输入流

cin>>strname>>nyears>>bmanager;//从输入流读取用户输入的数据

if ("end"==strname)

break;

emplyee* pemplyee=null;//根据用户输入创建相应的员工对象

if (bmanager)

{

pemplyee=new manager(strname,nyears);//如果用户输入的是一个经理,则创建manager对象

}

else

{

pemplyee=new worker(strname,nyears);//如果用户输入的是一个普通员工,则创建worker对象

}

m_arremplyee[nindex]=pemplyee;//将创建对象指针保存到数组中

++nindex;//索引值递增,开始下一次录入循环

}

m_ncount=nindex;//保存输入的员工总数

}

void salarysystem::displaysalary(void)//显示输出工资信息

{

cout<<"工资管理系统"<<endl;//显示工资信息

cout<<"当前员工总数:"<<m_ncount<<

"\n平均工资是:"<<getaversalary()<<endl;

cout<<"员工具体工资信息如下:"<<endl;

//循环遍历保存员工对象指针的数组,输出每个员工对象的具体信息,这里使用的是基类指针调用基类的共有接口函数,但是如果这个接口函数是虚函数,那么他们将调用这个指针所只想的实际对象的相应函数。例如,这里对gesalary()函数的调用,编译器将根据pemplyee这个基类指针所指向的具体对象是manager还是worker来决定到底是调用manager类中的getsalry()实现还是worker类中的getsalary()实现。这就是面向对象中多态的体现。

for (int i=0;i<m_ncount;++i)

{

emplyee* pemplyee=m_arremplyee[i];

cout<<pemplyee->getname()<<"\t"<<

pemplyee->getsalary()<<endl;

}

}

double salarysystem::getaversalary()

{

int ntotal=0;

for(int i =0;i<m_ncount;++i)

{

emplyee* pemplyee=m_arremplyee[i];

ntotal += pemplyee->getsalary();

}

return (double)ntotal/(m_ncount);

}

完成工资管理系统类salarysystem之后,我们只需在主函数中简单地使用这个类就完成了整个系统。

#include "stdafx.h"

#include "salarysystem.h"//引入salarysystem声明所在的头文件

int _tmain(int argc, _tchar* argv[])//在主函数中使用salarysystem对象

{

salarysystem nsalarysys;//创建salarysystem对象

nsalarysys.inputemplyee();//获取用户输入

nsalarysys.displaysalary();//显示具体的工资信息

return 0;

}

高手是这样炼成的。

c++类对象的内存模型

类是对属性和行为的封装,在类的对象中也应该有属相(成员变量)和行为(成员函数)

也就是在内存中也应该有对象的成员变量和成员函数

this指针是c++中的一个关键字,它代表只想当前对象的指针,成员函数中的成员变量就是通过this指针找到自己所属的对象。

利用该指针,可以访问到该对象的所有成员变量和成员函数。

这是一个成员变量通过this指针找所属对象的过程。

class base

{

public:

int changevalue(int nval)//成员函数访问成员变量

{

this->setvalue(nval)//通过this指针访问成员函数

return this->m_nval;//通过this指针访问成员变量

}

};

class base//base类

{

public:

void setvalue(int nval)//成员函数访问成员变量,setvalue是base类的成员函数

{

m_nval=nval;

}

private://类的成员变量,m_nval是base类的成员变量

int m_nval;

};

base abase;//创建对象调用其成员函数,abase是一个对象

abase.setvalue(1);调用成员函数对成员变量进行赋值

this指针帮助指向当前对象,上面abase是对象

class base

{

public:

void setvalue(int nval)//成员函数setvalue访问成员变量nval

{

this->m_nval=nval;//显示使用this指针访问成员变量

}

};

当通过某个对象调用它的成员函数时,系统会隐式地传递给成员函数一个指向这个对象的指针。

所以对成员变量的访问,就变成对这个对象所属成员变量的访问。

例如:通过abase对象调用setvalue()成员函数,那么在setvalue()成员函数中,隐藏的this指针就指向abase这个对象。

this->m_nval=nvla语句是对abase的m_nval成员变量赋值。

this指针---成员变量---成员函数---对象

利用指针,可以访问到该对象所有成员变量和变量函数

class base

{

public:

int changevalue(int nval)//成员函数访问成员变量

{

this->setvalue(nval)//通过this指针访问成员函数

return this->m_nval;//通过this指针访问成员变量

}

};

更多的情况下,this指针用来返回指向对象本身的指针以实现对象的链式引用,或者避免对同一对象进行赋值操作。

class point //描述一个点位置的类

{

public:

point(int x,int y):m_nx(x),m_ny(y)

{};

void operator=(point& pt)//重载赋值操作符"=",进行赋值操作

{

if (this !=&pt)//判断传递过来的参数是否是这个对象本身,如果是同一个对象,则不进行赋值操作

{

m_nx=pt.m_nx;

m_ny=pt.m_ny;

}

}

point& move(int x,int y)//移动点的位置

{

m_nx +=x;

m_ny +=y;

return *this;//返回对象本身,这样可以利用函数返回值进行链式引用

}

private:

int m_nx;

int m_ny;

};

c++中指针最难,指针也是最厉害的。

20150513

指针的运算

指针是一种基本数据类型,可参与算术运算,关系运算,赋值运算

最常用的指针运算时加减运算

例子:使用指针遍历整个数组

int narray[3]={1,2,3};//定义一个数组

int* pindex=narray;//将数组的起始地址复制给指针pindex

cout<<"指针指向的地址是:"<<pindex<<endl;//输出指针指向的地址

cout<<"指针指向的数据的值是:"<<*pindex<<endl;//输出值

pindex++;

cout<<"指针指向的地址是:"<<pindex<<endl;//输出指针指向的地址

cout<<"指针所指向的数据的值是:"<<*pindex<<endl;//输出值

int型指针加1,地址增加4个单位

字符型指针加1,地址增加1个单位

双精度型指针加2,地址增加16个单位。

将null跟指针进行比较,是判断一个指针是否可用的常用手段,可以有效避免指针的非法访问

int * pint;//定义一个指针,这时指针是一个随机值,指向随机的一个内存地址

pint=null;//将指针赋值为null,表示指针还没有合适的值,不可用

int narray[10];

pint=narray;//将数组首地址赋值给指针,这里赋值的是数值的首地址

if (null !=pint)//判断指针是否初始化完成

{

//指针有效,可以开始使用指针

}

null的讲解

是一个宏

#define null 0

实际上就是整数0,常用null值表示一个指针变量是空指针,它没有指向一个正确的内存地址,而是一个无效的不可访问的指针。

除了用null宏,还可以用nullptr表示一个空指针:

int* pint=nullptr;//定义一个指针,并将它赋值为空指针,表示此时指针不可用

if(nullprt==pint)//判断指针是否为空指针,如果是空指针,就对其进行赋值

{

pint=&narray;//将数组的首地址复制给指针

}

void函数的介绍

void体现的是一种抽象,更多用来修饰和限制一个函数。

如果一个函数没有返回值,则可用void作为这个函数的返回值类型,表示这个函数没有返回值;如果一个函数没有形式参数列表,也可以用void作为其形式参数,表示这个函数不需要任何参数。

void作用:

void类型的修饰作用

void类型指针作为指向抽象数据的指针,可以作为两个具有特定类型指针之间相互转换的桥梁。

如果两个指针的类型相同,可以直接在两个指针之间互相赋值;如果两个指针指向不同的数据类型,则不许使用强制类型转换运算符,把赋值操作符右边的指针类型转换为左边的指针类型

int* pint;   //指向整型数的指针

float* pfloat;//指向浮点数的指针

pint=pfloat;  //直接赋值会产生编译错误

pint=(int*)pfloat; //必须强制类型转换后进行赋值

当使用void类型指针时,就没有类型转换的麻烦,

void* pvoid;  //void类型指针

int* pint;  //int类型指针

pvoid=pint;  //任何其他类型的指针都可以直接赋值给void类型指针

int8 pint;

float* pfloat=(float*)pint;//这种强制类型转换方式非常粗鲁,所以在c++中引入新的类型转换操作符static_cast

格式为:

static_cast<类型说明符>(表达式)

c语言类型转换和c++类型转换比较

c:

int nval1,nval2;

double fresult=((double)navl1)/nval2;

c++:

couble frelult=static_cast<double>(nval1)/nval2;

int n=2;

int* pn=&n;

int** ppn=&pn;

**定义了一个指向pn指针的指针

指向指针的指针的语法格式:

数据类型标识符** 指针变量名

20150514

使用指针作为函数参数,

使用指针作为函数返回值

引用

引用的本质就是变量的别名,就是变量的错号。对变量的引用的任何操作,就是对变量本省的操作

语法格式为:

数据类型& 引用名=变量名

//数据类型要跟引用的变量的数据类型相同,"&"符号表示声明的是一个引用,

int nintvalue=1;//首先定义一个整型变量

int& rintvalue=nintvalue;//定义一个整型引用并将它跟整型变量关联起来

//引用在声明的时候必须初始化

指针和引用的区别:

引用在声明的时候必须初始化,指针在任何时候都可以完成初始化

就是说引用必须与某个合法的事先存在的变量关联,而指针可以为空指针(null),可以不与任何变量建立关联。

引用的主要应用就是传递函数的参数和返回值

void increase(int& nval)//给整型数加1的函数increase

{

nval+=1;

}

int nint =1;

increase(nint);//变量nint的值为2,这里调用了incarease函数,nint时参数,

三种传递函数参数和返回值的方法:

  • 传值,传值是指直接将实际参数的值复制给形式参数,完成参数的传递
  • 传指针,传指针是指将需要传递的数据的指针作为参数进行传递
  • 传引用,传引用是指将需要传递的数据的引用作为参数进行传递

三种比较:

//传值,通过传值传入参数和传出返回值

int funcbyvalue(int x)

{

x=x+1;

return x;

}

//通过传指针传入参数和传出返回值

void funcbypointer(int* p)

{

*p=*p +1;

}

//通过传引用来传入参数和传出返回值

void funcbyreference(int& r)

{

r=r+1;

}

int _tmain(int argc,_tchar* argv[])

{

int n =0;

cout<<"n的初始值,n="<<n<<endl;

funcbyvalue(n);

cout<<"传值,n="<<n<<endl;//其内部的形式参数x指示外部实际参数n的一份拷贝,当对x进行运算时不能改变n的值,所以输出结果为0

funcbypointer(&n);

cout<<"传指针,n="<<n<<endl;//指针p是指向外部变量n的指针,改变指针p所指向的数据的值实际上就是改变n的值,所以在函数内部对指针p所指向的数据的改变,就直接反映到n的数值的修改,输出结果为1,因为刚开始p=0,所以p=0+1=1

funcbyreference(n);

cout<<"传引用,n="<<n<<endl;//引用r就是外部变量n的引用,引用r和变量n都是同一个数据,在函数内部改变r同样也会修改n,所以最终输出结果为2.因为n=r,刚开始就是1+1,所以结果为2

return 0;

}

输出结果

n的初始值,n=0

传值,n=0

传指针,n=1

传引用,n=2

在可以的情况下,尽量使用传引用来传递函数参数,尽量少用传指针(指针使用具有一定的危险性),也少用传值(效率低下)

传指针:效率高,可以同时传入传出参数

传值:形式简单自然,便于理解,代码可读性高

传引用:效率高,可以同时传入传出参数,形式自然

c++中的亡羊补牢---异常处理

程序报错可能导致:算法失效,程序运行时无故停止,程序崩溃

最简单的就是使用return语句

异常处理机制

异常处理语法格式:

//用try开始处理异常

try

{

//包含可能抛出异常的语句

}

catch(异常类型名[形参名]) //捕获特定类型的异常

{

//对异常进行处理

}

//可以有多个catch语句并列,捕获不同的异常

catch(...)//如果省略具体的异常类型用"..."表示,则表示捕获所有类型的异常

{

//对所有类型的异常进行处理

}

finally:

{

//对异常的最终处理,对所有异常的处理都会执行这些语句

}

throw关键字语法结构:

throw异常表达式;

//除法函数

double divide(int a,int b)

{

if (0==b)

throw "不能使用0作为除数";

return(double)a/b;

}

处理异常的3个步骤:

1、抛出异常2、捕获异常3、处理异常

double divide(int a,int b)

{

if(0==b)

throw"不能使用0作为除数";//抛出异常

return (double)a/b;

}

try

{

double fresult=divide(3,0);//捕获异常

}

catch(char* pmsg)

{

cout<<"程序运行发生异常:"<<pmsg<<endl;//处理异常

}

根据函数接口声明抛出正确类型的异常对异常得到正确的处理很重要。

如果在函数的声明中没有包括异常的接口声明,则此函数可以抛出任何类型的异常

如:double divide(int a,int b);

如果将throw关键字之后的异常类型列表留空,则表示这个函数不会抛出任何类型的异常。

double divide(int a,int b) throw();

异常使用注意的地方:

1、不要用异常替代可以处理的分支结构;异常只能用来代表”异常“,是非预期的错误状态,不能用异常来完全代替返回值

bool bresult =isfinished();

if (true==besult)

{

return true;

}

else

{

return false;//不要用抛出异常来代替可以明确表示状态的返回值

}

2、不要再循环中使用异常处理

如果要对循环中发生的错误进行处理,使用返回值是一个好的选择

3、如果函数的参数是指针,则需要在函数入口处对这个指针的有效性进行检查

学习编写更加复杂的c++程序

一个程序的所有代码都包含在它的源文件或头文件中

源文件:用于实现程序的各种功能,将程序划分为多个子模块,每个模块单独放在一个源文件中进行管理。.cpp结尾

时间: 2024-10-25 16:48:54

C++--学习笔记011的相关文章

IOS开发学习笔记011

xcode使用技巧 1.自动生成类 2.断点调试 3.代码段保存 4.注释标记 1.新建类,自动生成两个文件和基本结构 第一步  第二步,选择新建一个类,而不是一个源文件  第三步,书写类名一级自己要继承的父类  第四步.选择文件的保存路径  最后,自动生成两个文件,一个头文件,一个源文件,文件的基本结构已经写好了. 2.断点调试 断点调试可以观察程序运行过程中各种变量的变化过程,用于检查错误. 取消断点或者删除断点 3.代码段保存  这里要设置代码段的名称和要使用的快捷方式,用于在文件中输入快

python学习笔记011——内置函数__sizeof__()

1 描述 __sizeof__() : 打印系统分配空间的大小 2 示例 def fun(): pass print(fun.__sizeof__()) 运行 112

python学习笔记011——内置函数__module__、__name__

1 __module__描述 __module__ : 如果当前模块为顶层模块执行 则打印__main__ 如果当前模块为被调用模块的时候 打印当前模块的名称 2 __module__示例 def fun(): pass print(fun.__module__) 运行 __main__ 1 __name__描述 __name__  : 打印函数名称 2 __name__示例 def fun(): pass print(fun.__name__) 运行 fun #hello.py def say

python学习笔记011——内置函数dir()

1 描述 dir()函数可以查看(打印)对象的属性和方法.不管时那种对象(python中一切皆对象)类型(数据,模块)都有自己的属性和方法. dir() 函数不带参数时,返回当前范围内的变量.方法和定义的类型列表: 带参数时,返回参数的属性.方法列表. 如果参数包含方法__dir__(),该方法将被调用.如果参数不包含__dir__(),该方法将最大限度地收集参数信息. 2 语法 dir(object) object -- 对象.变量.类型. 3 返回值 返回对象的属性列表 4 示例 4.1 获

python学习笔记011——函数式编程

1 函数式编程 面向对象 ,面向过程 ,函数式编程 侧重函数的作用,注重函数结果的传递 函数可以被赋值,也可以接受其他的值 2 函数式编程特点 1.函数是一等公民 与其他变量一样,可以赋值和被赋值,可以作为参数传递 2.只用表达式不用语句 表达式是一个单纯的运算过程,总有返回值,语句是执行某种操作,没有返回值.即每一步运算要单纯,有明确结果. 函数式编程是为运算产生的而不是IO 3. 没有副作用 尽量不使用全局内容也不修改系统变量 4.引用透明 函数运行结果因为参数而发生变化,而不是因为系统的状

linux用户、组和权限——学习笔记

linux用户.组和权限--学习笔记 1.linux用户user 2.linux组group 3.用户和组的配置文件 3.1.Passwd文件格式 3.2.shadow 文件格式 3.3.group文件格式 3.4.gshdow文件格式 4.用户和组管理命令 4.1.用户管理命令 4.2.组帐号维护命令 4.3.用户创建:useradd 4.4.小实验 4.5.用户属性修改 4.6.删除用户 4.7.查看用户相关的ID 信息 4.8.切换用户或以其他用户身份执行命令 4.9.设置密码 4.10.

义隆单片机学习笔记之(三) 应用例程

常用寄存器: 0x01 (R1) 计时器 0x02 (R2)程序计数器 PC 0x03 (R3)状态寄存器 0x04 (R4)间址寄存器 0x05 (R5)IO PORT 5 0x06 (R6)IO PORT 6 ----- (IOC5)P5的输入输出配置 ----- (IOC6)P6的输入输出配置 0x0f (ISR,读)中断信号指示寄存器(第三位有效,分别对应于3个中断源) 0x0f (IOCF,写)中断屏蔽标志 0x0E (IOCE)(IO60作为中断输入的配置与看门狗的开关在一个寄存器中

[51单片机学习笔记TWO]----蜂鸣器

蜂鸣器音乐播放实验 首先应该了解一下蜂鸣器音乐播放的原理,在这里我只讲一下电磁式蜂鸣器驱动原理(还有一种是压电式蜂鸣器): 电磁式蜂鸣器驱动原理: 蜂鸣器发声原理是电流通过电磁线圈,使电磁圈产生磁场来驱动振动膜发声的.因此需要一定的电流才能驱动它,而单片机I/O引脚输出的电压较小.单片机输出的TTLK电平基本驱动不了蜂鸣器,因需要增加一个放大电路.这里用三极管作为放大电路.下面是原理图: 我这里的J8端是跟芯片的P1^5端口相连,当P1^5输出高电平时,三极管截止,蜂鸣器不发声,反之,输出低电平

Web前端学习笔记(001)

....编号    ........类别    ............条目  ................明细....................时间 一.Web前端学习笔记                                    2016年6月15日10:38:53    /****************************************************************begin******************************