C++基础
1、不同数据类型的区别
-
表示意义不同
-
占用内存不同
-
表示的范围不同
-
使用方法不同
2、*变量名的命名规范*
1)只能包含3种字符(数字、大/小写字母,下划线)
2)不能以数字开头(即,只能以字母或下划线开头)
int 2name; //非法
3)不能和“关键字”同名(c语言内部已经使用的“名称”),比如类型名int
3、命名风格:
1)下划线风格
int student_age; (一般用于变量名、函数名)
2)小驼峰风格
int studentAge; (一般用于变量名、函数名)
1)大驼峰风格
class StudentAge; (一般用于“类名”)
2)全部大写 (一般用于宏)
#define MAX_AGE 30
4、cin.sync()在VS中失效!
C++的标准中, cin.sync()是清空缓冲区,但是实际的实现取决于编译器.
如果使用vc++或者g++编译器,是可以的, 但是使用vs中的编译器,就不可以.
void clearBuff() {
char tmp;
while ((tmp = getchar()) != '\n');
}
5、左移与右移
*<< 左移*
右边的位用 0 来填充, 移动超出左边边界的位则直接抛弃。
向左移动 n个位置,就等同于乘以 2的n次方
*>> 右移*
如果左操作数是无符号类型,则左边多出来的位用 0 来填充。
如果左操作数是有符号类型,则左边多出来的位用 符号位(最高位) 来填充。
向左移动 n个位置,就等同于除以 2的n次方。
只适用于: int/short/long/char 等定点数类型(float/double浮点数类型不能使用)
6、*逗号运算符*
优先级最低。
#include <stdio.h>
int main(void) {
int x;
// 先计算 x = 3+5, 再计算3*5
x = 3+5, 3*5, 10/5;
printf("x=%d\n", x); //x=8
//取最后一个表达式的值,作为整个“逗号表达式”的值
x = (3+5, 3*5, 10/5);
cout << x << endl; //x=2
return x;
}
7、*三目运算符*
条件 ? 表达式1 :表达式2
如果条件为真,就取表达式1作为整个表达式的值
如果条件为假,就取表达式2作为整个表达式的值
8、运算符的优先级
最高优先级:( )和[ ]
最低优先级:逗号表达式
倒数第二低优先级:赋值和复合赋值(=, +=, -= …)
x = a+ b*c;
! > 算术运算符 > 关系运算符 > && > || > 赋值运算符
9、函数重载
函数名相同, 但是, 函数的参数(形参)绝不相同:
-
参数个数不同
-
或参数个数相同, 但是参数的类型不同
只有返回类型不同,不能构成函数重载
只有形参变量名不同, 不能构成函数重载.
注意: C语言不支持函数重载
10、内联函数
内联函数:
当编译器在编译时, 如果遇到内联函数,
就会直接将整个函数体的代码插入”调用处”,
就相当于内联函数的函数体, 在调用处被重写了一次。
以避免函数调用的开销, 获得更快的时间。
内联函数的缺点:
使调用内联函数的程序,变得“臃肿”,消耗调用函数的“栈”空间。
内联函数的用法:
inline int add(int a, int b)
{
return a + b;
}
内联函数的使用场合:
1)内联函数中的代码应该只是很简单、执行很快的几条语句。
2)这个函数的使用频度非常高,比如在一个循环中被千万次地使用。
数的定义(即整个数体),而不能只出现内联函数的声明
11、断言
. 对非预期错误使用断言
(1)空指针。
(2)输入或者输出参数的值不在预期范围内。
(3)数组的越界。 处理方式:如果断言的条件返回错误,则终止程序执行。
原型定义: assert 的作用是先计算表达式 expression ,如果其值为假(即为 0),那么它先 向 stderr 打印一条出错信息, 然后通过调用 abort 来终止程序运行。
#include
void assert( int expression );
12、为什么要使用指针
1、函数的值传递,无法通过调用函数,来修改函数的实参
2、被调用函数需要提供更多的“返回值”给调用函数
3、减少值传递时带来的额外开销,提高代码执行效率
13、 什么是空指针?
空指针,就是值为 0 的指针。(任何程序数据都不会存储在地址为 0 的内存块中,它是被操作系 统预留的内存块。)
int *p = 0;
或者
int *p = NULL; //强烈推荐
14、 空指针的使用
1)指针初始化为空指针 int *select = NULL; 目的就是,避免访问非法数据。
2)指针不再使用时,可以设置为空指针
int *select = &xiao_long_lv;
select = NULL;
3)表示这个指针还没有具体的指向,使用前进行合法性判断
int *p = NULL;
// 。。。。
if ( p ) { //p 等同于 p!=NULL //指针不为空,对指针进行操作 }
15、坏指针
int *select; //没有初始化
情形一 printf(“选择的房间是: %d\n”, *select);
情形二 select = 100;
printf(“选择的房间是: %d\n”,
16、const和指针
int * zha_nan = &wife//可以随意赋值
const int * zhi_nan = &wife; //第一种写法
int const * zhi_nan = &wife; // 第二种写法--可以指向别的地址,不能*zhi_nan=10;
int * const nuan_nan = &wife;//不可以指向别的地址,不能nuan_nan=&xxx;
const int * const super_nuan_nan = &wife; //不允许指向别的地址,不能修改指向变量的值
总结: 看 const 离类型(int)近,还是离指针变量名近,离谁近,就修饰谁,谁就 不能变
17、 变量的 4 种存储类型
1、auto - 函数中所有的非静态局部变量。
2、register - 一般经常被使用的的变量(如某一变量需要计算几千次)可以设 置成寄存器变量,register 变量会被存储在寄存器中,计算速度远快于存在内存 中的非 register 变量。
3、static - 在变量前加上 static 关键字的变量。
4、extern - 把全局变量在其他源文件中声明成 extern 变量,可以扩展该全局变 量的作用域至声明的那个文件,其本质作用就是对全局变量作用域的扩展。
18、变量的作用域和生存周期
存储类别 | 存储期 | 作用域 | 声明方式 |
---|---|---|---|
auto | 自动 | 块 | 块内 |
register | 自动 | 块 | 块内,使用关键字 register |
static(局部) | 静态 | 块 | 块内,使用关键字 static |
static(全局) | 静态 | 文件内部 | 所有函数外,使用关键字 static |
extern | 静态 | 文件内部 | 所有函数外 |
19、内存泄漏检测工具
VisualC++ debugger 和 CRT 库
第一步: 包含以下头文件
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
第二步: 接管 new 操作符
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ ,__LINE__)
#define new DBG_NEW
#endif
#endif
第三步: 在代码结束出输出内存泄漏信息
_CrtDumpMemoryLeaks();
内存泄漏工具: Windows : Purify,BoundsCheaker、Deleaker、VisualLeak Detector(VLD),
Linux 平台:Valgrind memcheck