本文梳理 Java 转 C++ 开发的核心差异与学习要点,内容以代码示例为主,Java 基础语法部分可参考:JavaSE基础语法



一、宏定义、常量、sizeof关键字

#include<iostream>
#include<string>
#define day 7
using namespace std;

int main() {
	system("chcp 65001> nul"); // 解决 Visual Studio 中文乱码问题

	// 1、宏定义
	cout << "一周里总共有 " << day << " 天" << endl;

	// 2、const修饰变量
	const int month = 12;
	// month--; 会报错

	// 3、sizeof关键字
	cout << "short 类型所占内存空间为: " << sizeof(short) << endl; // 2
	cout << "int 类型所占内存空间为: " << sizeof(int) << endl; // 4
	cout << "long 类型所占内存空间为: " << sizeof(long) << endl; // 4
	cout << "long long 类型所占内存空间为: " << sizeof(long long) << endl; // 8
	
	system("pause"); // 防止窗口闪退
	return 0;
}
数据类型 占用空间 取值范围
short(短整型) 2字节 − 2 15 ∼ 2 15 − 1 -2^{15} \sim 2^{15}-1 2152151
int(整型) 4字节 − 2 31 ∼ 2 31 − 1 -2^{31} \sim 2^{31}-1 2312311
long(长整形) Windows为4字节,Linux为4字节(32位),8字节(64位) − 2 31 ∼ 2 31 − 1 -2^{31} \sim 2^{31}-1 2312311
long long(长长整形) 8字节 − 2 63 ∼ 2 63 − 1 -2^{63} \sim 2^{63}-1 2632631

二、浮点型、字符型、字符串型、布尔类型、空类型

#include<iostream>
#include<string>
using namespace std;

int main() {
	system("chcp 65001> nul");

	// 4、浮点型
	float f = 3.14f;
	double d = 3.14;
	// float f2 = 3e2; // 科学计数法 3 * 10 ^ 2 
	cout << f << endl; 
	cout << d << endl;
	cout << "float  sizeof = " << sizeof(f) << endl; // 4
	cout << "double sizeof = " << sizeof(d) << endl; // 8
	
	// 5、字符型
	char ch = 'a'; // 字符型变量是把对应ASCII码值存储在内存中
	cout << "char sizeof = " << sizeof(ch) << endl; // 1
	cout << "ch = " << (int)ch << endl; // 97
	char ch2 = 65;
	cout << "ch2 = " << ch2 << endl; // A
	
	// 6、字符串型
	char str[] = "Hello World!"; // 字符串常量 "Hello World!" 存储在内存中,str是一个指向字符串首字符的指针
	string str2 = "Hello C++!"; // string是C++标准库中的字符串类,str2是一个string对象,存储了字符串 "Hello C++!" 的内容
	
	// 需添加头文件 #include <string>
	cout << "str = " << str << endl;
	cout << "str2 = " << str2 << endl;
	cout << str[0] << endl;
	cout << str2[0] << endl;

	// 7、布尔类型
	bool flag = true;
	
	// 8、空类型:nullptr是C++11引入的空指针常量,表示指针不指向任何对象
	system("pause");
	return 0;
}

注:C和C++中字符型变量只占用1个字节

数据类型 占用空间 有效数字范围
float 4字节 7位有效数字
double 8字节 15-16位有效数字

三、算数运算、关系运算、三目运算、switch语句、goto语句

#include<iostream>
#include<string>
using namespace std;

int main() {
	system("chcp 65001> nul");

	// 1、算数运算
	// cout << a3 % b3 << endl; 取模运算,b3除数也不能为0
	// cout << a3 / b3 << endl; 除法运算,b3除数不可以为0

	// 2、关系运算
	int a = 0;
	int b = 1;
	cout << (a && b++) << endl;
	cout << "b = " << b << endl; // 1,b的值没有发生变化,因为逻辑与运算符&&具有短路特性,当a为0时,整个表达式的结果为false,b++不会被执行
	cout << (a & b++) << endl;
	cout << "b = " << b << endl; // 2
	a = 1;
	b = 0;
	cout << (a || b++) << endl;
	cout << "b = " << b << endl; // 0,b的值没有发生变化,因为逻辑或运算符||具有短路特性,当a为1时,整个表达式的结果为true,b++不会被执行
	cout << (a | b++) << endl;
	cout << "b = " << b << endl; // 1

	// 3、三目运算
	int a1 = 10;
	int b1 = 20;
	int c = a1 > b1 ? a1 : b1;
	cout << "a1 > b1 ? a1 : b1; = " << c << endl;

	cout << "-------------------------------------------------------" << endl;

	// switch 语句
	// case里如果没有break,那么程序会一直向下执行
	// switch语句中表达式类型只能是 整型 或者 字符型
	int score = 10;
	cout << "请给电影打分" << endl;

	switch (score)
	{
	case 10:
		cout << "完美" << endl;
	case 9:
		cout << "经典" << endl;
		break;
	case 8:
		cout << "非常好" << endl;
		break;
	case 7:
	case 6:
		cout << "一般" << endl;
		break;
	default:`在这里插入代码片`
		cout << "烂片" << endl;
		break;
	}
	// 输出:完美\n经典

	cout << "-------------------------------------------------------" << endl;

	// goto语句
	// 不建议使用goto语句
	cout << "1" << endl;
	goto FLAG;

	cout << "2" << endl;
	cout << "3" << endl;
	cout << "4" << endl;
FLAG:
	cout << "5" << endl;

	system("pause");
	return 0;
}

四、一维数组与二维数组

#include<iostream>
#include <string>
using namespace std;

int main() {
	//定义方式1
	//数据类型 数组名[元素个数];
	int arr[10];

	//利用下标赋值
	arr[0] = 100;
	arr[1] = 99;
	arr[2] = 85;

	//利用下标输出
	cout << arr[0] << endl;
	cout << arr[1] << endl;
	cout << arr[2] << endl;

	//定义方式2
	//数据类型 数组名[元素个数] =  {值1,值2 ,值3 ...};
	//如果{}内不足10个数据,剩余数据用0补全
	int arr2[10] = { 100, 90,80,70,60,50,40,30,20 };

	//输出
	cout << arr2[0] << endl; // 100
	cout << arr2[9] << endl; // 0

	//定义方式3
	//数据类型 数组名[] =  {值1,值2 ,值3 ...};
	int arr3[] = { 100,90,80,70,60,50,40,30,20,10 };

	for (int i = 0; i < sizeof(arr3) / 4; i++) {
		cout << arr3[i] << endl;
	}

	cout << arr3 << endl; // 输出数组名,输出的是数组首元素的地址

	cout << "-------------------------------------------------------" << endl;

	// 二维数组定义的四种方式:
	//方式1  
	//数组类型 数组名 [行数][列数]
	int arr4[2][3];
	arr4[0][0] = 1;
	arr4[0][1] = 2;
	arr4[0][2] = 3;
	arr4[1][0] = 4;
	arr4[1][1] = 5;
	arr4[1][2] = 6;

	// 打印 
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 3; j++) {
			cout << arr4[i][j] << " ";
		}
	}
	cout << endl;

	//方式2 
	//数据类型 数组名[行数][列数] = { {数据1,数据2 } ,{数据3,数据4 } };
	int arr5[2][3] = {
		{1,2,3},
		{4,5,6}
	};

	//方式3
	//数据类型 数组名[行数][列数] = { 数据1,数据2 ,数据3,数据4  };
	int arr6[2][3] = { 1,2,3,4,5,6 };

	//方式4 
	//数据类型 数组名[][列数] = { 数据1,数据2 ,数据3,数据4  };
	int arr7[][3] = { 1,2,3,4,5,6 };
	// 在定义二维数组时,如果初始化了数据,可以省略行数

	for (int i = 0; i < sizeof(arr7) / sizeof(arr7[0]); i++) {
		for (int j = 0; j < sizeof(arr7[0]) / sizeof(arr7[0][0]); j++) {
			cout << arr7[i][j] << " ";
		}
	}
	cout << endl;
	
	system("pause");
	return 0;
}

五、函数调用、分文件函数编写

#include<iostream>
#include<string>
#include"max.h"
using namespace std;

//函数定义
int add(int num1, int num2) {
	int sum = num1 + num2;
	return sum;
}
// 或者事先声明函数原型
int sub(int num1, int num2);
int sub(int a, int b);
// 声明可以多次,但定义只能有一次

// 函数定义
void swap1(int* a, int* b);
void bubbleSort(int arr[], int size);

int main() {
	system("chcp 65001> nul");

	cout << "add(num1, num2): " << add(10, 20) << endl; // 30
	cout << "sub(num1, num2): " << sub(10, 20) << endl; // -10

	// 函数分文件编写一般有4个步骤
	//  1. 创建后缀名为.h的头文件,在头文件中写函数的声明
	//	2. 创建后缀名为.cpp的源文件,在源文件中写函数的定义
	cout << "max(num1, num2): " << max(10, 20) << endl; // 20
	
	system("pause");
	return 0;
}

max.cpp文件:

#include "max.h"

int max(int a, int b) {
	return (a > b) ? a : b;
}

max.h文件:

#include<iostream>

//实现两个数字交换的函数声明
void swap(int a, int b);

六、指针、常量指针、指针应用

注:指针里面存储的地址,可以利用*访问该地址的内容

#include<iostream>
#include<string>
using namespace std;

int main() {
	// 指针的定义和使用
	int num = 10; //定义整型变量
	int* p; //指针定义语法: 数据类型 * 变量名 ;

	//指针变量赋值
	p = &num; // &操作符获取变量num的地址,将地址赋值给指针变量p
	cout << &num << endl; // 000000ED530FFA14, 打印数据num的地址
	cout << p << endl;  // 000000ED530FFA14, 打印指针变量p
	// 上面打印的内容相同

	//2、指针的使用
	// 通过*操作指针变量访问内存中的内容,这个过程称为解引用
	cout << "*p = " << *p << endl;

	// 所有指针类型在64位操作系统下是8个字节
	cout << sizeof(p) << endl;
	cout << sizeof(char*) << endl;
	cout << sizeof(float*) << endl;
	cout << sizeof(double*) << endl;

	cout << "-------------------------------------------------------" << endl;

	// 空指针和野指针都不是我们申请的空间,因此不要访问。

	p = NULL; // 指针变量指向内存中编号为0的空间
	//内存编号0~255为系统占用内存,不允许用户访问
	//cout << *p << endl; // 运行时错误:访问了无效的内存地址
	// 即访问空指针报错

	// 野指针
	// 指针变量p指向内存地址编号为0x1100的空间
	p = (int*)0x1101;
	//cout << *p << endl; //访问野指针报错

	cout << "-------------------------------------------------------" << endl;

	// const修饰指针
	//	1. const修饰指针--- 常量指针
	//	2. const修饰常量--- 指针常量
	//	3. const即修饰指针,又修饰常量

	int a = 10;
	int b = 10;

	// 常量指针,指针指向的内容不能修改,指针本身可以修改
	// const int* 常量 指针
	const int* p1 = &a;
	p1 = &b; //正确
	//*p1 = 100; //错误

	// 指针常量,指针指向不能修改,指针指向的内容可以修改
	// int* const 指针 常量
	int* const p2 = &a;
	//p2 = &b; //错误
	*p2 = 100; //正确

	//const既修饰指针又修饰常量
	const int* const p3 = &a;
	//p3 = &b; //错误
	//*p3 = 100; //错误

	system("pause");
	return 0;
}

指针应用:

#include<iostream>
#include<string>
using namespace std;

// 函数声明
void swap1(int* a, int* b);
void bubbleSort(int arr[], int size);

int main() {
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int* pArr = arr;  //指向数组的指针
	// 数组名在表达式中会被转换为指向数组首元素的指针,因此可以直接将数组名赋值给指针变量

	cout << "第一个元素: " << arr[0] << endl;
	cout << "指针访问第一个元素: " << *pArr << endl;

	for (int i = 0; i < sizeof(arr) / 4; i++) {
		//利用指针遍历数组
		cout << *pArr << " ";
		pArr++;
	}
	cout << endl;
	cout << "-------------------------------------------------------" << endl;

	// 指针和函数,函数参数传递方式:值传递和地址传递
	int num1 = 10;
	int num2 = 20;
	swap1(&num1, &num2); // 交换成功, 地址传递,函数内交换的是num1和num2的地址中的内容
	cout << "num1 = " << num1 << endl; // 20
	cout << "num2 = " << num2 << endl; // 10
	cout << "-------------------------------------------------------" << endl;

	int arr2[10] = { 4,3,6,9,1,2,10,8,7,5 };
	int len = sizeof(arr2) / sizeof(int);
	bubbleSort(arr2, len);

	for (int i = 0; i < len; i++) {
		cout << arr2[i] << " ";
	}

	system("pause");
	return 0;
}

// 函数定义
void swap1(int* a, int* b) {
	// 相当于 int *a = &num1; int *b = &num2;
	int temp = *a;
	*a = *b;
	*b = temp;
	// 相当于把指针所指向的地址里面的值给交换了
}

// 函数定义
int sub(int num1, int num2) {
	return num1 - num2;
}

// 冒泡排序
// 等同于 void bubbleSort(int* arr, int size) 
// 相当于 int* arr = arr2;arr2是一个数组名,数组名在表达式中会被转换为指向数组首元素的指针,因此函数参数可以写成int* arr或者int arr[],两者等价
void bubbleSort(int arr[], int size) {
	for (int i = 0; i < size - 1; i++) {
		for (int j = 0; j < size - 1 - i; j++) {
			if (arr[j] > arr[j + 1]) {
				int temp = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = temp;
			}
		}
	}
}

七、结构体、结构体指针

#include<iostream>
#include<string>
using namespace std;

//结构体定义
struct student
{
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
}stu3; //结构体变量创建方式3 

// 函数声明
void printStudent(student stu);
void printStudent2(student* stu);
void printStudent3(const student* stu);

int main() {
	system("chcp 65001> nul");
	//通过结构体创建变量的方式有三种:
	// * struct 结构体名 变量名
	// * struct 结构体名 变量名 = { 成员1值 , 成员2值... }
	// * 定义结构体时顺便创建变量

	// 结构体变量创建方式1
	struct student stu1;
	stu1.name = "张三";
	stu1.age = 18;
	stu1.score = 100;

	// 结构体变量创建方式2
	struct student stu2 = { "李四",19,60 };
	//student stu4 = { "赵六", 20, 90 };
	// 创建结构体变量时,关键字struct可以省略

	// 结构体变量创建方式3,变量初始化
	stu3.name = "王五";
	stu3.age = 18;
	stu3.score = 80;

	// 结构体数组
	struct student arrStu[3] =
	{
		{"张三",18,80 },
		{"李四",19,60 },
		{"王五",20,70 }
	};

	cout << "-------------------------------------------------------" << endl;

	// 结构体指针
	struct student* p = &stu1;
	p->name = "李四"; // ->操作符访问结构体指针变量p指向的结构体变量stu1的成员

	stu1 = { "张三",18,100 };

	printStudent(stu1); //值传递,函数内修改的stu1是形参stu的副本,不会影响实参stu1
	cout << "主函数中 年龄: " << stu1.age << endl; // 18
	printStudent2(&stu1); //地址传递,函数内修改的stu1是实参stu1的地址中的内容,会影响实参stu1
	cout << "主函数中 年龄: " << stu1.age << endl; // 28

	system("pause");
	return 0;
}

//值传递
void printStudent(student stu)
{
	stu.age = 28;
	cout << "子函数中 年龄: " << stu.age << endl;
}

//地址传递
void printStudent2(student* stu)
{
	stu->age = 28;
	cout << "子函数中 年龄: " << stu->age << endl;
}

//const使用场景
void printStudent(const student* stu) //加const防止函数体中的误操作
{
	//stu->age = 100; //操作失败,因为加了const修饰
	cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;
}

文章参考:黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐