【C/C++】学习笔记

基本数据类型

1字节(B) = 8位(bit)

TypeC/C++Java
int4字节4字节
short2字节2字节
long4字节8字节
char1字节1字节
double8字节8字节
long double10字节10字节

函数&函数指针

#include <iostream>

void (*funcp)(int* a, int* b);
void point_func(int* a,int* b)
{
	*a = 200;
	printf("函数指针\n");
}
int main()
{
	int a = 10;
	int b = 20;
	// funcp是一个函数指针,将函数point_func()的地址赋给它
	funcp = point_func;
	funcp(&a, &b);
	printf("a值 %d",a);
}
int *p[3];//指针数组,每个元素都是一个指针
int a[3][4];
int (*p)[4];//数组指针
p=a;//此时p指向a[0][]
p++;//此时p指向a[1][]

结构体、共用体

struct Student{
    char a;// 1字节
    int b;// 4字节
    char c;// 1字节
}s1,s2;// 设在32位系统中,内存对齐后,整个结构体大小为12字节
typedef struct{
	int i;
}Students;

共用体:是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。目的:节约内存

union Student{
	int i;
	int j;
	float k;
};

库文件编译

gcc test.c -fPIC -shared/static -o test.so

动态库与静态库区别

静态库文件比较大动态库比较小
静态库需要在编译时被链接在目标代码中,动态库在运行时才会被加载到目标代码
静态库类似于Android中的Module,一旦打包APK需要重新进行编译。
动态库类似于jar包打包是不需要重新进行编译

类的构造和析构、友元函数

C++的Student.h头文件的写法

#pragma once
#ifndef Student_H
#define Student_H
class Student{
    int i;//默认私有成员
    friend void test();//友元函数
    friend class Teacher;//友元类
public:
    Student(int i);//构造函数
     ~Student();//析构函数
private:
    int j;//私有成员
protected:
    int k;//保护成员
public:
    int l;//公有成员
};
#endif // !Student_H

Students.cpp

#include "Student.h"
#include <iostream>
using namespace std;
Student::Student(int i):i(i){ //默认赋值 this->i = i
    cout << "构造方法" << endl;
}
Student::~Student(){
    cout << "析构方法" << endl;
}

单例对象

// Student.h
class Student{
private:
    static Student* instance;
    Student();
public:
    static Student* getInstance();
};
// Student.cpp
#include "Student.h"
Student* Student::instance = 0;
Student* Student::getInstance(){
    if(!instance){
        instance = new Student();
    }
    return instance;
}
// 使用
Student* stu = Student::getInstance();

继承

#include<iostream>
using namespace std;
class Parent{
public:
    void method(){
        cout<< "parent" << endl;
    }
};
class Child1 : Parent{
public:
    void method(){
        cout<< "child" << endl;
    }
};
class Child2 : private Parent{
    // 默认继承私有的
};
class Child3 : Child1, Child2{
    
};

多态

静态多态
Parent* child = new Child();
child->method();// 这里调用的是父类的方法
动态多态
// 虚函数
class Parent{
public:
    virtual void method(){
        // 子类实例化时会检查父类的方法,从而调用父类的函数
        /* 所以构造方法永远不要设为虚函数,析构方法要设为虚函数 */
    }
}
// 此外,纯虚函数要在子类中实现

类模板、函数模板

#include<iostream>
// 函数模板
template <typename T>
T methodname(T i, T j){
    return i>j?i:j;
}
// 类模板
template <class A, class B>
class C{
public:
    A test(A a, B b){
        return a + b;
    }
}

类型转换

强转类型解释
const_cast字面上理解就是去 const 属性
static_cast命名上理解是静态类型转换。如 int 转换成 char
dynamic_cast命名上理解是动态类型转换。如子类和父类之间的多态类型转换。
reinterpret_cast仅仅重新解释类型,但没有进行二进制的转换

4种类型转换的格式,如:TYPE B = static_cast(TYPE)(a)

const_cast

修改类型的const或volatile属性

const char *a;
char *b = const_cast<char*>(a);
	
char *a;
const char *b = const_cast<const char*>(a);

static_cast

  1. 基础类型之间互转。如:float转成int、int转成unsigned int等
  2. 指针与void之间互转。如:float*转成void*、Bean*转成void*、函数指针转成void*等
  3. 子类指针/引用与 父类指针/引用 转换。
class Parent {
public:
	void test() {
		cout << "p" << endl;
	}
};
class Child :public Parent{
public:
	 void test() {
		cout << "c" << endl;
	}
};
Parent  *p = new Parent;
Child  *c = static_cast<Child*>(p);
//输出c
c->test();
//Parent test加上 virtual 输出 p

dynamic_cast

主要 将基类指针、引用 安全地转为派生类.

在运行期对可疑的转型操作进行安全检查,仅对多态有效

//基类至少有一个虚函数
//对指针转换失败的得到NULL,对引用失败  抛出bad_cast异常 
Parent  *p = new Parent;
Child  *c = dynamic_cast<Child*>(p);
if (!c) {
	cout << "转换失败" << endl;
}


Parent  *p = new Child;
Child  *c = dynamic_cast<Child*>(p);
if (c) {
	cout << "转换成功" << endl;
}

reinterpret_cast

对指针、引用进行原始转换

float i = 10;

//&i float指针,指向一个地址,转换为int类型,j就是这个地址
int j = reinterpret_cast<int>(&i);
cout  << hex << &i << endl;
cout  << hex  << j << endl;

cout<<hex<<i<<endl; //输出十六进制数
cout<<oct<<i<<endl; //输出八进制数
cout<<dec<<i<<endl; //输出十进制数

char*与int转换

//char* 转int float
int i = atoi("1");
float f = atof("1.1f");
cout << i << endl;
cout << f << endl;
	
//int 转 char*
char c[10];
//10进制
itoa(100, c,10);
cout << c << endl;

//int 转 char*
char c1[10];
sprintf(c1, "%d", 100);
cout << c1 << endl;

异常

void test1()
{
	throw "测试!";
}

void test2()
{
	throw exception("测试");
}

try {
	test1();
}
catch (const char *m) {
	cout << m << endl;
}
try {
	test2();
}
catch (exception  &e) {
	cout << e.what() << endl;
}

//自定义
class MyException : public exception
{
public:
   virtual char const* what() const
    {
        return "myexception";
    }
};

//随便抛出一个对象都可以

文件与流操作

C 语言的文件读写操作

头文件:stdio.h

函数原型:FILE * fopen(const char * path, const char * mode);

path: 操作的文件路径

mode:模式

模式描述
r打开一个已有的文本文件,允许读取文件。
w打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。
a打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,程序会在已有的文件内容中追加内容。
r+打开一个文本文件,允许读写文件。
w+打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。
a+打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。
//========================================================================
FILE *f = fopen("xxxx\\t.txt","w");
//写入单个字符
fputc('a', f);
fclose(f);


FILE *f = fopen("xxxx\\t.txt","w");
char *txt = "123456";
//写入以 null 结尾的字符数组
fputs(txt, f);
//格式化并输出
fprintf(f,"%s",txt);
fclose(f);

//========================================================================
fgetc(f); //读取一个字符

char buff[255];
FILE *f = fopen("xxxx\\t.txt", "r");
//读取 遇到第一个空格字符停止
fscanf(f, "%s", buff);
printf("1: %s\n", buff);

//最大读取 255-1 个字符
fgets(buff, 255, f);
printf("2: %s\n", buff);
fclose(f);

//二进制 I/O 函数
size_t fread(void *ptr, size_t size_of_elements, 
             size_t number_of_elements, FILE *a_file);       
size_t fwrite(const void *ptr, size_t size_of_elements, 
             size_t number_of_elements, FILE *a_file);
//1、写入/读取数据缓存区
//2、每个数据项的大小
//3、多少个数据项
//4、流
//如:图片、视频等以二进制操作:
//写入buffer 有 1024个字节
fwrite(buffer,1024,1,f);

C++ 文件读写操作

<iostream> 和 <fstream>

数据类型描述
ofstream输出文件流,创建文件并向文件写入信息。
ifstream输入文件流,从文件读取信息。
fstream文件流,且同时具有 ofstream 和 ifstream 两种功能。
char data[100];
// 以写模式打开文件
ofstream outfile;
outfile.open("XXX\\f.txt");
cout << "输入你的名字: ";
//cin 接收终端的输入
cin >> data;
// 向文件写入用户输入的数据
outfile << data << endl;
// 关闭打开的文件
outfile.close();

// 以读模式打开文件
ifstream infile;
infile.open("XXX\\f.txt");

cout << "读取文件" << endl;
infile >> data;
cout << data << endl;

// 关闭
infile.close();

容器

#include<iostream>
#include<vector>
#include<set>
using namespace std;
int main(){
    // 序列式与关联式
    // 序列式容器:元素排列顺序与元素本身无关,由添加顺序决定的stack
    // vector、list、dequeue、queue、stack、priority、ueue
    vector<int> vec_1;
    // 声明有一个元素空间vector<int> vec_2(1);/1/6个元素值都是1
    vector<int> vec_3(6, 1);
    vector<int> vec_4(vec_3);
    // 增加元素
    vec_1.push_back(10);
    // 通过下标来获得元素
    cout << "通过下标来获得元素:" << vec_1[0] << endl;
    // 直接获得队首与队尾的元素
    vec_1.front();
    vec_1.back();
    // 清空
    vec_1.clear();
    vec_1.erase(vec_1.begin(), vec_1.end());
    cout << "获得vec的容量大小:" << vec_1.capacity() << endl;

    // 关联式 set、map、hashmap
    // set 集合,元素不可重复
    set<int> set1 = {1, 2, 3, 4};
    // insert()插入元素,返回值是一键值对pair
    pair<set<int>::iterator, bool> _pair = set1.insert(1);
    set<int>::iterator i_b = set1.begin();
    set1.end();// 指向最后一个元素的下一个元素NULL
    for(; itt != set1.end(); itt++){
        cout << *itt << endl;
    }
    // map 
    map<int, string> map1;
    map<int, string> map2 = {{1, "a"}, {2, "b"}};
    return 0;
}

命名空间

//第一个命名空间
namespace spacename1{
    void func(){
        cout << "Inside"<< endl;
    }
}
//第二个命名空间
namespace spacename2{
    void func(){
        cout << "outsite" << endl;
    }
}
// 使同名函数调用不冲突
// using namespace spacename1;
spacename1::func();
spacename2::func();

C++引用

引用指针
不存在空引用,引用必须连接到一块合法的内存有空指针
一旦引用被初始化为一个对象,就不能被指向到另一个对象指针可以在任何时候指向到另一个对象
引用必须在创建时被初始化指针可以在任何时间被初始化
int i = 17;
int* p = &i;
int& r = i;
cout << "Value of i reference:" << r << endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值