1. 计算机组成
- 输入设备
- 控制器
- 存储器
- 运算器
- 输出设备
2. 基础信息
一些关键字(保留字),标识符第一个字符必须是字母或者下划线,不能是数字。
iostream 包含输入和输出流的基本运算。 命名空间,指名程序变量所在空间。
cout表示输出流 <<表示流插入运算符, 将要输出的内容给导输出流,<< endl表示插入一个回车符号。 cin >> a >> b 表示输入流,输入一个给a 再输入一个给b;
BDOH 二十八十六进制;原码补码反码;二进制小数,运算等。
3. 实体作用域与与生命期
实体在其作用域内,均可见。
前置声明 (forward declaration): extern 类型 变量名 可以将其可见区域向前延伸
extern 返回类型 函数名( 类型1 参数名1 ...) 将函数原型向前拉。
static 类型 变量名 :私有的 对其它源文件不可用 减少作用域
在同一个工程的不同项目中,全局变量会互相干扰,应充分利用extern 和 static函数
在程序运行的过程中,系统是动态的分配空间的。这叫做自动存储。
程序员通过指令的方式人工完成的上述操作成为自由存储;
静态存储使得变量可以永久的占用存储空间,应当减少相关的使用。
大部分变量都是自动存储的,在前面加上auto 可以省略
register可以修饰变量为寄存器变量,可以大大加快读取速度。
静态局部变量
static 修饰,使得变成静态的局部变量,会保持其值不变。第二次重复 static int=0的时候不会再将这个数置零,这个操作会被忽略,其原本的变化过程会被永远的保持。
使得函数变成内部函数,只能由本文件使用,其他文件不能使用。
c++的函数本质上都是外部函数,extern修饰可以省略。
<>的头文件是只在系统默认路径下找,“”则需要再在用户路径下找。
所以调用自己的写的文件应该用 引号,而不是尖括号。
4. 函数的定义
一般定义:
返回类型 函数名(形参列表) //可以没有输入()内为空或者void //函数的头部叫接口
{
函数声明部分;
函数执行部分;
}
定义函数的时候用的参数,称为形式参数,在不调用此函数的时候,这些参数不占用实际的存储单元,只有在调用的时候才占用内存。调用结束后,内存会被释放。
实际参数:调用函数的时候提供给被调函数的数据,其类型次序和数目要与函数定义一致。
形参是作为内部变量,对实参产生一个副本,而不改变实参原本的值。
在函数使用之前需要对函数进行一次声明,函数的定义就是对函数的一次声明。
对函数接口进行声明,可以采用函数原型的方法。只需要声明函数的返回值和形参的列表,只用说明形参的类型,不用带形参的变量名即可。这样可以在函数定义之前,使得编译不报错。
int gcd(int,int)
用函数,以表达式的方式调用,或者利用函数调用语句调用,这主要是针对没有返回值的函数。
内联函数:可以减少原本用于函数调用的时间,但只能针对简单的函数。
将编译的时候,将函数的代码直接嵌入主函数中。
inline 返回类型 函数名...
内联函数不得有Switch结构和循环结构,必须在第一次调用之前声明其是内联函数。
函数的默认参数:
在定义函数的时候,给形式参数以默认参数;这在函数调用的时候,若给的实参数目不够,余下的参数会使用默认的值。
若在函数定义的时候设置了默认参数,就不能在声明的时候再次设置,反之亦然。
若某个参数具有了默认值,其右边的所有参数必须都有默认值。
函数重载,在用一个域中使用同一个函数名定义多个函数。其形参的数目、类型等应当有不同,其返回值类型也会不同。
由于形参列表不同,系统会自动匹配对应的参数类型列表,进行调用,无需额外声明。
5. 函数的模板
template<模板的形参列表> 返回类型 函数名(形参列表)
{
函数体
}
例如:
template <typename T>
T abs (T x) //指的是返回类型和x的类型都是T
{
return x<0? -x:x;
}
int main()
{
int n=-5;
double d=-5.1;
cout << abs(n) << ';' << abs(d) << endl;
return 0;
}
上面的 typename 也可以换成 class 但这会与后面类的声明冲突,一般都采用typename
<>内可以有多个参数,由逗号隔开。
6. 数组作为函数的输入
将整个数组名传入函数后,实际上传入的是数组头的地址,在函数中可以直接改变原数组的数值。
- 形参数组就是实参数组,在被调函数中使用形参就是在间接的使用实参,与普通变量不同。
- 当需要返回多个值的 时候,可以通过传给函数一个空数组以存储变量。
- 既然形参数组就是实参数组,则函数调用的时候,不会占用额外的存储空间。因此函数定义数组的大小没关系,可以缺省,或者更大,或者更小。因此函数调用的时候,可以额外给一个参数以标定数组的长度。
- 多维数组调用的时候,除了第一维度之外的长度必须给出。不能缺省,不能不对。
7.字符串的使用
初始化:
- C风格的初始化: char str1[20]="Java"
- string str2="Java"
- string str3("Java") //str3是一个字符串类的对象,可以用括号的方式初始化。
引用:
可以直接利用赋值运算符:
str1="Str1";
字符串的输入和输出:
cin >>
cout<<
puts(a)
get(a)
str1.c_str() //将str1转换为c风格字符串,返回值是char类型的指针。
str1.copy(S1,n,pos); 将str1的内容从pos开始复制,n个存储到S1中;
strcpy(S1,"Java") //将字符串拷贝到S1中
str1.assign(S1,n) //将S1中n个字符赋值给str1
str1 = str2 + str3 //可以使用加法运算符将两个字符串拼接起来
str1 == str2 //可以直接使用关系运算符
str1.size()
str1.length() //调用string的成员函数,等等等等一系列操作。
string SY[5]={"gzl","Cao","Liu","SunWukong"};
8. 指针的定义与使用
可以解决返回值不唯一的问题;
指针是使得两个函数进行数据交换必要的工具。
指针类型 *指针变量名 =地址初值//指针类型表明其所指向的对象的类型。
int *p,i;
p = &i;
&是取址运算符
*间接引用运算符 可以访问指针所指向的对象或内存单元。
空地址可以是Null 或者直接等于0 但不能等于一个为0的变量。
地址声明的类型应当与其指向的对象类型相同。
指针指向一个确定空间的变量(已知对象) 则称其为有效的。
空指针、未初始化的指针都不可以进行间接引用。
迷途指针:一个指针指向的原对象消亡后,其指向的地址仍未原地址,但对象变成了未知对象。
例如在调用函数中的变量,调用结束后其会消亡,全局变量的指针就可能是迷途指针。
指针加减整数运算,一般在数组中有意义。可以做自增,自减运算。
指针可以做减法运算,也是在数组中有意义,可以用来计算数组的长度。
关系运算,表示存储位置的前后关系。
const 指向类型 *指针变量 const int *p 指向const对象的指针
不能通过指针来改变其所指向对象的值。 指针本身指向的对象可以改变,但不能通过该指针改变其指向对象的值。
非const的指针不能指向const的变量。
const指针 指向类型 *const p
这类指针可以指向非const对象,但其指向的地址不能被改变。但可以通过间接引用修改其指向对象的值。
const 指向类型 *const 指针变量:既不能间接引用,也不能修改指向的地址。
9. 指针与数组/字符串
通过指针访问数组:
int *p,a[10];
p=a;
//此时a[i]与p[i]等价
*(a+i)
*(p+i) //二者等价,a实际上是第一个元素的地址,以上四者等价
下标访问法:直观
指针引用法:高效
自增和自减十分有效,可以指向数组的上一个/下一个变量。
可以通过定义一个char类型的指针,指向字符串的第一个字符。
char *p="C language"
cout << p << endl;//输出整个字符串
cout << p+2 << endl;//输出从第三个字符开始的整个字符串
//因此在输出字符串的时候,均会输出到字符的结尾。
//字符串的名字/数组名就是地址,不带中括号的时候可以当指针来用
指针并不能代替数组,数组存储的是整个字符串,而指针是首地址;存储内容不同
数组是一个常量,不能进行额外的赋值和自增自减,后者可以;运算方式不同。
不能对数组重新进行赋值操作,但指针可以任意赋值;赋值方式不同。