C++笔记

C++笔记

一、输入输出

scanf 输入字符串,%c,空格是不会被跳过的

用scanf输入,出现非控制字符,则这些字符会被跳过

scanf("%d %c,%f:%d",&a,&b,&c,&d);
prinft("%d,%c,%f,%d",a,b,c,d);

这时候输入

12 k,3.75:290
// 12和k之间的空格不会被输入(注意%c,空格也算是一个字符)
// , : 不会被输入 (用scanf输入,出现非控制字符,则这些字符会被跳过)

则会输出

12,k,3.750000,290

二、变量

变量就是一个代号,程序运行时系统会自动为变量分配内存空间,于是变量就代表系统分配的那片内存空间,对变量的访问,就是对其代表的内存空间的访问

变量有名字和类型两种属性,不同变量的名字就对应了内存中的不同地址(记不同位置),而变量的类型,决定了一个变量占用多少字节

三、c++基本数据类型

1.int long short char的最高位(最左边)是符号位,为1则表示负数,为0则表示非零数。

2.一个字节等于8个比特,即8个二进制位

3.int 字节数4 取值范围

E = -2^{31} 到 2^{31}-1

因为有4个字节,一个字节8位,那么就有32位,最高位是符号位,也就是有31位,那么

4.sizeof(变量名) sizeof(类型名) 求占用字节数

5.有符号整数二进制表示形式

非负数: 1 0000 0000 0000 0001

负数: -1 1111 1111 1111 1111

将一个负整数表示为二进制的方法

  • 设置符号位为1
  • 其余位等于绝对值取反再加1

比如-1 设置符号位为1,绝对值为1,1的二进制表示形式

1000 0000 0000 0001 (设置符号位为1)

再取反

1111 1111 1111 1110 (符号位不用取反)

再加1

1111 1111 1111 1110
                  1
---------------------
1111 1111 1111 1111

所以-1的二进制表示形式就是1111 1111 1111 1111

6.数据类型的自动转换


int a = 18.99; // a为18

double d = 30; // d 为30.0

int k = 'a'
printf("%d", k) // 97

整形数据也可以转换为字符型数据,但是有个问题,整形数据有2 4 8字节,字符型数据只有一个字节,装不下下去,这时候的处理是:

只会留下最右边的一个字节(第0位到第8位),其他字节丢弃

四、友元函数、友元类

https://www.runoob.com/cplusplus/cpp-friend-functions.html

五、c++闭包,Lambda 函数与表达式

六、c++指针

  • 指针就是一个变量,声明如下:
Type *pr;

这个Type必须是一个有效的c++数据类型,例如int等

int main()
{
    int a = 10;
    int *prt;
    prt = &a;
    
    cout << &a << endl;
    // 输出指针所指变量的地址
    cout << prt << endl;
    // 输出指针所指变量的值(加*就是取值)
    cout << *prt << endl;
    // 输出存储这个指针变量的地址(加&就是取地址)
    cout << &prt << endl;
   return 0;
}


结果:
0x7ffd566597ec
0x7ffd566597ec
10
0x7ffd566597e0


  • 指针是可以进行算术运算的

比如一个int类型的指针ptr,如果这时候指针指向的地址是 0xbfa088b0,那么 ptr++ 后就是 0xbfa088b4 ,原因是ptr++后他会指向下一个整数位置,即当前位置往后移4个字节,之所以是4个字节,因为这个是int类型的指针,int类型是4个字节

  • 指针数组:就是一个存储指针变量的数组

声明

int *ptr[MAX]

一定要指定数据的个数MAX,不然编译不过

  • 数组指针

double balance[50];

balance是一个指向&balance[0]的指针

  • 指针常量
int * const p; 
int a,b;
int * const p=&a //指针常量
//那么分为一下两种操作
*p=9;//操作成功
p=&b;//操作错误

因为是常量了,所以他的值不允许修改,又因为是指针,所以他的值就是地址

但是可以修改这个地址的值

  • 常量指针

在定义指针变量的时候,数据类型前用const修饰,被定义的指针变量就是指向常量的指针变量

const int *p = &a; //常量指针
int a,b;
 const int *p=&a //常量指针
//那么分为一下两种操作
*p=9;//操作错误
p=&b;//操作成功

因为常量指针本质是指针,并且这个指针是一个指向常量的指针,指针指向的变量的值不可通过该指针修改,但是指针指向的值(地址)可以改变。

  • 指向指针的指针

一般的指针是指向一个变量的地址

指向指针的指向,就是一个指向指针变量的指针

定义

int **var;
#include <iostream>
 
using namespace std;
 
int main ()
{
    int  var;
    int  *ptr;
    int  **pptr;
 
    var = 3000;
 
    // 获取 var 的地址
    ptr = &var;
 
    // 使用运算符 & 获取 ptr 的地址
    pptr = &ptr;
 
    // 使用 pptr 获取值
    cout << "var 值为 :" << var << endl;
    cout << "*ptr 值为:" << *ptr << endl;
    cout << "**pptr 值为:" << **pptr << endl;
 
    return 0;
}


// 输出

var 值为 :3000
*ptr 值为:3000
**pptr 值为:3000

七、引用

引用变量:其实就是一个变量的别名

int i = 88;
int &r = i;

这时候r变量就是引用变量,我们可以对r变量进行赋值

r = 8;

这时候i和r变量的值都改成8了,原因就是r其实就是变量i的别名,所以对r操作,也就相当于对i操作

引用VS指针

引用很容易与指针混淆,它们之间有三个主要的不同:

  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。

把引用作为参数

// 函数定义
void swap(int& x, int& y)
{
   int temp;
   temp = x; /* 保存地址 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 x 赋值给 y  */
  
   return;
}

把引用作为返回值

double& setValues( int i )
{
  return vals[i];   // 返回第 i 个元素的引用
}

函数返回引用,其实也可以看作是返回的一个指针,所以可以直接把这个函数做为左值

setValues(1) = 20.23;

当返回一个引用时,要注意被引用的对象不能超出作用域。所以返回一个对局部变量的引用是不合法的,但是,可以返回一个对静态变量的引用。


int& func() {
   int q;
   //! return q; // 在编译时发生错误
   static int x;
   return x;     // 安全,x 在函数作用域外依然是有效的
}

八、结构体


struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

type_name结构体类型名称

object_names 是可以定义多个结构体变量

结构体作为函数参数

void printBook( struct Books book )
{
   cout << "书标题 : " << book.title <<endl;
   cout << "书作者 : " << book.author <<endl;
   cout << "书类目 : " << book.subject <<endl;
   cout << "书 ID : " << book.book_id <<endl;
}

指向结构的指针

struct Books *struct_pointer;


九、重载运算符和重载函数

函数重载

函数名相同,形参不同

不能通过返回类型的不同来重载函数


class printData
{
   public:
      void print(int i) {
        cout << "整数为: " << i << endl;
      }
 
      void print(double  f) {
        cout << "浮点数为: " << f << endl;
      }
 
      void print(char c[]) {
        cout << "字符串为: " << c << endl;
      }
};

运算符重载

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的

Box operator+(const Box&);

大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数,如下所示:


Box operator+(const Box&, const Box&);

如果是类的成员函数,那么就不需要两个形参了,另一个用this就可以

// 重载 + 运算符,用于把两个 Box 对象相加
      Box operator+(const Box& b)
      {
         Box box;
         box.length = this->length + b.length;
         box.breadth = this->breadth + b.breadth;
         box.height = this->height + b.height;
         return box;
      }
      
// Box1 调用 + 函数,所以重载operator+中的this就是box1
 Box3 = Box1 + Box2;


不是所有的运算符都可以重载

C++ 动态内存

了解动态内存在 C++ 中是如何工作的是成为一名合格的 C++ 程序员必不可少的。C++ 程序中的内存分为两个部分:

  • 栈:在函数内部声明的所有变量都将占用栈内存。
  • 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

new 和 delete 运算符

C++命名空间

定义命名空间

// 第一个命名空间
namespace first_space{
   void func(){
      cout << "Inside first_space" << endl;
   }
}

调用

 // 调用第一个命名空间中的函数
   first_space::func();

您可以使用 using namespace 指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。

using namespace std;

C++模板

函数模板


#include <iostream>
#include <string>
 
using namespace std;
 
template <typename T>
inline T const& Max (T const& a, T const& b) 
{ 
    return a < b ? b:a; 
} 
int main ()
{
 
    int i = 39;
    int j = 20;
    cout << "Max(i, j): " << Max(i, j) << endl; 
 
    double f1 = 13.5; 
    double f2 = 20.7; 
    cout << "Max(f1, f2): " << Max(f1, f2) << endl; 
 
    string s1 = "Hello"; 
    string s2 = "World"; 
    cout << "Max(s1, s2): " << Max(s1, s2) << endl; 
 
   return 0;
}

类模板

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
 
using namespace std;
 
template <class T>
class Stack { 
  private: 
    vector<T> elems;     // 元素 
 
  public: 
    void push(T const&);  // 入栈
    void pop();               // 出栈
    T top() const;            // 返回栈顶元素
    bool empty() const{       // 如果为空则返回真。
        return elems.empty(); 
    } 
}; 
 
template <class T>
void Stack<T>::push (T const& elem) 
{ 
    // 追加传入元素的副本
    elems.push_back(elem);    
} 
 
template <class T>
void Stack<T>::pop () 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::pop(): empty stack"); 
    }
    // 删除最后一个元素
    elems.pop_back();         
} 
 
template <class T>
T Stack<T>::top () const 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::top(): empty stack"); 
    }
    // 返回最后一个元素的副本 
    return elems.back();      
} 
 
int main() 
{ 
    try { 
        Stack<int>         intStack;  // int 类型的栈 
        Stack<string> stringStack;    // string 类型的栈 
 
        // 操作 int 类型的栈 
        intStack.push(7); 
        cout << intStack.top() <<endl; 
 
        // 操作 string 类型的栈 
        stringStack.push("hello"); 
        cout << stringStack.top() << std::endl; 
        stringStack.pop(); 
        stringStack.pop(); 
    } 
    catch (exception const& ex) { 
        cerr << "Exception: " << ex.what() <<endl; 
        return -1;
    } 
}

C++ Struct和类

C++ Struct和类

多态

允许将子类类型的指针赋值给父类类型的指针

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容

  • C++ 是 C 语言的超集,它是一种使用非常广泛的计算机编程语言。C++ 作为一种静态数据类型检查的、支持多范型的...
    神齐阅读 892评论 0 1
  • 重新系统学习下C++;但是还是少了好多知识点;socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme阅读 19,903评论 0 50
  • cpp技术知识点笔记: 1:list 和 vector的实现区别? list空间按需分配,是链表类型,内存不一定连...
    小熊之怒阅读 219评论 0 0
  • ^异或运算符,先转换为二进制,相同为0,不同为1 0^1得1 1^1得0 0^0得0 1^0得1 转换十进制,A*...
    你飞跃俊杰阅读 280评论 0 0
  • 几种语言的特性 汇编程序:将汇编语言源程序翻译成目标程序编译程序:将高级语言源程序翻译成目标程序解释程序:将高级语...
    囊萤映雪的萤阅读 2,893评论 1 5