侧边栏壁纸
博主头像
Into The Abyss 博主等级

My Life is a Death Race

  • 累计撰写 34 篇文章
  • 累计创建 7 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

c++_study_02

Administrator
2023-10-16 / 0 评论 / 0 点赞 / 170 阅读 / 0 字

结构体

自定义的数据类型,C++中定义结构体变量时,可以省略struct。

函数中调用结构体变量时,实参传递给形参时发生了内存拷贝,效率低

//形参用结构体变量
struct student{
    //成员变量
    char name[10];
    int number;
};

void func(student stu){
    strcpy(stu.name,"lisi");
    stu.number = 2;
}

int main(int argc, char const *argv[])
{
    student stu1; 
    stu1.number = 1;
    strcpy(stu1.name,"zhangsan");
    cout<<stu1.name<<" "<<stu1.number<<endl;
    func(stu1);
    cout<<stu1.name<<" "<<stu1.number<<endl;
    return 0;
}
//输出为:
//zhangsan 1
//zhangsan 1

可以使用引用&来进行传递,不会发生内存拷贝。

//形参用结构体引用
//修改func函数为func1
void func1(student &stu){
    strcpy(stu.name,"lisi");
    stu.number = 2;
}
//使用  func1(stu1); 调用

//输出为
//zhangsan 1
//lisi 2

也可以使用结构体指针进行传递

//形参用结构体指针
//修改func函数为func2
void func2(student *stu){
    strcpy(stu->name,"lisi");
    stu->number = 2;
}
//使用  func2(&stu1); 调用

//输出为
//zhangsan 1
//lisi 2

c++中的结构体具备了c语言中的结构体的全部功能,还增加了拓展功能

c++中的结构体不仅有成员变量,还可以定义成员函数

public和private成员修饰符

public:用该修饰符修饰结构体/类中的成员变量/成员函数,就可以被外界访问。

provate:用该修饰符修饰结构体/类中的成员变量/成员函数,只能被内部定义的成员函数使用。

c++中的结构体和类基本相同,结构体中不加成员修饰符默认为public,类中不加成员修饰符默认为private;结构体继承默认为public,类继承默认为private

类的组织

类的定义代码放在.h头文件中,头文件名与类名相同;

类的实现放在.cpp文件中,与类名相同,导入对应的头文件;

函数与后置返回类型

函数定义中,形参如果用不到的话,则可以不给形参变量名字,只给起类型,例如void func(int a, int){}

函数定义时,可以只有形参类型,没有形参名,例如void func(int, int);

函数返回指针问题

int *func(){
    int tmp = 9;
    return &tmp;  //不可以,tmp为临时变量,在执行完func函数后,tmp被系统回收,不能够再使用,可以将tmp设置为全局变量
}

int *p = func();

函数返回引用问题

int &func(){
    int tmp = 9;
    return tmp; 
}

int &p = func();
p = 10; // 不可以,原因与指针相同,tmp地址被回收,p与tmp地址相同。

int q = func();
q =10; //可以

把函数返回类型放在函数名之前,这种写法叫作前置返回类型;在c++11中引入后置返回类型,在函数声明和定义中,将返回类型写在参数列表之后

auto func(int a,int b) -> void; //函数声明
auto func(int a,int b) -> void{
    
} //函数定义

内联函数

函数定义之前加inline,这个普通函数就成了内联函数。

一般用在函数体很小,调用频繁的函数,循环,分支,递归尽量不要出现在inline函数中。

在编译阶段对inline函数进行处理,系统尝试将调用该函数的动作替换为函数本体,来提升性能。

inline只是开发者对编译器的一个建议,编译器可以尝试去做,也可以不去做,取决于编译器,程序员不能控制。

内联函数的定义要放在头文件中

可能会造成代码膨胀问题;各种编译器处理可能不相同

string

定义和初始化string

string s1; //默认初始化
string s2 = "hello"; //把hello拷贝到s2代表的内存中,不包括"\0"
string s3("hello"); //与s2相同,写法不同
string s4 = s2; //把s2的内容拷贝到s4中,s2与s4内存不同
string s5(6,'a'); //将s5初始化为aaaaaa

string对象上的操作

string s1;
//判断是否为空
s1.empty();
//返回字节/字符数量
s1.size();
s1.length();
//返回s1中的第n个字符
int n = 1;
s1[n];
// s1 + s2   将s1与s2连接
//string的赋值
string s2 = "abcd";
string s3 = "ef";
s3 = s2; // s3为abcd
//返回一个字符串中的内容指针,正规c字符串指针常量,以"\0"结尾
const char *p;
p = s1.c_str();

s1 = "abc" + "cde"; //不能这样加
s1 = "abc"+s2+"def"; //可以
//范围for的应用
for(auto c:s1){
    //不能改变s1中的值
}

for(auto &c:s1){
    c = toupper(c); //可以改变s1中的值,toupper()将小写变为大写,大写不变。
}

vector

集合或者动态数组,可以把若干对象放入其中,也被成为容器。初始化vector<数据类型> 名称

vector<int> a; //可以
vector<int *> b; //可以
vector<int &> c; //不可以,引用只是别名,指针不是对象

// 初始化
vector<int> a; //默认
vector<int> b(a); //元素拷贝初始化,或者vector<int> b = a;
vector<int> c = {1,2,3,4}; //列表初始化赋值
vector<int> d(15,0); //创建15个int类型,且值为0


a.push_back(1); //向vector末尾加入数据

a.empty();  //判断是否为空

a.size();  //返回元素个数

a.clear(); //移除所有元素,将容器清空

a[n]; //返回a中的第n个元素

//范围for,与string相同

迭代器

迭代器是一种遍历容器内元素的数据类型,有点像指针,可以理解为迭代器用来指向容器中的某个元素。

通过迭代器,我们就可以读容器中的元素值,读string中的每个字符,还可以修改某个迭代器所指向的元素值。

迭代器类型

vector<int> iv = {100,200,300};
//vector<int>::iterator iter;  // 定义迭代器
//iter = iv.begin(); // 如果容器内有元素,则begin返回的迭代器指向容器的第一个元素。
//iter = iv.end(); // end返回的迭代器指向的并不是末端元素,而是末端元素的后面,一个不存在的元素
//iter = iv.rbegin(); // 如果容器内有元素,则begin返回的迭代器指向容器的最后一个元素。
//iter = iv.rend(); // rend返回的迭代器指向的并不是第一个元素,而是第一个元素的前面,一个不存在的元素
//如果一个容器为空,那么begin和end返回地迭代器相同
// 迭代器的使用
for(vector<int>::iterator iter = iv.begin(); iter != iv.end();iter++){
    cout<<*iter<<endl;
}
// 反向迭代器的使用
for(vector<int>::reverse_iterator riter = iv.rbegin(); riter != iv.rend(); riter++){
    cout<<*riter<<endl;
}

迭代器运算符

*iter:返回迭代器iter所指向元素的引用,必须要保证这个迭代器指向的是有效的容器元素

++iter、iter++:让迭代器指向容器的下一个元素,已经指向end时不能在++

--iter、iter--:让迭代器指向容器的上一个元素,已经指向开头元素时不能在–

iter1 == iter2、iter1 != iter2:判断两个迭代器是否相等

(*iter).num、iter->num:应用结构中的成员

const_iterator迭代器

const_iterator迭代器表示值不能改变的迭代器,即指向的元素值不可变,而不是迭代器本身不能改变,只能从容器中读出元素,不能改变。

常量容器只能用const_iterator迭代器来进行遍历。

cbegin()cend()返回的都是const_iterator迭代器

迭代器失效

在范围for语句中或操作迭代器的过程中,不能改变容器的容量,不能增加或者删除容器中的元素,否则会使迭代器失效

while(iter != iv.end()){
    iter = iv.erase(iter);
} //迭代器回收

while(!iv.empty()){
    auto iter = iv.begin();
    iv.erase(iter);
}

iv.clear();
0
c++

评论区