写在前面:掌握基本C++,带你掌握STL、Qt、MFC基础。前提你一定读过我前面的博客内容了,虽然前面写的张飞李奎一样不堪入目,但是有涵盖了基础的内容。
走近C++
记住重要关键字(关键字组合)怎么用?数据变不变?怎么变?作用域?内存中怎么放置的?
C/C++
- [C++面向对象(C面向过程) || 封装、继承、多态;可移植、C++11标准]
- C++变量检测、函数检测、类型转换检测增强(C中可行、C++不可行更加严格了) C++struct中可以增加函数
- 引用时可以不加struct 三目运算符:(a>b? a:b)=10;//C++中可以赋值操作符左边的是左值,可以放到赋值操作符右面的是右值;C中不可以(C中返回的是值,C++中返回的是变量)
- 在c++中,一个const不必创建内存空间,而在c中,一个const总是需要一块内存空间。const在C++默认内部链接C相反(extern const外部链接(变量));(分配内存便可以修改,使用指针)
- 各种语言第一步Hello Word
#include <iostream>//输入输出标准,头文件
using namespace std;//命名空间
int main()
{
std::cout << "hello word" << endl;//cout标准输出;<<左移运算符、*、&运算符;endl标准结束换行 ; :: 全局作用域 std:: std作用域
system("pause");//按任意键继续
return EXIT_SUCCESS;//EXIT_SUCCESS==0
}
头文件 | 标准约定 | 例子演示 | 说明 |
---|---|---|---|
c++旧式风格 | 以.h结尾 | iostream.h | c++程序可用 |
c旧式风格 | 以.h结尾 | math.h | c/c++程序可用 |
c++新式风格 | 无扩展名 | iostream | c++程序可用,使用namespace std |
转换后的c | 加上前缀c,无扩展名 | cmath | c++程序可用,可使用非c特性,如namespace std |
C4996错误:#define _CRT_SECURE_NO_WARNINGS
C++头文件创建和调用HelloWord:
C++几个重要关键字符
1. 作用域运算符::
- 作用域::
//全局变量 ::a 全局变量 int a = 10; //1. 局部变量和全局变量同名 void test(){ int a = 20; //打印局部变量a cout << "局部变量a:" << a << endl; //打印全局变量a cout << "全局变量a:" << ::a << endl; }
2. 命名空间 namespace
-
namespace :标准C++引入的关键字namespace(命名空间/名字空间/名称空间),可以更好地控制标识符的作用域; 必须定义在全局作用域下,可以嵌套; 命名空间是开放的(增加数据);命名空间可以无名(匿名);命名空间可以起别名(变量赋值)。
#define _CRT_SECURE_NO_WARNINGS #include <iostream>//输入输出标准 #include "01.h" using namespace std;//命名空间 namespace B { namespace A { int a = 10; } namespace A { int ab = 20; } namespace//只能在该命名空间使用 { int ac = 30; } namespace D = A; } int main() { cout << "namespace a: " << ::B::A::a << endl; cout << "namespace ab: " << ::B::A::ab << endl; cout << "namespace ac: " << ::B::ac << endl; cout << "namespace da: " << ::B::D::a << endl; system("pause");//按任意键继续 return EXIT_SUCCESS;//EXIT_SUCCESS==0 }
3. Using编译指令
-
Using编译指令 ,Using namespace xx;使用using声明或using编译指令会增加命名冲突的可能性。
#define _CRT_SECURE_NO_WARNINGS #include <iostream>//输入输出标准 #include "01.h" using namespace std;//命名空间 namespace A { int aa = 10; } void test() { //int aa = 20; using namespace A; cout << "aa:"<<aa << endl; cout << "::A::aa:" << ::A::aa << endl; } int main() { test(); system("pause");//按任意键继续 return EXIT_SUCCESS;//EXIT_SUCCESS==0 }
4. 关键字const
-
const修饰普通变量:constA在符号表中,当我们对constA取地址,这个时候为constA分配了新的空间,*p操作的是分配的空间,而constA是从符号表获得的值。
const int constA = 10; int* p = (int*)&constA; *p = 300; cout << "constA:" << constA << endl; cout << "*p:" << *p << endl; //输出:constA:10; *p: 300;
-
const修饰指针变量:A: const 修饰指针指向的内容,则内容为不可变量。B: const 修饰指针,则指针为不可变量。C: const 修饰指针和指针指向的内容,则指针和指针指向的内容都为不可变量。
-
const修饰参数传递,不可做返回值
-
const char*, char const*, char*const 的区别: 菜鸟教程.
5. 引用 &
-
引用定义: ( type+&别名 = 原名: int & b = a;)
int a = 10; int aa = 20; int &b = a;//引用必须初始化 //b = aa;//error 引用初始化后不可以修改 typedef int (ARR)[10];//定义数组
-
引用和指针:不存在空引用。引用必须连接到一块合法的内存。一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。引用必须在创建时被初始化。指针可以在任何时间被初始化。
-
引用和函数,函数传递:值传递void fun(int a, int b)、地址传递void fun(int *a, int *b)、引用传递void fun(int &a ,int &b)。地址和引用传递都可以改变值。注意事项,不要返回局部变量的引用;如果函数返回值是引用,那么函数的调用可以作为左值。引用修饰形参,修饰形参为只读;const &a =10;//分配内存
void fun (int &a, int &b) //形参为两个整型的引用 { int temp = 0; c = a; a = b; b = c; } int x = 10,y = 20; fun(x,y); //在主函数中调用时,实参传过去后a是x的别名,b是y的别名。 ///____________________________________ //将两个值进行交换 void fun( int *a,int *b) //形参为两个整型的指针变量 { int temp = 0; //定义一个临时变量。良好的习惯是定义一个变量并初始化它; c = *a; //将*a赋值给c; *a = *b; //将*b赋值给*a; *b = c; //再将c赋值给*b;这样就完成了a、b数值的交换 } int x = 10,y = 20; fun(&x,&y); //在主函数中调用时,传过去的实参需要写成 取地址a,取地址b,比较麻烦,也不易理解。
-
常量引用、指向常量的指针、常量指针的区别引用
//-------常量指针------- const int *p1 = &a; a = 300; //OK,仍然可以通过原来的声明修改值, //*p1 = 56; //Error,*p1是const int的,不可修改,即常量指针不可修改其指向地址 p1 = &b; //OK,指针还可以指向别处,因为指针只是个变量,可以随意指向; //-------指针常量-------// int* const p2 = &a; a = 500; //OK,仍然可以通过原来的声明修改值, *p2 = 400; //OK,指针是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化 //p2 = &b; //Error,因为p2是const 指针,因此不能改变p2指向的内容 //-------指向常量的常量指针-------// const int* const p3 = &a; //*p3 = 1; //Error //p3 = &b; //Error a = 5000; //OK,仍然可以通过原来的声明修改值
6. 类 和 对象
-
定义、实例化
public class Box//public 公共权限 { public: double length; // 盒子的长度 private: double breadth; // 盒子的宽度 double height; // 盒子的高度 public void printLength(int length) { cout<<length<<endl; } }; Box box1 ; box1.length = 2f;
-
类是对象的抽象,对象是对类的实例。
7. 函数
-
内联函数
为了解决宏函数不足,设计的内联函数。 内联仅仅只是给编译器(VS、MyEclipse)一个建议,编译器不一定会接受这种建议,如果你没有将函数声明为内联函数,那么编译器也可能将此函数做内联编译。一个好的编译器将会内联小的、简单的函数。#include <iostream> using namespace std; inline int Max(int x, int y) { return (x > y)? x : y; } // 程序的主函数 int main( ) { cout << "Max (20,10): " << Max(20,10) << endl; cout << "Max (0,200): " << Max(0,200) << endl; cout << "Max (100,1010): " << Max(100,1010) << endl; return 0; }
1.在内联函数内不允许使用循环语句和开关语句;
2.内联函数的定义必须出现在内联函数第一次调用之前;
3.类结构中所在的类说明内部定义的函数是内联函数。
4.不能对函数进行取址操作class Person{ public: Person() { cout << "构造函数!" << endl; } void PrintPerson(){ cout << "输出Person!" << endl; } }
构造函数Person,成员函数PrintPerson在类的内部定义,自动成为内联函数。
-
函数默认参数参考、占位参数参考。函数的默认参数从左向右,如果一个参数设置了默认参数,那么这个参数之后的参数都必须设置默认参数。如果函数声明和函数定义分开写,函数声明和函数定义不能同时设置默认参数。C语言中没有以上两种参数,C++扩展的。
-
函数重载:同一个作用域、参数个数不同、参数类型不同、参数顺序不同
#include <iostream> using namespace std; class printData { public: void print(int i) { cout << "整数为: " << i << endl; } void print(double f) { cout << "浮点数为: " << f << endl; } void print(char c[]) { cout << "字符串为: " << c << endl; } }; int main(void) { printData pd; pd.print(5); // 输出整数 pd.print(500.263); // 输出浮点数 char c[] = "Hello C++"; pd.print(c); // 输出字符串 return 0; }
返回值类型不可做为重载条件,重载内部原理:
-
extern 浅析
extern "C"void show();//C++中引用C中的show方法#ifdef __cplusplus exter "C" { } #endif