指针:
1.定义:指针指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。例如:
int *ptr;
char *ptr;
int **ptr;
int (*ptr)[3];
int *(*ptr)[4];
2.运算符&和*:&是取地址运算符,&a的运算结果就是a的地址。
3.空指针:int *p1=nullptr;int *p2=0;int *p3=NULL;
4.通用指针:void*
引用:
1定义:.它可以作为对象的另一个名字,通过引用可以间接地操纵对象,使用方式类似于指针但是不需要指针的语法,用&来定义。
2.与指针的区别引用:不能重新绑定到另一个对象。引用不存在空引用。
右值引用:
1.定义:只能绑定到一个将要到一个将要销毁的对象。
2.用m&&表示。例如:int i=42;int &r=i;int &&rr=i*5;
const限定指针和引用:
1.指向常量的指针:不允许修改ival的值:const int ival=1024;
2.指向非const对象的const指针:
int *const pi=&ival;它表明pi是一个常量,它指向并且一直指向ival,但是*pi可以改变。
3.指向const对象的const指针。const int* const pi=&ival;它说明 pi的指向不能改变并且指向常量。
结构体:
定义:结构体把一组来自不同类型的数据组合在一起构成复合类型,其中每个数据都是结构体的成员。关键字由struct定义。例如:struct X{char c;int i;float f;double d;};
. X s1,s2;
. X* ps=&s1;
s1.c='a';
标准库类型string
1.定义和初始化
默认初始化:string s1;
string s2=s1;
string s3="hello"
string s4;
2.string对象上的操作
os<<s 输入流 is>> 从输入流中读取字符串赋值给s s.empty() s为空返回true 否则返回false
如果希望在读取的字符串中能保留输入时的空白符,使用getline()函数:输入流对象和存放读入字符串的string对象,遇到换行符为止。
容器vector
1.标准库类型vector表示对象的集合,其中所有对象的类型都相同,可以通过索引访问各个对象,像vector这样容纳着其他对象的对象称为为容器。vector是长度可变的向量。
2.操作:v.push_back(t):向v的尾端添加一个值为t的元素。
v.pop_back()删除v末尾的元素。
函数
1函数的定义
函数定义的语法形式:
数据类型 函数名(形式参数表)
{
函数体 //执行语句
}
函数返回值类型 函数体中由return语句返回的值的类型。没有返回值其类型为void
(2)函数定义的例子
定义一个函数,返回两个数中的较大数。
int max(int x,int y)
{
if(x>y) return x;
else return y;
}
2 函数的声明和调用
(1)函数的声明
调用函数之前先要声明函数原型,按如下形式:
类型说明符 被调函数名(形式参数表);
例如
int js(int n);
也可以
int js(int);
(2)函数的调用
调用形式:函数名(实际参数表)
3 函数调用方式
(1)传值调用
传值调用就是指当一个函数被调用时,根据实参和形参的对应关系将实参的值一一
复制给形参,即实参的值单向传递给形参。函数本身不对实参进行任何操作,
即使形参的值在函数中改变,实参的值也不会受到影响。
(2)传引用
引用的概念:
类型名 & 引用名 = 某变量名;
某个变量的引用,和这个变量是一回事,相当于该变量的一个别名
int n = 4;
int & r = n;
r = 4;
cout << r; //输出 4;
cout << n; //输出 4;
n = 5;
cout << r; //输出5
(注:定义引用时一定要将其初始化成引用某个变量,不初始化编译不过。
引用只能引用变量,不能引用常量和表达式)
引用的作用:
void swap( int & a, int & b)
{
int tmp;
tmp = a; a = b; b = tmp;
}
int n1, n2;
swap(n1,n2) ; // n1,n2的值被交换
(3)传地址
如果在函数定义时将形参说明成指针,调用函数时就需要指定地址值形式的实参。这时的参数传递方式就是按地址传递方式。 按地址传递与按值传递的不同在于:形参指针和实参指针指向同一个地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
例:
#include <iostream>
using namespace std;
void swap(int*,int*);
int main()
{
int a = 3, b = 4;
cout << "a = " << a << ", b = "
<< b << endl;
swap(&a,&b);
cout << "a = " << a << ", b = "
<< b << endl;
system("pause");
return 0;
}
void swap(int *x,int *y)
{
int t = *x;
*x = *y;
*y = t;
}
4 递归函数
直接或间接调用自身的函数称为递归函数
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
(1)递归的基本思想
问题分解:
把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的小问题,
最小问题可以直接解决。
(2)递归的关键在于找出递归定义和递归终止条件。
递归定义:使问题向边界条件转化的规则。递归定义必须能使问题越来越简单。
递归终止条件:也就是所描述问题的最简单情况,它本身不再使用递归的定义。
5.函数重载:允许多个函数共享同一个函数名。
例如对print()函数做如下定义:
void print (const int *b,const int *e){...}
void print(const int ia[],size_t size) {...}
当调用重载函数时,编译器会根据实参的类型判断出要调用的是哪个函数。