现在的位置: 首页 > 综合 > 正文

每日学习 兜兜转转 7.5

2017年11月22日 ⁄ 综合 ⁄ 共 4104字 ⁄ 字号 评论关闭


学习博客上的各种杂知识 兜兜转载


C解析


是当今主流程序设计方法-面向对象的核心机制
类是面向对象程序设计中对具有相同性质对象的抽象

对象是类的实例,相对抽象地类,对象是具体的实体

对象是类的实例。是生成对象的”模板“


  2.printf常见使用格式
                 printf(char *format,arg1,arg2 ...);
    prinft定义格式
                   int printf(char *format, ... )
         此处的省略号...表示参数的数量与类型可变

关键:如何处理...代表的参数表,它甚至连名字都没有。答案在标准头文件<stdarg.h>中的一组宏定义,这组宏定义提供了遍历参数表的方法。va_list类型用于声明一个变量,该变量将依次引用参数表的各个参数。va_startva_list变量指向第一个无名参数。va_arg返回参数表中的一个参数,并将va_list变量指向下一个无名参数。va_arg根据一个数据类型名决定返回参数的类型与指针移到的步长。va_end用于最后做一些清理工作。

字符串常量

"acb132"

字符串常量就是字符数组,内部以'\0'结尾

枚举常量

默认第一个枚举名的值为0,第二个为1,类推,

外部变量与静态变量默认初始值为0

自动变量的默认初始化为未定义值(为垃圾)  

#include<stdio.h>
void swap(int *a,int *b)
{
int *t;
t=a;
a=b;
b=t;
}

int main()
{
int a=10,b=20;
int *pa,*pb;
pa=&a;
pb=&b;
printf("%d %d ",*pa,*pb);
swap(pa,pb);
printf("%d %d ",*pa,*pb);
}

上面输出10 20 10 20

简单的函数传值 传址问题。。。

给的是地址 把地址当成常量传值 地址这个量进行交换 返回回来输出不变

更改下swap函数

void swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}

输出:10 20 20 10

给的是地址 传过去是地址。把地址中的值交换了 所以返回输出值交换了


extern

声明变量在外部定义

例1:外部变量定义在文件开头,在调用它的函数的上面,extern可省略

外部变量定义在文件中间,在调用它的函数的下面,必须使用extern声明

主文件使用从文件里的外部变量,extern可以省略

从文件使用主文件的外部变量,必须使用extern声明

C++

1)构造函数用来对类的数据成员进行初始化,析构函数用来释放已经实例化的对象。

一个类除了需要定义一般的构造函数外,还要定义拷贝、赋值、析构三大函数;

缓冲区:

每个输出流都管理一个缓冲区,用来保存读写的数据。导致缓冲区的刷新原因:

  • 程序正常结束,作为main函数的return操作的一部分,缓冲被刷新
  • 缓冲区满,刷新缓冲区
  • 操作符endl可以用来显示的刷新缓冲区
  • 默认情况下,写到ceer的内容都是立即刷新的
  • 一个输出流可能被关联到另一个流,此时缓冲区会被刷新
除了endl,还有flushends两个操作符可以刷新缓冲区,如下所示:
  1. cout << "scott" << endl;//输出scott和一个换行符,然后刷新缓冲区  
  2. cout << "scott" << flush;//输出scott 然后刷新缓冲区  
  3. cout << "scott" << ends;//输出scott和一个空字符 然后刷新缓冲区

STL(Standard Template Library)

标准模板库。从根本上说,STL是一些“容器”的集合,这些“容器”有list, vector,set,map等,

STL也是算法和其它一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。每一个C++程序员都应该好好学习STL。

大体上包括container(容器)、algorithm(算法)和iterator(迭代器),容器和算法通过迭代器可以进行无缝连接。

2.顺序容器:


vector      可变大小数组。支持快速随机访问。在尾部之外的位置插入/删除元素速度可能很慢。

deque        双端队列。支持快速随机访问。在头尾插入/删除元素速度很快。

list       双向链表。只支持双向顺序访问。在list任何位置插入/删除速度都很快。

string       与vector类似。

添加元素:

c.pusk_back(t) 在c尾部加入元素t——list、deque、vector支持

c.push_front(t) 在c头部加入元素t ——list、deque支持,vector不支持。

c.insert(p, t)     在迭代器p指向的元素之前创建一个值为t的元素,返回指向新元素的迭代器。

c.insert(p, n, t) 在迭代器p指向的元素之前插入n个值为t的元素,返回指向新添加第一个元素的迭代器。

c.insert(p, b, e)将迭代器b和e指定的范围内的元素插入到迭代器p指向的元素之前。

删除元素:

c.pop_back() 删除c中尾元素

c.pop_front() 删除c中首元素——同样,vector不支持

c.erase(p)     删除迭代器p指向的元素,返回一个执行被删元素之后元素的迭代器

c.erase(b, e) 删除迭代器b、e范围内元素

c.clear()        删除c中所有元素

3.迭代器

迭代器范围:一个左闭右开区间[begin,
end)

iterator、const_iterator、reverse_iterator、const_reverse_iterator;

  1. vector<int> vec(10);//vec含10个元素,每个元素都是0  
  2. vector<int>::iterator i = vec.begin();//获取指向第一个元素的迭代器。  
  3. *i = 10;//解引用可以作为左值改变容器中的值  

1.泛型算法

find函数用于找出容器中一个特定的值,有三个参数

  1. int val =  10;//val为我们需要查找的值  
  2. auto result = find(vec.begin(), vec.end(), val):

如果没有找到,返回第二个参数,即容器尾部迭代器vec.end(),表示失败。


count函数用来统计容器中元素个数

count(str.begin(), str.end(), val); 


accumulate函数定义在numeric头文件中,用于统计指定迭代器范围内元素的和。

第三个参数是和的初值,用一般为0.

int num = accumulate(vec.begin(), vec.end(), 0);
 


fill函数用来向给定范围内容器写入数据。

fill(v.begin(), v.end(), 0); //将每个元素置为0

sort(words.begin(), words.end());
 




关联容器

与顺序容器不同,关联容器的元素是按关键字来访问和保存的。而顺序容器中的元素是按他们在容器中的位置来顺序保存的。

关联容器最常见的是map、set、multimap、multiset

map的元素以键-值【key-value】对的形式组织:键用作元素在map中的索引,而值则表示所存储和读取的数据。

set仅包含一个键,并有效的支持关于某个键是否存在的查询。

pair类型

首先介绍下pair,pair定义在utility头文件中,

一个pair保存两个数据成员,类似容器,pair是一个用来生成特点类型的模板。

当创建一个pair时,我们必须提供两个类型名。

pair<string, string> a; //保存两个string

pair<string, int> b; //一个保存string,一个保存int

可以使用make_pair来构建一个pair

查找与统计map中的元素:

    1、使用m.count(k); 统计m中k出现的次数

    2、使用m.find(k);查找以k为索引的元素,如果存在返回指向该元素的迭代器,否则返回末端迭代器

动态内存

C++中,动态内存管理是通过一对运算符完成的:new和delete。

C语言中通过malloc与free函数来实现先动态内存的分配与释放

2.智能指针

由于 C++ 语言没有自动内存回收机制,每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见。

       用智能指针便可以有效缓解这类问题

       C++11新标准提供了两种智能指针,负责自动释放所指向的对象。

shared_ptr允许多个指针指向同一个对象;unique_ptr则"独占"所指向的对象。

标准库还定义了一个名为weak_ptr的伴随类;这三种类型都定义在memory头文件中。


    对于编译器来说,智能指针实际上是一个栈对象,并非指针类型,在栈对象生命期即将结束时,智能指针通过析构函数释放有它管理的堆内存。所有智能指针都重载了“operator->”操作符,直接返回对象的引用,用以操作对象。访问智能指针原来的方法则使用“.”操作符。

       访问智能指针包含的裸指针则可以用 get() 函数。由于智能指针是一个对象,所以if (my_smart_object)永远为真,要判断智能指针的裸指针是否为空,需要这样判断:if (my_smart_object.get())。

       智能指针包含了 reset() 方法,如果不传递参数(或者传递 NULL),则智能指针会释放当前管理的内存。如果传递一个对象,则智能指针会释放当前对象,来管理新传入的对象。

深拷贝浅拷贝

>浅拷贝: 指的是在对象复制时,只对对象中的数据成员进行简单的赋值;默认拷贝构造函数执行的也是浅拷贝。        大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了。

>深拷贝:当类的成员变量有指针类型时,拷贝对象时应该为指针变量重新分配好空间,避免浅拷贝中只拷贝指针的    值,使得两个指针指向同一块内存空间。

抱歉!评论已关闭.