c++初探

c语言分区栈Stack(大地址,由高向低使用)堆Heap(由低向高使用)全局or静态常量区文本and代码区(小地址)#include<stdlib.h>#include<stdio.h>int total = 0; //全局or静态常量区void hehe() { //函数,在stack中 static int he = 0; //全局or静态常量区,因为static只会创建一次 he++; total++;}int main(
摘要由CSDN通过智能技术生成

c语言分区

  1. 栈Stack(大地址,由高向低使用)
  2. 堆Heap(由低向高使用)
  3. 全局or静态常量区
  4. 文本and代码区(小地址)
#include<stdlib.h>
#include<stdio.h>

int total = 0;  //全局or静态常量区

void hehe() { //函数,在stack中
    static int he = 0; //全局or静态常量区,因为static只会创建一次
    he++;
    total++;
}

int main() {
    int k = 3;  //函数的内部变量,在stack中,但3在代码区
    char *str = "Hello, world!";  //  str函数中内部变量,在stack中,“hello world”在常量区
    int *p = (int *) malloc(sizeof(int));  // p在stack中,malloc动态分配的内存在堆中
    hehe();
    hehe();
    printf("%d%s%d", k, str, *p);
    free(p);
    return 0;  //stack中内存释放
}

类和对象

  • :类是一个模板,它描述一类对象的行为和状态。
  • 对象:对象是类的一个实例

c语言如何处理类和对象:

  • 没有“类”,只有“类型”

  • 没有“对象”,只有“变量”

  • 结构体变量+函数

    c语言采用结构体变量+函数的方式来实现类似功能,如下

    #include "stdio.h"
    
    struct Student{
        int id;
    };
    
    void printID(struct Student *in){
        printf("My id is %d.\n",in->id);
    }
    
    int main(){
        struct Student one;
        one.id=999;
        printID(&one);
        return 0;
    }
    

但我们发现,Student的属性和加在属性上的操作是割裂开的,我们可以使用函数指针类解决此问题

  • 函数指针
#include "stdio.h"

struct Student{
    int id;
    void (*printID)(struct Student *in);
};

void printID(struct Student *in){
    printf("My id is %d.\n",in->id);
}

int main(){
    struct Student one;
    one.id=999;
    one.printID=printID;
    one.printID(&one);
    return 0;
}

不一样的体验,用纯文本命令行写C++程序

  1. 打开vmware运行ubuntu
  2. 桌面右键打开终端
  3. 输入命令ls查看当前所在位置
  4. 输入命令cd 桌面进入桌面这个文件夹
  5. 输入命令touch test.cpp创建test.cpp文件
  6. 打开test.cpp文件,输入以下代码并保存在这里插入图片描述
  7. 输入命令g++ test.cpp编译test.cpp文件,我们发现桌面上产生了一个新的文件a.out,这就是编译产生的可执行文件,接下来我们运行之
  8. 输入命令./a.out运行,发现如下输出:在这里插入图片描述

c++的新特性

类(class)

之前说过了

bool类型和auto类型

bool,c语言中,真假用整形来代替,0 -->False && !0-->True && True--> && False-->0

c++中,可以true,false,也可以用0和1

auto,让编译器推断是什么类型,但必须在初始化时赋值,否则编译报错

cout,在打印浮点数是会省略后面的部分

引用

int a = 3;  //定义了变量a,并用3使其初始化,=不是运算符=含义是初始化
int b;  //定义了变量b,没有初始化
b = 3;  //把3赋值给b,=是运算符

int array[10]={1,2,3};  //定义了数组array,并用{1,2,3}使其初始化
array={1,2,3};  //错误
array[10]={1,2,3};  //错误
int *p; // *的含义是p是一个指针,不是取值运算符,p是指向int类型的指针
int a = 3;
p = &a;
*p = 6;  // *的是取值运算符
int b = 6;
int &r = b; // &的含义是r是一个引用类型,不是取地址运算符,r是int类型的引用,=表示用b来初始化r,让r成为b的引用,不是赋值,可以理解为给b起个外号,自此之后r就是b,b就是r
r = 123;
cout << r << endl;  // 123
cout << b << endl;  // 123

在C++中函数的参数传递:

  • 按值传递(pass by value)
  • 地址传递(pass by pointer)
  • 引用传递(pass by reference)

引用必须在定义时初始化,一旦创建就不可更换引用的对象

int b = 6;
int &r;  //error: 'r' declared as reference but not initialized
r = b;  //把b的值赋值给r,但此时r并没有任何的引用

关于赋值

int a, b, c;
(a = b = c = 3) = 666;
cout << a << endl;  //666
cout << b << endl;  //3
cout << c << endl;  //3

赋值之后返回的是左值的引用

初始化的新语法

int a{3};
int array[5]{1, 2, 3, 4, 5};

new和delete

int *p;
p = (int *) malloc(sizeof(int));
free(p);
p = new int;
delete p;
deleete[] p;  //复杂类型应该这样写
#include "iostream"
using namespace std;
class Student {
public:
    int sid;
};
int main() {
    Student one, two;
    one.sid = 1;
    two.sid = 2;
    cout << &one << endl;
    cout << &two << endl;
    one = two;
    two.sid = 999;
    cout << &one << endl;
    cout << &two << endl;
    return 0;
}
#include "iostream"
using namespace std;
class Student {
public:
    int sid;
};
int main() {
    Student *one = new Student();
    Student *two = new Student();
//    Student *one, *two;
//    one = new Student();
//    two = new Student();
    one->sid = 1;
    two->sid = 2;
    cout << &one << endl;  //0x63fde8
    cout << &two << endl;  //0x63fde0
    one = two; //内存泄漏
    two->sid = 999;
    cout << one << endl;  //0x1c1770
    cout << two << endl;  //0x1c1770
    return 0;
}

进一步理解Java的引用,相当于c++中的指针,java的引用和c++的引用是不一样的

class Student {
    public int sid;
}

public class test {
    public static void main(String args[]) {
        Student one = new Student();  //创建对象一定需要new
        Student two = new Student();  
        one.sid = 1;
        two.sid = 2;
        System.out.println("one: " + one);  //one: Student@7291c18f
        System.out.println("two: " + two);  //two: Student@34a245ab
        one = two;
        two.sid = 999;
        System.out.println("one: " + one);  //one: Student@34a245ab
        System.out.println("two: " + two);  //two: Student@34a245ab
    }
}

新的for循环

for-each不再赘述,可以使用auto,each是取出来的容器里的值,&each可以修改容器里本来的值

在这里插入图片描述
在这里插入图片描述

重载

C++ 允许在同一作用域中的某个函数运算符指定多个定义,分别称为函数重载运算符重载

在同一个作用域内,可以声明几个同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。不能仅通过返回类型的不同来重载函数。

我们可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

注:在一个函数声明中,const可以修饰形参表明他是一个输入参数,在函数内部不可以改变其值;

lambda

auto f = [](auto a, auto b) -> auto { return a + b; };
cout << f(3.1, 5) << endl; // 8.1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值