Linux系统编程
c/c++编程
#include
#include
int main()
{
int pid;
pid = fork();
if (pid==-1)
{
printf("error\n");
}
if (pid == 0)
printf("child: my = %d, parent = %d\n", getpid(), getppid());
//getpid()获取当前进程pid,getppid()获取父进程pid
else
printf("parent: my = %d, child = %d\n", getpid(), pid);
return 0;
}/*父进程从fork返回处继续执行,在父进程中,fork返回子进程PID
子进程从fork返回处开始执行,在子进程中,fork返回0*/
#include
using namespace std;
class MyClass
{
//基类
};
class myclass :public MyClass {
//派生类
};
/*在使用try catch注意*/
//派生类需要放在最前面,避免穿透
//int main() {
//
// try
// {
// throw MyClass();
// }
//
// catch (myclass) {
//
// cout << "myclass派生类" << endl;
// }
// catch (MyClass)
// {
// cout << "Myclass基类" << endl;
// }
// return 0;
//}
int main() {
try
{
throw myclass();//抛出异常
}
//捕获异常
catch (MyClass)
{
cout << "Myclass基类" << endl;
}
catch (myclass) {
cout << "myclass派生类" << endl;
}
return 0;
}//异常穿透执行
/*
catch (MyClass)
{
cout << "Myclass基类" << endl;
}
*/
#include
#include
#include
struct dynamicArray
{
void** addr2;
//指向的是数组空间
void* addr1;
//指向的是一个空间
};
void test2() {
struct dynamicArray* addr = malloc(sizeof(struct dynamicArray));
addr->addr2 = malloc(sizeof(void*) * 5);
printf("\n2-----------------------%d\n", addr);
//可以对数组空间赋值
addr->addr2[3] = 1;
addr->addr2[4] = 2;
printf("%d\n", addr->addr2[3]);
printf("%d\n", addr->addr2[4]);
}
void test1() {
struct dynamicArray* addr = malloc(sizeof(struct dynamicArray));
addr->addr1 = malloc(sizeof(void*) * 5);
printf("1-----------------------%d\n", addr);
//仅仅对一个空间赋值
addr->addr1 = 1;
printf("%d\n", addr->addr1);
}
//回调
//底层
void back_func_test(void* back_func(void*,void*)) {
int* x;
int y = 10;
x = &y;
back_func(*x,*x+10);
}
//给用户留好了接口,就是用户如果想访问那个值,用户自己决定
//用户
void back1(void *data1,void *data2) {
//假如一个用户只想访问*x
printf("%d\n", data1);
//printf("%d\n", data2);
}
void back2(void* data1, void* data2) {
//假如用户想访问*x,*x+10
printf("%d\n", data1);
printf("%d\n", data2);
}
int main() {
/*test1();
test2();*/
printf("用户1\n");
back_func_test(back1);
printf("用户2\n");
back_func_test(back2);
return 0;
}
#include
#include
#include
#include
struct dynamicArray
{
void** addr;
//在堆区开辟数组
int capacity;
//数组容量
int Size;
//数组大小
};
//初始化数组
struct dynamicArray* initArray(int Capacity) {
if (Capacity <= 0) {
return;
}
struct dynamicArray* arr = malloc(sizeof(struct dynamicArray));
//申请结构体指针
if (arr)
{
//arr不为空
arr->capacity = Capacity;
arr->Size = 0;
arr->addr = malloc(sizeof(void*) * Capacity);
}
else
{
printf("fail\n");
return;
}
return arr;
}
//插入数据(data)向数组(arr)中的某一个位置(pos)
void insertArray(struct dynamicArray* arr, int pos, void* data) {
if (arr) {
if (pos<0 || pos>arr->Size)
{
//无效位置,强制尾插
pos = arr->Size;
}
}
if (data == NULL)
{
}
if (arr) {
if (arr->capacity == arr->Size)
{
//如果满空间,申请新空间
int newCapacity = arr->capacity * 2;
void** newSpace = malloc(sizeof(void*) * newCapacity);
//把原空间,拷贝新空间
if (newSpace)
{
memcpy(newSpace, arr->addr, sizeof(void*) * arr->capacity);
//释放原空间
free(arr->addr);
//指向新空间
arr->addr = newSpace;
arr->capacity = newCapacity;
//更新容量
}
}
//插入数据到指定位置
for (int i = arr->Size - 1; i >= pos; i--)
{
arr->addr[i + 1] = arr->addr[i];
}
arr->addr[pos] = data;
arr->Size++;//更新大小
}
}
//遍历数组
void foreachArray(struct dynamicArray* arr,void(*myprint)(void*)){
if (arr==NULL)
{
}
if (myprint==NULL)
{
}
for (int i = 0; i < arr->Size; i++)
{
myprint(arr->addr[i]);
}
}
//按照位置删除
void delArray(struct dynamicArray* arr,int pos) {
if (arr)
{
}
if (pos<0||pos>arr->Size-1)
{
return;
}
for (int i = pos; i < arr->Size-1; i++)
{
arr->addr[i] = arr->addr[i + 1];
}
arr->Size--;
}
//按照值删除
void delvalueArray(struct dynamicArray* arr, void* data,int(*myCompare(void*,void*))) {
if (arr==NULL)
{
}
if (data==NULL)
{
}
for (int i = 0; i < arr->Size-1; i++)
{
if (myCompare(arr->addr[i],data))
{
delArray(arr, i);
break;
}
}
}
struct Person
{
char name[32];
int age;
};
//回调函数
void myprint(void* data) {
struct Person* p = data;
printf("%s %d\n", p->name, p->age);
}
int myCompare(void* data1, void* data2) {
struct Person *p1 = data1;
struct Person *p2 = data2;//强转
return strcmp(p1->name,p2->name)==0 && (p1->age == p2->age);
}
//销毁数组
void desArray(struct dynamicArray* arr) {
if (arr==NULL)
{
}
//先释放堆区的数组,再释放结构体
if (arr->addr!=NULL)
{
free(arr->addr);
arr->addr = NULL;
}
free(arr);
arr = NULL;
printf("end\n");
}
void test01() {
struct dynamicArray* ARR=initArray(5);
//初始化数组
struct Person p1 = {
"yi",20 };
struct Person p2 = {
"er",20 };
struct Person p3 = {
"san",20 };
struct Person p4 = {
"si",20 };
struct Person p5 = {
"wu",20 };
struct Person p6 = {
"liu",20 };
//插入数据前容量 大小
printf("\n----%d %d\n", ARR->capacity, ARR->Size);
insertArray(ARR, 0, &p1);
insertArray(ARR, 1, &p2);
insertArray(ARR, 2, &p3);
insertArray(ARR, -1, &p4);
insertArray(ARR, 3, &p5);
insertArray(ARR, 4, &p6);
//插入数据后容量 大小
printf("\n----%d %d\n", ARR->capacity, ARR->Size);
foreachArray(ARR, myprint);
delArray(ARR, 1);//删除“1”位置
printf("--------------------\n");
foreachArray(ARR, myprint);
printf("--------------------\n");
struct Person p = {
"san",20 };
delvalueArray(ARR,&p,myCompare);
foreachArray(ARR, myprint);
desArray(ARR);
}
int main() {
int a[32] = {
0 };
test01();
}
#include
using namespace std;
//函数模板一般格式
/*
template <类型形式参数表> 返回值 函数名(形式参数,...){
//函数体
}
*/
// template 关键字
// <> 表示模板参数(两种)
// 1.类型参数(class / typedef)
// 2.非类型参数(一般为常数)
// Type 可为int double
template
Type max_us(Type x, Type y) {
return x > y ? x : y;
}
//数组模板
template
Type max_arr(Type arr[len]) {
Type ret = arr[0];
for (int i = 1; i < len; i++)
{
ret = (arr[i] > ret ? arr[i] : ret);
}
return ret;
}
//重载函数模板,实现字符、字符串比较
char* max_us(char* a, char* b) {
if (strcmp(a,b))
{
return a;
}
else
{
return b;
}
}
//类模板
int main() {
int i = max_us(8, 9);
double j = max_us(9.1, 10.9);
//歧义
//显示标识模板
float k = max_us(8.1f, 3);
cout << i << endl;
cout << j << endl;
cout << k << endl;
int a[5] = { 1,4,2,9,6 };
//数组模板使用
int max_a = max_arr(a);
cout << max_a << endl;
cout << "重载模板" << endl;
cout << max_us('a', 'n') << endl;
cout << max_us(9, 10) << endl;
cout << "end" << endl;
return 0;
}
#include
using namespace std;
/*
类模板一般定义形式
template <类型形式参数表> class 类模板名
{
//函数体
}
类模板成员函数定义形式
template <类型形式参数表>
返回类型 类模板名 <类型名表>::成员函数名(形式参数列表)
{
//函数体
}
类模板的成员函数定义时的类模板名与类模板定义时要一致,
类模板不是一个真实的类,需要重新生成类,生成类的形式
类模板名 <类型实在参数表>
新生成的类定义对象的形式
类模板名 <类型实在参数表> 对象名
*/
template
class Container
{
Type u;
public:
void begin2(const Type& itnew);//声明函数
};
template void Container::begin2(const Type& p) {
//函数实现
u = p;
cout << u << endl;
}
int main() {
Container myContainer;//定义对象
int i = 100;
myContainer.begin2(i);
}
#include
#include
#include
#include
using namespace std;
//vector 容器(存放自定义数据)
class person {
public:
person(string name, int age) {
this->name = name;
this->age = age;
}
string name;
int age;
};
void test02() {
vector vp;
person p1("a", 10);
person p2("b", 20);
person p3("c", 30);
//向容器添加数据
vp.push_back(p1);
vp.push_back(p2);
vp.push_back(p3);
//遍历数据
for (vector::iterator it = vp.begin(); it!= vp.end(); it++) {
cout << (*it).name << endl;
cout << (*it).age << endl;
//cout << it->name << endl;
}
}
void test03() {
vector vp;
person p1("a", 10);
person p2("b", 20);
person p3("c", 30);
//向容器添加数据
vp.push_back(&p1);
vp.push_back(&p2);
vp.push_back(&p3);
//遍历数据
for (vector::iterator it = vp.begin(); it != vp.end(); it++) {
cout << (*it)->name << endl;
cout << (*it)->age << endl;
}
}
//vector 容器(数组)
void myprint(int val)
{
cout << val << endl;
}
void test01() {
//存放整型数据的容器 varray
vector varray;
varray.push_back(10);//向容器中添加数据
varray.push_back(90);
varray.push_back(19);
//通过迭代器访问容器中数据
vector::iterator itbegin = varray.begin();
//指向容器第一个数据
vector::iterator itend = varray.end();
//指向容器最后一个数据的下一个数据
while (itbegin!=itend)
{
cout << *itbegin << endl;
itbegin++;
}
//遍历2
for (vector::iterator it = varray.begin(); it != varray.end(); it++) {
cout << *it << endl;
}
//遍历3
for_each (varray.begin(), varray.end(), myprint);
}
int main() {
//test01();
/*test02();*/
test03();
cout << "----------------" << endl;
}
#include
#include
#include
#include
using namespace std;
void test01() {
//嵌套容器
vector> vv;
vector v1;
vector v2;
vector v3;
for (int i = 0; i < 3; i++)
{
v1.push_back(i + 2);
v2.push_back(i + 3);
v3.push_back(i + 4);
//向三个小容器添加数据
}
vv.push_back(v1);
vv.push_back(v2);
vv.push_back(v3);
//向大容器添加数据
for (vector> ::iterator it=vv.begin();it!=vv.end(); it++){
//遍历大容器
for (vector::iterator vit = (*it).begin();vit!=(*it).end(); vit++)
{
//遍历小容器
cout << " "<<*vit ;
}
cout << endl;
}
}
int main() {
test01();
return 0;
}
#include
using namespace std;
void fun() {
int* p = new int(10);
//p指向堆区变量,初始为10
cout << *p << endl;
delete p;
p = NULL;
}
void funarr() {
int* p1 = new int[10];
//p指向堆区数组,大小为10
for (int i = 0; i < 10; i++)
{
p1[i] = i + 100;
}
for (int i = 0; i < 10; i++)
{
cout << p1[i] << endl;
}
//释放数据(如果是数组加上[])
delete[]p1;
p1 = NULL;
}
int main() {
fun();
cout << "-------------" << endl;
funarr();
return 0;
}
引用本质是指针常量。
#include
using namespace std;
/*
数据类型 &别名=原名
*/
//函数中引用传参
void swap(int &a,int &b) {
int temp;
temp = a;
a = b;
b = temp;
cout << "A=" << a << " B=" << b << endl;
}
//引用做函数返回值
int& test01() {
int a = 10;
return a;
}
int& test02() {
static int a = 16;//存在全局区
return a;
}
int global = 190;//
int& test03() {
return global;
}
int main() {
int a=1;
int b = 9;
//创建引用
int& A = a;//引用必须初始化
//int& A = b;//初始化后不可更改指向(只能为a的别名)
cout << A << endl;
int a1 = 10;
int b1 = 18;
swap(a1, b1);//此时函数中的引用形参为形参的别名
cout << "-----------------" << endl;
int& ref = test01();
cout << ref << endl;
cout << ref << endl;
//返回局部变量,非法操作,局部变量存在栈区,执行完成后被系统释放
cout << "-----------------" << endl;
int gl = test03();
cout << gl << endl;
cout << gl << endl;//全局变量
cout << "-----------------" << endl;
int& ref02 = test02();
cout << ref02 << endl;
cout << ref02 << endl;
test02() = 1000;//如果函数返回值为引用,函数可以作为[左值]
cout << ref02 << endl;
cout << ref02 << endl;
cout << "-----------------" << endl;
int e = 10;
int e2 = 1;
int* const f = &e;//指针常量,指针是常量,不能更改指向
cout << *f << endl;
cout << "-----------------" << endl;
const int* f2 = &e;//常量指针,常量的指针,值不能更改
cout << *f2 << endl;
f2 = &e2;
cout << *f2 << endl;
return 0;
}
#include
using namespace std;
void test01(const int& a) {
//常量引用,修饰形参,防止误操作
//a = 100;//错误,修改了值
cout << a << endl;
}
int main() {
int a = 11;
//int& b = 10;//错误
const int& b = 10;
test01(a);
return 0;
}
#include
using namespace std;
void test01(int a, int b, int c = 10);
//声明中有默认参数,实现就不能有默认参数
void test01(int a,int b,int c) {
int sum;
sum = a + b + c;
cout << sum << endl;
}
//函数占位参数
//也可以有默认值
void test02(int a,int =10) {
cout <<"占位测试 "<< a << endl;
}
int main() {
test01(10, 10);
test01(10, 10,80);//函数中如果设置默认参数可以少传
test02(1,0);
return 0;
}
#include
using namespace std;
void func(int& a) {
cout << "int& a" << endl;
}
void func(const int& a) {
cout << "const int& a" << endl;
}
int main() {
int a = 10;
func(a);
func(1);
return 0;
}
#include
using namespace std;
//拷贝构造函数
class Person {
public:
Person(int age) {
this->cage = age;
cout << this->cage << endl;
}
Person(const Person& p) {
//拷贝构造函数
this->cage = p.cage;
cout << this->cage << endl;
cout << "拷贝构造函数" << endl;
}
~Person() {
//析构函数
cout << "析构函数" << endl;
}
private:
int cage;
};
void test01() {
//使用一个初始化的对象初始另一个对象
Person p1(20);
Person p2(p1);
}
void test02(Person p) {
}
int main() {
test01();
return 0;
}
#include
using namespace std;
class MyClass
{
public:
int cage;
int *cheight;
//有参构造函数
MyClass(int age,int height) {
this->cheight = new int(height);
//堆区申请空间
this->cage = age;
}
MyClass(const MyClass& p) {
//自写拷贝函数
cage = p.cage;
//cheight=p.cheight;//编译器默认实现
cheight = new int(*p.cheight);
}
/*如果注释掉自写拷贝函数会出错。
* 出错原因:堆区重复释放,浅拷贝执行过程。
* 堆区释放过程,先释放p1此时p1的*cheight指向堆区释放,
* 接着执行p,因为p的*cheight指向堆区已经释放,所以出错
* p p1
* 【cage】 【cage】栈
* 【*cheight】\ /【*cheight】区
* 【申请的堆区】
*/
/*深拷贝
* p p1
* 【cage】 【cage】
* 【*cheight】\ 【*cheight】\
* 【申请的堆区】 【申请的堆区】
*/
~MyClass();
};
MyClass::~MyClass()
{
if (cheight!=NULL)
{
delete cheight;
cheight = NULL;
}
cout << "执行析构" << endl;
cout << cheight << endl;
}
void test01() {
MyClass p(10,99);
MyClass p1(p);//系统默认提供拷贝函数
std::cout << p.cage << " "<<*p.cheight<
对已有的运算符进行定义,赋于新功能,适应新类型。
#include
using namespace std;
class Person {
public:
//成员函数重载+号
Person operator+(Person& p) {
Person temp;
temp.age = this->age + p.age;
temp.height = this->height + p.height;
return temp;
}
int age;
int height;
};
//全局函数重载+号
//Person operator+ (Person& p1,Person& p2) {
// Person temp;
// temp.age = p1.age + p2.age;
// temp.height = p1.height + p2.height;
//
// return temp;
//}
void test01() {
Person test;
Person p1;
p1.age = 10;
p1.height = 99;
Person p2;
p2.age = 11;
p2.height = 100;
test = p1 + p2;
cout << test.age << " " << test.height << endl;
}
int main() {
test01();//两种重载方式不能一起使用。
/*
成员函数重载本质
Person p3=p1.operator+(p2);
全局函数重载本质
Person p3=operator+(p1,p2);
*/
return 0;
}
#include
using namespace std;
class Person {
public:
int operator()(int a, int b){
return a + b;
}
};
void test01() {
int a = 9;
int b = 10;
int temp;
Person p;
temp=p(a, b);//重载(),仿函数
cout<
静态(函数重载、运算符重载)、动态(派生类、虚函数)。
#include
using namespace std;
class Animal {
public:
/*void speak1() {
cout << "动物speak" << endl;
}*/
//虚函数
virtual void speak1() {
cout << "动物speak" << endl;
}
};//父类
//子类继承父类
class cat :public Animal {
public:
void speak1() {
cout << "猫speak" << endl;
}
};
class dog :public Animal {
public://子类重写了父类函数
//重写:返回值、函数名、参数类型相同
void speak1() {
cout << "狗speak" << endl;
}
};
void dospeak(Animal& animal) {
animal.speak1();
}
int main() {
//实现:想让各种类小动物说话
cat c1;
dospeak(c1);//我想猫说话,可是实现动物说话
//如果想实现想让各种类小动物说话,需要虚函数关键字
/*
* 动态条件:
* 有继承关系
* 子类重写父类虚函数
* 动态使用:
* 父类指针或引用,执行类对象
*/
dog d1;
dospeak(d1);//父类指针或引用,执行类对象
return 0;
}
在父类的虚函数中,虚函数类似指针,会指向一个虚函数表。子类继承父类会把虚函数表重新拷贝一份,所以要在子类中重写虚函数,更改指向。
#include
using namespace std;
class Person {
public:
virtual void func()=0;
//纯虚函数
//只要有一个纯虚函数就是抽象类
//抽象类不能实例化
//抽象类的子类必须重写抽象类(父类)的纯虚函数
};
class Son :public Person{
virtual void func() {
cout << "Son 类" << endl;
//抽象类的子类必须重写抽象类(父类)的纯虚函数,否则还是抽象类
}
};
int main() {
//Person p;
//new Person;//抽象类不能实例化
Person* p = new Son;
/*
* 纯虚函数更多提供一个接口,new 不同之类对象,父类指针访问
*/
p->func();
return 0;
}
#include
#include
using namespace std;
//虚析构解决父类指针释放子类对象时不完全
class Person {
public:
Person() {
cout<<"Person构造函数"<speak1();
//父类指针在析构时候,不会调用子类析构函数,会导致子类堆区内存泄露
//即:son 堆区不能释放(~son6()未执行)
//解决:父类析构改成虚析构
delete p;
//释放
}
int main() {
test01();//多态
return 0;
}
纯虚析构需要实现
.hpp .cpp
#pragma once
#include
#include
//类与实现写在一起
using namespace std;
//类模板
template
class Person {
public:
Person(T1 name, T2 age);
void showPerson();//类外实现成员函数
T1 mname;
T2 mage;
};
/*----------------------------------------*/
template
Person::Person(T1 name, T2 age) {
this->mname = name;
this->mage = age;//类外实现构造
}
/*----------------------------------------*/
template
void Person::showPerson() {
//类外实现成员函数
cout << "输出:" << this->mname << " " << this->mage << endl;
}
/*-------------------------------------
#include"practice.hpp"
int main() {
Person obj("Tom", 10);
obj.showPerson();
return 0;
}