1、程序由函数组成,函数只完成自己特定的功能即可
   把函数声明写在头文件里(想使用函数时,可直接导入头文件,调用函数),把函数实现写在".cc"文件中
   把多个".cc"文件编译成可执行文件 ->分别编译成".o"文件,再连接到一起
  
2、值传递
   函数中的参数传递是值传递,形参只是实参的一份拷贝数据,在函数中改变形参的值,对实参无影响
  
3、作业分析:显示层(与用户的交互)
             操作数据(完成业务逻辑) biz层
             数据(id , password , balance )                       
  
  
Bank实现代码 
================================================================
            biz.h
================================================================
//operation

/* p : Password of account .
 * b : balance of account .
 * return : id of account .
 */
long create( int p , double b );
void save( double sum ) ;

/*
 * return : 0 success , otherwise -1 returned .
 */
int withdraw( int p , double sum ) ;
double query( int p ) ;
long generateId();

================================================================
            biz.cc
================================================================

#include <iostream>
using namespace std;
static long id ;
static int passwd ;
static double balance ;
#include <iostream>
using namespace std;
long generateId(){
 static int id = 1 ;
 return id++ ;
}
long create( int p , double b ){
 id = generateId();
 passwd = p ;
 balance = b ;
 return id ;
}
void save( double sum ){
 balance += sum ;
}
int withdraw( int p , double sum ){
 if( p != passwd ){
  cout<<"invalid password ." << endl;
  return -1 ;
 }
 if( balance < (sum + 10) ){
  cout<<"no enough money ." << endl;
  return -1 ;
 }
 balance -= sum ;
 return 0 ;
}
double query( int p ){
 if( p != passwd ){
  cout<<"invalid password " << endl;
  return -1 ;
 }else{
  return balance ;
 }
}

================================================================
            menu.h
================================================================
int showMenu();

void createMenu();
void saveMenu();
void withdrawMenu();
void queryMenu();
================================================================
            menu.cc
================================================================
#include "biz.h"
#include <iostream>
using namespace std;

int showMenu(){
 cout<<"create ------> 1 " << endl;
 cout<<"save   ------> 2 " << endl;
 cout<<"withdraw ----> 3 " << endl;
 cout<<"query -------> 4 " << endl;
 cout<<"exit --------> 0 " << endl;
 cout<<"enter your choice >";
 int c ;
 cin>>c ;
 if( !cin ){
  return -1 ;
 }else{
  return c ;
 }
}

void createMenu(){
 int passwd ; 
 double balance ;

cout<<"\tenter password >";
 cin>>passwd ;
 cout<<"\tenter balance >";
 cin>>balance ;

long id = create( passwd , balance );
 cout<<"======================"<<endl;
 cout<<"create account ok , id = " << id <<endl;
 cout<<"======================"<<endl;
}
void saveMenu(){
 double sum ;
 cout<<"\tenter sum >";
 cin>>sum ;
 
 save( sum ) ;

cout<<"======================"<<endl;
 cout<<"save money ok "<<endl;
 cout<<"======================"<<endl;
}
void withdrawMenu(){
 int passwd ;
 double sum ;
 cout<<"\tenter password >";
 cin>>passwd ;
 cout<<"\tenter sum >";
 cin>>sum ;

int ret = withdraw( passwd , sum ) ;

if( ret == 0 ){
  cout<<"========================"<<endl;
  cout<<"withdraw successful . "<<endl;
  cout<<"========================"<<endl;
 } 
}
void queryMenu(){
 int passwd ;
 cout<<"\tenter password >";
 cin>>passwd ;

double ret = query( passwd ) ;
 if( ret != -1 ){
    cout<<"============================"<<endl;
    cout<<"BLANCE : $ " << ret << endl;
    cout<<"============================"<<endl;
 }else{
    cout<<"============================"<<endl;
    cout<<"invalid password "<<endl;
    cout<<"============================"<<endl;
 }
}
================================================================
            main.cc
================================================================
#include <iostream>
#include "menu.h"
using namespace std;
int main(){
 int c = 0 ;
 do{
  c = showMenu();
  if( c == -1 ) { break ; }

switch( c ){
    case 1 :
   createMenu();
   break;
    case 2 :
   saveMenu();
   break;
    case 3 :
   withdrawMenu();
   break;
    case 4 :
   queryMenu();
   break;
    case 0 :
   cout<<"===================="<<endl;
   cout<<"Good Bye "<<endl;
   cout<<"===================="<<endl;
   break;
    default :
   cout<<"===================="<<endl;
   cout<<"invalid option, try again.";
   cout<<endl;
   cout<<"===================="<<endl;
   break;
  } 
 }while( c != 0 );
 return 0 ;
}
================================================================

4、数组
   (1)声明数组    <元素类型> 数组名[元素个数]   int intArray[100]; -->intArray 是个集合,有100个元素,每个元素都是int类型的
   (2)初始化数组 
   (3)使用        通过数组的下标来访问数组中的元素,下标从0开始  intArray[0]=100; -->intArray数组中的第一个元素赋值为100
  
   数组声明时,元素个数必须是常量表达式
   数组声明带有初始化,则可直接为数组赋值
   在数组声明时,必须指明数组长度,若在声明时候初始化,数组长度可省
   int a1[2]={100,200}; 长度2
   int a2[] = {5,6,7}; 长度3
  
   对于数组中的元素个数,比声明时的多,则会报错,这样的越界访问,对整个程序来说会有很严重的后果!!!
                         比声明少,系统会把余下的没有定义数据的元素初始化为0
                     
   不初始化的数组,其中的元素数据为随机数
  
   下标工作的原理:
           表示编号,还表示当前元素相对于数组起始位置的偏移量
           计算机通过偏移量找到元素在内存中的位置
          
5、数组的排序
   选择排序:找出最小的放在第一个位置
             数组元素有n个,需要找n-1次,需要比较n-i次(i为开始元素的位置)
            
6、多维数组
    二维数组;一个数组中的每个元素是个数组
            声明: int iA[5][10];  -->“5”代表数组有5行,“10”代表数组有10列
                   声明时,第一维可以省略!
            确定一个元素需要2个下标
           
7、结构
   用户自己定义的一组数据类型
   声明结构时,编译器不会分配空间,在声明一个结构的变量的时候才会为其分配空间
   结构中的成员是多个简单类型组成的
   用 “结构名.成员名”来操作其中的成员变量
   strcpy(p.name,"huxz");为char数组赋值
   结构类型的变量间也可以相互赋值
  
   结构的大小就是所有成员的大小之和(每个成员的大小必须是int类型的整倍数,当不够时,会自动补齐)
   Unix上还要求,结构的大小是结构的最大的成员的整倍数
   size(of)  计算结构大小

作业:把银行系统用结构改写,要求可以开多个账户(定义一个account类型的数组保存)
      struct account{
           long id;
           int password;
           double balance;
      }
     
      create(int password,double balance);
      void save(int id , double sum);
      int withdraw(int id,int password,double sun);
      double query(int id,int password);

1、变量的存储
   (1)内存是一块空间,把其中的每个字节做了编号,为了以后计算机能通过编号找到数据
   (2)编址方式:绝对编址(在整个程序中使用),相对编址(字节相对于逻辑0偏移量,在进程中使用)

2、取变量地址
   (1)"&"  &i 表示取内存中i的地址
        地址的编址用十六进制表示
   (2)逻辑0在代码区
        全局变量在数据区,地址的编址是大于0的
        局部变量在栈区,地址的编址是小于0的
   
3、数组、结构的地址
   (1)数组中的数据在内存中是连续存储的。 数组中每个元素的地址相差的值应为数组元素类型的大小。
   (2)结构的地址:
        结构的空间是连续的。
        结构的起始地址与第一个成员变量的地址是一样的。

4、存储地址—
   指针:存储变量的地址
   指针的类型由将要保存的地址的变量类型决定
   int*只能保存int变量的地址
   指针赋值一定要是同类型的指针才能相互赋值!
  
5、指针的运算
   (1)指针和指针之间的运算
      “+”,“*”,“/” 指针与指针间是不能做这些运算,没有意义!
      “-” 可以做减法运算,以“sizeof(指针类型)”作为计算单位的!    注意:要同类型的指针才能做此运算,不同的话,会对运算单位产生歧义。
  (2)指针和数字之间的运算(加、减都可以)
      int i = 100;
      int * p = &i;
      打印 p+1  -> 相当于在地址上加4,因为存储的变量是int类型的
           p+2  -> 相当于在地址上加8
  
6、通过指针访问所指向的变量
   *p 代表指针p所指向的变量  *p <=> i
  
   指针在声明的时候,即初始化
   int * p = NULL;  表示没有明确指向,不能 *p ,会出现 “段错误”的异常  -->空指针
  
   段错误原因 (1)空指针
              (2)数组越界
              (3)递归的条件不正确
             
7、课堂练习
    用指针打印出数组中个元素的值
    #include <iostream>
    using namespace std;

int main(){
       int ai[6]={34,4,12,67,34,2};
       int *p = &ai[0];
       for(int i = 0 ; i < 6 ; i++){
           cout <<"a[" << i << "]=" <<*(p+i) << endl;
       }
       return 0;
    }
   
    int *p = ai ; 数组的本质就是用指针实现的,数组的名字就代表数组的首地址(起始地址)
                 数组的名字是指向数组首地址(a[0])的指针
                
    ai 数组名,就是指向数组首地址的指针,可以用下标取元素,也可以把数组名当指针来访问元素   *(ai+n)
    p  指针名,也是指向首地址的指针,也可以通过下标(像数组名一样)访问数组元素   
    p[n] <=>  *(p+n)
   
8、结构指针
   struct person{
        int id;
        int age;
   }
  
   int main(){
        person per = {1,20};
        person* p = &per;
        cout << "per.id ="<<per.id<<endl;  //通过结构名取成员变量
        cout << "per.age=" << per.age <<endl;
        cout <<"======================"<<endl;
        cout << "(*P).id=" << (*P).id <<endl;   //通过指针访问结构的成员变量 
        cout << "(*P).age=" << (*P).age <<endl;  //   (*p).id  <=>  p->id   只有结构指针可以这样使用 
        cout <<"======================"<<endl;
        cout << "p->id=" << p->id <<endl;  
        cout << "p->age=" << p->age <<endl;
      
        return 0;
   }
  
9、指针的地址
   指针变量在内存中占4个字节(与类型无关,因为保存地址的指针只保存地址)
   保存int型指针(int* p = &i)的地址用int**保存(int** pp = &p)
  
   #include <iostream>
   using namespace std;

int main(){
     int i = 0 ;
     int * p = &i ;
     int ** pp = & p ;

cout<<"&i = " << &i << endl;
     cout<<"p = " << p << endl;
     cout<<"&p = " << &p << endl;
     cout<<"pp = " << pp << endl;
     cout<<"&pp = " << &pp << endl;

cout<<"i = " <<i << endl;
     cout<<"*p = " << *p << endl;
     cout<<"*pp = " << *pp << endl;
     cout<<"**pp  = " << **pp << endl;
 
     return 0 ; 
    }
   
执行结果:
&i = 0xffbffbec
p = 0xffbffbec
&p = 0xffbfbe8
pp = 0xffbfbe8
&pp = 0xffbffbe4
i = 0
*p = 0
*pp = 0xffbffbec
**pp = 0
  
     pp  ->  p  ->  i   指向关系
      pp=&p     p=&i
      *pp=p     *p=i       **pp=*p=i

1、数组指针声明的时候不用初始化,声明以后就指向数组的首地址了,以后不允许改变,所以,数组指针可以认为是一个常量,一旦赋值就不能改变

2、char数组
   (1)打印char数组的名字即打印数组的内容
   (2)对于字符数组,'\0'是结束标志 
        字符 '\0' = 数组0  可以认为字符'\0'的ASCII码就是0
        要保存5个字符,就要把字符数组长度声明为6
  
   (3)strcpy()和memset()
        给一个字符串数组赋值 strcpy(),自动为字符串补 '\0'
        在使用strcpy之前,要调用memset(str,0,sizeof(str));初始化一片内存
                                   str  ->   初始化内存的起始位置
                                   0    ->   初始化的值 (初始化为0,清除垃圾数字)
                           sizeof(str)  ->   初始化空间的大小
    (4)strlen(str)
       计算实际存储的字符个数,不包括'\0'
   
    (5)strcmp(str1,str2)
       比较2个字符串是否相等
       实际比较的两个字符串的ASCII码的大小,返回0则内容一样
      
    (6)字符串的拆分  strtok(a,b);
       a、被拆分的字符串名字,当此处是NULL时,表示要拆分的不是新串
       b、分隔符号
       此函数调用一次,拆分一次
       当此函数返回NULL时,则表明拆分完毕
      
       "Hello World"叫字符串常量,存储在data数据区里,类型就是char*
           其值是一个地址,指向数据区里的一块空间
           数据区里的空间保存的内容就是"Hello World"
      
       char line[50];
       strcpy(line,"1:liucy:20:male");
      
       char *p = strtok(line , ":");  //p指针指向的变量
       cout << p << endl;
       while(p != NULL){
           p = strtok ( NULL , ":" );
           cout << p << endl;
       }
      
      
    (7)  strcpy(name,"1234"); //name是个变量,可以改变
           strcpy(p,"1234"); //p是个指针,指向一个字符串,是常量,不能改变 
           p = "1234"; //这样是正确的
           指针指向的是常量,不能通过指针改其值,若指向变量,则可以通过指针改变变量的值
          
    (8)字符串连接 strcat(sub,"world");
         连接条件:sub字符串数组的剩余长度要大于连接的字符串长度
        
         char *p = "Hello";
         strcat(p,""World); //error 指针指向一个常量,不能改变,所以指针后面不能添加东西
        
3、通过指针传递参数
   通过传递地址。改变变量的值
       
        #include <iostream>
        using namespace std;

void fn (int *pa){
           *pa = 2 * (*pa);  //*pa是指针pa指向的变量的值,在此做的操作,会对变量造成永久的改变
        }

int main(){
           int a = 100;
           fn(&a);          //把a的地址传个fn函数
           cout << a << endl;
           return 0;
        }
       
4、课堂练习
   字符串  “1:huxinzhe:20:male”
   要求:声明一个结构
           Person{
             int id;
             char name[50];
             int age;
             char gender[10];
           }
   拆分赋值 提示:atoi可以把字符串转换成int型
  
   #include <iostream>
   #include <string.h>
   #include <stdlib.h>
   using namespace std;

struct Person{
      int id;
      char name[20];
      int age;
      char gender[10];
   };

int main(){
       Person per;

char line[50];
      
       while(true){
            cout << "enter a string>";
            cin>>line;

if(strcmp(line,"exit")==0)
                break;
            char *p = strtok(line , ":");
            per.id = atoi(p);
           
            p = strtok(NULL , ":");
            strcpy(per.name,p);
           
            p = strtok(NULL , ":");
            per.age = atoi(p);
           
            p = strtok(NULL , ":");
            strcpy(per.gender,p);

cout <<"per.id     = " <<per.id << endl;
            cout <<"per.name   = " <<per.name << endl;
            cout <<"per.age    = " <<per.age << endl;
            cout <<"per.gender = " <<per.gender << endl;

}
       return 0;
   }
  
5、内存管理
   堆(heap):动态的内存申请与释放
   堆空间不能通过像( 数据区,栈)变量访问空间,要使用指针保存地址
  
   (1)堆空间的管理  new / delete
        new int
        new Person
       
        new 操作符返回值是地址,用指针保存
        int *p = new int;  //在堆空间中申请4个字节
        *p = 100;          //赋值
        delete p;          //释放空间
       
    (2)动态申请空间,对内存的使用变的方便,能更好的控制对内存的占用
         动态内存的指针不能重复赋值,这样会造成内存丢失
         释放空间后,还可以通过指针访问原来的数据。
         释放空间后,还可以再次通过指针赋值,释放的意思就是表示曾经申请的内存的标记位更改,别人可以使用
         这样会造成过期的指针更改重要数据,建议在释放指针以后 ,把指针赋值为NULL ,确保数据安全
         delete p ;
         p = NULL :
        
     (3)在申请空间的同时初始化
        int *p = new int(123);  申请4个字节大小,保存数字“123” 
       
    (4)int *p = new int[10];  一次在堆里申请10个int,并且申请的内存是连续的。
        *(p+1) , p[1]  都能取到下一个数据
        此时的*p就是第一个元素的值
        在释放的时候 delete[] p;  p = NULL; 确保释放的是多个指针 
       
     (5)在堆空间里申请结构
        Person *p = new Person;
        p->id = 1;
        // (*p).id = 1;
       
6、  传递参数
     最好传地址,节省内存(因为不用进行入栈,出栈操作,直接用指针访问数据)
     在参数前加const,可避免在函数内部对数据进行非法修改
    
     当一个数组做参数时,编译器会自动把数组的首地址传个函数
     所以在函数内部对数组的更改,就是通过指针对数组中元素的永久性更改
    
7、数组,存数据个数不限,通过一个函数insert()存数据,disp()打印数组

C++笔记 2的更多相关文章

  1. git-简单流程(学习笔记)

    这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...

  2. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  3. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

  4. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  5. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  6. NET Core-学习笔记(三)

    这里将要和大家分享的是学习总结第三篇:首先感慨一下这周跟随netcore官网学习是遇到的一些问题: a.官网的英文版教程使用的部分nuget包和我当时安装的最新包版本不一致,所以没法按照教材上给出的列 ...

  7. springMVC学习笔记--知识点总结1

    以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...

  8. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  9. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  10. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

随机推荐

  1. 8、java内部类

    一.基本介绍 内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. 内部类可以是静态static的,也可用public,default,protected和private修饰:而外部顶级 ...

  2. 用openssl生成SSL使用的私钥和证书,并自己做CA签名(转)

    本 文记叙的是一次基于SSL的socket通讯程序开发中,有关证书,签名,身份验证相关的步骤. 我们的场景下,socket服务端是java语言编写的,客户端是c语言.使用了一个叫做matrixssl的 ...

  3. MySQL Desc指令相关

    MySQL Desc指令相关   2011-08-09 11:25:50|  分类: my基本命令 |举报 |字号 订阅 1.desc tablename; 例如 :mysql> desc jo ...

  4. linux 和windows系统下同时可用的UML建模工具(umbrello),超强

    原文地址:linux 和windows系统下同时可用的UML建模工具(umbrello),超强 作者:zhangjiakouzf OPEN SOURCE 的 UML建模工具 -- umbrello   ...

  5. TP3.2:实现Ajax无刷新上传图片

    1.基于TP3.2+ajaxfileupload进行无刷新上传图片,本次只上传一张,多张以后搞出来再发 2.效果:   3.html代码: <html> <head> < ...

  6. HDUOJ -----Color the ball

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  7. HDUOJ-----2399GPA

    GPA Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  8. 【LeetCode】40. Combination Sum II (2 solutions)

    Combination Sum II Given a collection of candidate numbers (C) and a target number (T), find all uni ...

  9. 【LeetCode】136. Single Number (4 solutions)

    Single Number Given an array of integers, every element appears twice except for one. Find that sing ...

  10. Linux内存使用方法详细解析

    我是一名程序员,那么我在这里以一个程序员的角度来讲解Linux内存的使用. 一提到内存管理,我们头脑中闪出的两个概念,就是虚拟内存,与物理内存.这两个概念主要来自于linux内核的支持. Linux在 ...