cpp学习记录03

结构体

定义:用户自定义符合数据类型,可以包含不同类型的不同成员。

//声明结构体
struct 结构体类型(自己起名)
{
    成员1类型 成员1名称;
    。。。
    成员N类型 成员N名称;

}

基本用法(类似class)

    struct  Student {
        string name;
        int age = 20; //设定默认值
        string gender;
    };

    //结构体的变量声明 可以在前面带上struct关键字(非必须 但推荐写)
    struct Student stu;

    //对结构体变量赋值
    stu = {"sj",11,"male"};
    //cout<< stu << endl;  结构体变量是一个整体的包装,无法直接cout输出
    cout << stu.name <<endl;

结构体数组

    
    struct  Student {
        string name;
        int age;
        string gender;
    };
    //方式1声明
    struct Student stu2[3];
    stu2[0] = {"kk",11,"male"};
    stu2[1] = {"dd",3,"female"};
    stu2[2] = {"ll",4,"male"};

    //方式2声明
    struct Student stu3[3] = {{"kk",11,"male"},{"dd",3,"female"},{"ll",4,"male"}};
    for(Student i:stu2) {
        cout << i.name << endl;
    }

结构体指针

    struct Student stu0 = {"cc",12,"male"};
    //创捷结构体指针,指向结构体对象的地址
    struct Student * p = &stu0;
    //通过结构体指针访问成员
    cout << p-> name <<endl;
//自己管理内存空间    
struct Student * p7 = new Student {"qq",39,"male"};
    delete p7;

结构体指针数组

    //方式1
    struct Student stu4[3] = {{"kk",11,"male"},{"dd",3,"female"},{"ll",4,"male"}};
    struct Student * p1 = stu4;
    cout << p1[0].name <<endl;
    //方式2 能自己管理内存
    struct Student * p9 = new Student[3]{{"kk",11,"male"},{"dd",3,"female"},{"ll",4,"male"}};
    cout << p9[0].name <<endl;
    delete[] p9;

函数

//语法
返回值类型 函数名称 (参数列表)
{
函数体
。。。
返回值
}

地址传递

void switch_num(int *a,int *b) {
    //直接对地址里的内容进行修改,能实现对外部变量进行操作
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(int argc, char *argv[]) {
    int *a = new int(10);
    int *b = new int(20);
    switch_num(a,b);
    cout << *a << endl;  //20
    cout << *b << endl;  //10
    delete a;
    delete b;
}

函数传入数组

由于数组对象本身只是第一个元素的地址,所以数组传参不区分值传递还是地址传递。本质都是传地址

void arr_test(int a[],int length)  //很难通过地址值知道数组长度,所以一般要求把数组长度
                                    //作为参数传入
{
   cout<<sizeof(a)<<endl;  //指针长度 8字节
   //说明传进来的就是指针
    for(int i=0 ; i<length ; i++) {
        cout<<*(a+i)<<endl;
        cout<<a[i]<<endl;
    }
}

int main(int argc, char *argv[]) {
   int arr[] = {1,2,3,4,5,6,7};
   cout<<sizeof(arr)<<endl;  //28 7*4字节
   arr_test(arr,sizeof(arr)/sizeof(arr[0]));  
}

排序练习

void sort(int arr[],int length) {
    for(int i=0;i<length;i++) {
        int temp;
        int min = arr[i];
        int min_index = i;
        for(int j=i;j<length;j++) {
            if(arr[j]<min) {
                min = arr[j];
                min_index = j;
            }
        }
        temp = arr[i];
        arr[i] = arr[min_index];
        arr[min_index] = temp;
    }
}
int main(int argc, char *argv[]) {
   int arr[] = {2,10,4,3,9,6,7};
    sort(arr,sizeof(arr)/sizeof(arr[0]));
    for(int i:arr) {
        cout<<i<<endl;
    }
}

引用

引用:是变量的一个别名,它是某个已存在变量的另一个名字

特点:1引用创建后不可更改(更改指向到其他内存区域)

2.因为不可更改,所以引用必须初始化

3.因必须初始化,所以引用不可为空(不可修改)

本质:是一个指针常量

    int a = 10;
    //数据类型& 引用名 = 被引用变量;
    int& b = a;     //自动转换为 int* const b = &a  指向地址不可改
    cout << "a=" << a <<endl; //10
    cout << "b=" << b <<endl; //10
    a = 20;
    cout << "a=" << a <<endl; //20
    cout << "b=" << b <<endl; //20
    b = 30;         //内部发现b是引用,自动转换为 *b = 30
    cout << "a=" << a <<endl; //30
    cout << "b=" << b <<endl; //30
    //相当于a和b完全等价了

引用传递

void switch_num(int &x,int &y)  //这里相当于执行了 int* const x=&a;
                                                //int* const y =&b;
{
 int temp = x;
    x = y;
    y = temp;
}
int main(int argc, char *argv[]) {
    int a = 10;
    int b = 20;
    switch_num(a,b);
    cout<<a<<endl;  //20
    cout<<b<<endl;  //10
    return 0;
}

常量引用

目的:防止误操作修改引用值

//误操作情况
void show(int& x) {
    x = 100;    //误操作
    cout<< x <<endl;
}
int main(int argc, char *argv[]) {
    int a = 10;
    show(a);
    cout<<a<<endl;  //导致变量a的值变为100
    return 0;
}
//用const修饰后
void show(const int& x) {
    x = 100;    //用const修饰后 编译阶段直接报错不通过防止犯错
    cout<< x <<endl;
}

返回指针的函数

语法

返回值类型 * 函数名(形参){
    函数体
    return 指针
}

实例

//错误写法
int * add(int a,int b) {
    int sum;
    sum = a + b;
    return &sum; //这是局部变量,在函数执行完毕后,变量会被销毁,所占内存空间将被释放
    //这就是C++的静态内存管理,如果要规避需要动态内存管理(new delete)
}
//正确写法
int * add1(int a,int b) {
    int *sum = new int;
    *sum = a + b;
    return sum;
}
int main() {
    int* c = add1(1,2);

    delete c;  //不删除的话会有提示
}

函数返回数组

其实和返回指针是一样的,因为返回数组本质上就是返回指针

函数重载

函数名可相同

需要满足的条件:同一个作用于下,名称相同,函数参数类型不同,或个数不同,或顺序不同

static

是一个关键字可以修饰 函数和变量

int * add(int a,int b) {
    static int sum = a + b;  //当用static修饰后,函数完成时不会被回收
    return &sum;
}

int main() {
    int *p = add(1,2);
    cout << *p << endl;
    return 0;
}

但无限制的使用static会浪费内存

内存分区模型

内存大方向分为4个区域

代码区:存放二进制代码,由操作系统进行管理的

全局区:存放全局变量和静态变量以及常量

栈区:由编译器自动分贝释放,存放函数的参数值,局部变量等

堆区:有程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值