C++的特性和基础语法【一】

C++和Java的共性与区别

阅读本文的读者中,大多都有一定的Java基础,所以本文会建立在你有一定Java基础的情况下来讲解。首先C++支持的基础数据类型,运算符,控制流语句,类和对象这些和java基本一致。但C++还具有如下特性:

  • 编程范式:Java是一种面向对象的编程语言,注意是只支持;而C++同时支持面向对象编程和面向过程编程,因为继承了C语言的特点。这意味着C++可以使用类和对象来组织代码,也可以使用函数和结构体等来实现面向过程编程。

  • 内存模型和内存管理:C++在内存模型上(类似jvm运行时数据区)和java有所不同,但也比较类似。在内存管理上,Java是通过Jvm自动管理的;而C++在有些场景需要手动管理内存,比如通过new和delete运算符来动态分配和释放内存。

  • 强大的指针(无所不在):C++提供了指针的概念,允许直接访问和操作内存地址。这使得C++在一些场景下更高效,但也需要谨慎使用,以避免指针错误和内存安全问题。

  • 多重继承:C++支持多重继承,这意味着一个类可以从多个基类派生。而Java只支持单一继承,一个类只能继承自一个父类。这里不分析谁更好,只是提出这种特性,后面的章节再来讨论。

  • 运算符重载:C++允许对运算符进行重载,从而可以自定义类对象之间的运算行为。这在某些情况下可以使代码更简洁和易读。

C++的数据类型

C++提供了基本的数据类型,intshortlongfloatdoublecharbool,这些和java是一样的。此外还提供了signed有符号整数和unsigned无符号整数。struct结构体,指针和引用。

局部变量也支持static和const

在Java中局部变量是不能使用static修饰的,而C++中的局部变量可以使用 static。当 static 修饰局部变量时,它仍然处于内存的全局区,这意味着函数执行完毕后也不会被销毁。这对于需要在多次函数调用之间共享数据的情况会有用。也就是说static修饰的变量,无论是全局变量还是局部变量都是在全局区。

cpp 复制代码
void func1() {
    static int count = 0;
    count++;
    cout << count << endl;
}

int main() {
    func1(); // 输出: 1
    func1(); // 输出: 2
    func1(); // 输出: 3

    return 0;
}

局部变量也能用const修饰,这意味着该变量在函数执行过程中是只读的,而无法被修改。这一点在很多实际业务场景中非常有用,后面的章节会再来解释这一点。

cpp 复制代码
void func2() {
    //不能再被修改
    const int value = 10;
}


void func3(const Student &stu) {
    //stu 引用变量只读,无法修改
}

signed和unsigned

cpp 复制代码
// signed修饰符 ,可以表示负数和正数
signed int a = -10; 

// unsigned修饰符 ,只能表示非负数
unsigned int b = 20;

此外,还有一种简化的方式表示无符号整数。uint8_t,uint16_t,uint32_t,uint64_t

struct结构体

C++中的结构体是继承自C语言的特性,用struct关键字表示。是一种复合数据类型,用于将不同类型的数据组合在一起。结构体可以包含多个成员变量,每个成员变量可以是不同的数据类型。但是C++中的结构体可以包含成员函数和访问修饰符,从而更接近于类的概念。

C语言中的结构体

cpp 复制代码
struct Person {  
std::string name;  
int age;  
};

C++中的结构体

cpp 复制代码
struct Person {
    std::string name;
    int age;

    //支持函数
    void display() {
        std::cout << name << std::endl;
        std::cout << age << std::endl;
    }
};
cpp 复制代码
int main() {
    Person p1; //创建结构体对象
    p1.name = "John";
    p1.age = 25;
    p1.display();
    return 0;
}

指针

C++中的指针是一种变量,它是指向某个变量的内存地址。通过指针,我们可以直接访问和操作内存中的数据。

指针的简单使用如下,这里不展开细讲,在后面的章节还会讲解,这里有个基础概念就行。

cpp 复制代码
int main() {
    int a =10;
    int *ptr; //声明一个指针
    ptr = &a; //取地址运算符(&)将变量的地址赋值给指针
    *ptr =20; //修改指向的内容

    return 0;
}

引用

在C++中,引用是一种别名,它指向了一个已经存在的变量或者对象,通过引用可以直接操作原始变量。

cpp 复制代码
int main() {
    int a = 10;
    int &ref = a; //声明引用ref,它是变量a的别名。

    return 0;
}

上面是引用的简单使用。引用必须在声明时进行初始化,并且一旦初始化后,它将一直引用同一个变量。 引用的好处很多,特别是作为函数参数和返回值的时候,这里不展开,后面的章节会解释。

引用与指针的区别

  • 引用与指针类似,但有一些重要区别。引用必须在声明时进行初始化,并且不能改变引用所指向的变量。
  • 引用不需要使用解引用操作符*来访问所引用的变量,而是直接使用引用变量名。

C++中的常量

c++中的常量的含义和java是一样的。在c++中提供了2种方式来定义常量。

使用 #define 定义符号常量

使用方式如下,定义了常量PI。

cpp 复制代码
#define PI 3.14159

#defineC语言中的预处理指令,C++ 继承了这个特性。使用 #define 定义常量时,编译器会直接将代码中出现的符号替换为对应的常量值,这会增加代码的可读性和可维护性。

使用const

cpp 复制代码
const float PI = 3.14;

const常量在使用上和安全上要比#define更好,建议优先使用const。

namespace命名空间

在C++和C语言中是支持面向过程编程的,也就是说我们可以在文件中直接声明全局的变量或者函数,注意,这一点和java不同,java所有变量和函数的定义都要在类中。这就导致了一个问题,可能出现命名冲突, C语言中通常使用不同的命名约定来避免命名冲突。而C++则引入了namespace命名空间来解决这个问题,而且它允许我们将相关的变量、函数等放在一个namespace中。

cpp 复制代码
namespace space1 {
    int sum = 10;
}

namespace space2 {
    int sum = 10;
}

int main() {
    // 访问命名空间中的变量
    std::cout << space1::sum << endl;
    std::cout << space2::sum << endl;

    return 0;
}

注意:访问命名空间中的成员是通过::作用域操作符来访问的。此外命名空间还可以定义函数,类对象等。

std是c++中的标准命名空间。c++标准库中的标识符都定义在这里,比如说常用的<iostream>,std::cout,vector等。在使用的文件当中加上using namespace std;即可使用。

C++内存分配的2种方式

在C++中,有多种方式来进行内存的分配和释放,其中包括 mallocfree 函数以及 newdelete 运算符。 mallocfree 是C语言中的函数,用于动态分配和释放内存。C++中继承了这一特性,使用 malloc 分配内存时,需要手动指定要分配的字节数,并返回一个指向分配内存的指针。使用 free 释放内存时,需要传入指向要释放的内存的指针。

cpp 复制代码
    //sizeof(int)是int 的大小,
    int *ptr = (int *) malloc(sizeof(int)); 
    free(ptr);

malloc/free是C语言就有的特性,c++继承了这一特性。但c++更推荐使用new运算符分配内存。malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会自动调用构造函数和析构函数进行初始化与清理。注意:对于数组的分配和释放,需要使用 new[]delete[] 运算符。

cpp 复制代码
    int* ptr = new int; // 使用new运算符分配内存
    delete ptr; // 使用delete运算符释放内存
    
    int* arr = new int[5]; // 使用new[]运算符分配数组内存
    delete[] arr; // 使用delete[]运算符释放数组内存

虽然 mallocfree 在C++中仍然可用,但为了更好地利用C++的面向对象的特性和资源管理机制,推荐使用 newdelete 运算符进行内存的分配和释放。

相关推荐
努力努力再努力wz4 分钟前
【c++进阶系列】:万字详解多态
java·linux·运维·开发语言·c++
NuyoahC1 小时前
笔试——Day46
c++·算法·笔试
啊吧怪不啊吧2 小时前
C++之list类的代码及其逻辑详解 (中)
开发语言·数据结构·c++·list
hai_qin2 小时前
三,设计模式-抽象工厂模式
c++·设计模式·抽象工厂模式
永不停转2 小时前
详谈 QLayout::SizeConstraint 和 QSizePolicy 对 QWidget 尺寸的影响
c++·qt
楼田莉子3 小时前
C++算法学习专题:滑动窗口
开发语言·数据结构·c++·学习·算法·leetcode
炸膛坦客3 小时前
C++ 学习与 CLion 使用:(四)常量和变量,包括字面常量和符号常量
开发语言·c++·学习
特立独行的猫a3 小时前
C/C++三方库移植到HarmonyOS平台详细教程(补充版so库和头文件形式)
c语言·c++·harmonyos·napi·三方库·aki
wangluoqi5 小时前
c++ 数据结构-并查集、ST表 小总结
数据结构·c++
时间之里13 小时前
c++:MFC中sqlite3的使用(附实际案例)
c++·mfc·sqlite3