C++学习笔记【基础篇】
【1】变量的声明
C++中的变量可以在多个地方多次声明,但只能定义一次。
在一个文件中的变量的声明、定义和初始化操作:
#include <iostream>
using namespace std;
extern int a; //声明
int main() {
int a; //定义
a = 5; //初始化
cout << "a = " << a << endl;
return 0;
}
【2】C++ 变量作用域
作用域是程序的一个区域,一般来说有三个地方可以定义变量:
①在函数或一个代码块内部声明的变量,称为局部变量。
②在函数参数的定义中声明的变量,称为形式参数。
③在所有函数外部声明的变量,称为全局变量。
需要注意:当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值:
【3】定义常量
在 C++ 中,有两种简单的定义常量的方式:
- 使用 #define 预处理器。
- 使用 const 关键字。
#include <iostream>
using namespace std;
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'
int main()
{
int area;
area = LENGTH * WIDTH;
cout << area;
cout << NEWLINE;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE = '\n';
int area;
area = LENGTH * WIDTH;
cout << area;
cout << NEWLINE;
return 0;
}
【4】数据类型
可以通过运行以下程序来查看你电脑上各种数据类型的大小。
#include<iostream>
#include <limits>
using namespace std;
int main()
{
cout << "type: \t\t" << "************size**************"<< endl;
cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);
cout << "\t最大值:" << (numeric_limits<bool>::max)();
cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;
cout << "char: \t\t" << "所占字节数:" << sizeof(char);
cout << "\t最大值:" << (numeric_limits<char>::max)();
cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;
cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);
cout << "\t最大值:" << (numeric_limits<signed char>::max)();
cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;
cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);
cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();
cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl;
cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);
cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();
cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;
cout << "short: \t\t" << "所占字节数:" << sizeof(short);
cout << "\t最大值:" << (numeric_limits<short>::max)();
cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;
cout << "int: \t\t" << "所占字节数:" << sizeof(int);
cout << "\t最大值:" << (numeric_limits<int>::max)();
cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;
cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);
cout << "\t最大值:" << (numeric_limits<unsigned>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;
cout << "long: \t\t" << "所占字节数:" << sizeof(long);
cout << "\t最大值:" << (numeric_limits<long>::max)();
cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;
cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);
cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;
cout << "double: \t" << "所占字节数:" << sizeof(double);
cout << "\t最大值:" << (numeric_limits<double>::max)();
cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;
cout << "long double: \t" << "所占字节数:" << sizeof(long double);
cout << "\t最大值:" << (numeric_limits<long double>::max)();
cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;
cout << "float: \t\t" << "所占字节数:" << sizeof(float);
cout << "\t最大值:" << (numeric_limits<float>::max)();
cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;
cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);
cout << "\t最大值:" << (numeric_limits<size_t>::max)();
cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;
cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;
// << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl;
cout << "type: \t\t" << "************size**************"<< endl;
return 0;
}
【5】typedef 声明
#include <iostream>
using namespace std;
typedef int zheng; //将int重命名为zheng
int main() {
zheng a = 50; //定义变量a,a的值为50
cout << "a = " << a << endl;
return 0;
}
运行结果如下:
a = 50
【6】extern 声明
当您有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数。
extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候,如下所示:
第一个文件:main.cpp
#include <iostream>
int count ;
extern void write_extern();
int main()
{
count = 5;
write_extern();
}
第二个文件:support.cpp
#include <iostream>
extern int count;
void write_extern(void)
{
std::cout << "Count is " << count << std::endl;
}
可以看到,在support.cpp文件中需要用到main.cpp文件中定义的count全局变量,因此在support.cpp文件中需要用extern来声明main.cpp文件中的count变量,这样就能实现在support.cpp文件中访问main.cpp文件中的count变量的目的。同理,在main.cpp文件中需要访问support.cpp文件中的void write_extern(void)函数。也需要用extern来声明。
【7】C++运算符
参考菜鸟教程,很详细。链接:https://www.runoob.com/cplusplus/cpp-operators.html
【8】C++函数
①值传递
②引用传递
③指针传递
参考菜鸟教程,链接:https://www.runoob.com/cplusplus/cpp-functions.html
最后总结值传递与引用传递的区别:
1. 在函数定义格式上有不同:
值传递在定义处是:swap(int x, int y);
引用传递在这义处是:swap(int &x, int &y);
2. 调用时有相同的格式:
值传递:swap(a,b);
引用传递:swap(a,b);
3. 功能上是不同的:
值传递的函数里操作的不是a,b变量本身,只是将a,b值赋给了x,y函数里操作的只是x,y变量而不是a,b,显示a,b的值不会被swap函数所修改。
引用传递swap(a,b)函数里是用a,b分别代替了x,y。函数里操作的是a,b。
【9】C++数学运算
C++ 内置了丰富的数学函数,可对各种数字进行运算。下表列出了 C++ 中一些有用的内置的数学函数。
为了利用这些函数,您需要引用数学头文件 。
示例代码如下:
#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
// 数字定义
short s = 10;
int i = -1000;
long l = 100000;
float f = 230.47;
double d = 200.374;
// 数学运算
cout << "sin(d) :" << sin(d) << endl;
cout << "abs(i) :" << abs(i) << endl;
cout << "floor(d) :" << floor(d) << endl;
cout << "sqrt(f) :" << sqrt(f) << endl;
cout << "pow( d, 2) :" << pow(d, 2) << endl;
return 0;
}
【10】C++数组
①一维数组
int a[5] = {1,2,3,4,5};
或者
int a[] = {1,2,3,4,5};
或者
int a[5];
a[0] = 1; a[1] = 2;……
也可以采用for循环赋值;
② 二维数组
一个二维数组可以被认为是一个带有 x 行和 y 列的表格。下面是一个二维数组,包含 3 行和 4 列:
int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
内部嵌套的括号是可选的,下面的初始化与上面是等同的:
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
还有指针数组等等,详见菜鸟教程:https://www.runoob.com/cplusplus/cpp-arrays.html
动态二维数组详见:https://blog.csdn.net/qq_26822029/article/details/85037209
【11】C++指针
指针是用来存放变量地址的。如下:
int *p;
int a = 20;
p = &a; //将a的地址赋值给p指针
另外,指向指针的指针用来存放指针的地址。如下:
int a = 50;
int *p;
int **pa;
p = &a; //存放变量a的地址
pa = &p; //存放指针p的地址
详见:https://www.runoob.com/cplusplus/cpp-pointers.html
【12】C++结构体
话不多说,直接看例子:
#include <iostream>
#include <cstring>
using namespace std;
// 声明一个结构体类型 Books,使用typedef重命名是个好习惯
typedef struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
}books;
//指针传递
void point_print(books *book);
//值传递
void value_print(books book);
int main()
{
books Book1; // 定义结构体类型 Books 的变量 Book1
books Book2; // 定义结构体类型 Books 的变量 Book2
// Book1 详述
strcpy_s(Book1.title, "C++ 教程");
strcpy_s(Book1.author, "Runoob");
strcpy_s(Book1.subject, "编程语言");
Book1.book_id = 12345;
// Book2 详述
strcpy_s(Book2.title, "CSS 教程");
strcpy_s(Book2.author, "Runoob");
strcpy_s(Book2.subject, "前端技术");
Book2.book_id = 12346;
//调用指针传递函数输出信息
point_print(&Book1);
point_print(&Book2);
//调用值传递函数输出信息
value_print(Book1);
value_print(Book2);
return 0;
}
//指针传递函数,需使用->运算符访问结构体成员
void point_print(books *book) {
cout << book->author << endl;
cout << book->book_id << endl;
cout << book->subject << endl;
cout << book->title << endl;
return;
}
//值传递函数,需使用.运算符访问结构体成员
void value_print(books book) {
cout << book.author << endl;
cout << book.book_id << endl;
cout << book.subject << endl;
cout << book.title << endl;
return;
}
【13】C++预编译
#ifndef SOMETHING_H
#define SOMETHING_H
//…各种宏定义,函数声明,变量声明
#endif
一般在头文件中都使用预编译语句,防止重编译。SOMETHING_H一般就是.h头文件全名大写。
#ifndef起到的效果是防止一个源文件多次包含同一个头文件,而不是防止两个源文件包含同一个头文件。网上很多资料对这一细节的描述都是错误的。事实上,防止同一头文件被两个不同的源文件包含这种要求本身就是不合理的,头文件存在的价值就是被不同的源文件包含。 假如你有一个C源文件,它包含了多个头文件,比如头文件A和头文件B,而头文件B又包含了头文件A,则最终的效果是,该源文件包含了两次头文件A。如果你在头文件A里定义了结构体或者类类型(这是最常见的情况),那么问题来了,编译时会报大量的重复定义错误。
需要注意的是:如果在一个头文件中定义了全局变量,比如头文件A中定义了全局变量int a,在源文件B和源文件C中同时包含可头文件A,那么即使使用了#ifndef语句,依然会报大量重复定义的错误。但是,如果是声明全局变量的话(必须用extern关键字声明),即不给它赋值,则不会报错。
【14】C++头文件编写规范
一般来说头文件编写的内容为以下四点:
①宏定义
②外部变量声明
③函数声明
④包含头文件(可用可不用)
例子如下:
#ifndef SD_H_
#define SD_H_
// 包含头文件
#include <stdio.h>
#include "sys.h"
// 宏定义
#define SD_TYPE_ERR 0X00
#define SD_TYPE_MMC 0X01
// 外部变量声明
extern int SD_Type; //SD卡的类型
//函数声明
char SD_SPI_ReadWriteByte(char data);
void SD_SPI_SpeedLow(void);
void SD_SPI_SpeedHigh(void);
#endif
【15】面向对象——继承
三类继承的特点: