一、指针与函数
通过将指针作为函数参数的办法,既可以返回多个运算结果,又避免了使用全局变量。
指针变量和数组在很大程度上都是等效的。字符数组/字符串和指针变量也是等效的。
如果要返回一个地址定义的时候需要 是 char *函数名(char *p, const char *p2)
p2是不能通过地址来改变其原本里面的内容的。
在字符串拷贝过程中最好在字符串最后看是否有结束符号。
二、引用
通过对象名是无法直接引用其他的局部变量,指针访问比较抽象,阅读困难。
引用:一个对象的别名。
引用类型 &引用名称 = 对象名称
引用全部是const类型,声明后不可更改,不能在是其他对象的引用。
1. 声明一个引用变量的时候 ,必须初始化,绑定其引用的对象。
2. 不能有空引用,必须与有效对象的内存单元关联。
3. 初始化后,不得改变引用关系。
4. 指定类型的引用不能初始化不同类型的变量上。
5. 取引用的地址,和取变量的地址是相同的。
主要是将引用作为函数的形参。可以像指针一样改变原本的值。
#include <iostream>
using namespace std;
//引用作为函数形参
void swap(int &a,int &b)
{
int t;
t=a, a=b, b=t;
}
int main()
{
int x=10, y=20;
swap(x,y);
cout<<x<<","<<y;return 0;
}
引用比指针更加的直观,简便,直接。
引用作为函数的返回值:
返回值可以是一个指针,可以是一个引用。
函数返回的是一个引用,说明返回的是一个实际的变量,其可以直接作为左值。即可以直接改变其的值,给其赋值。比如通过函数计算x,y两个数中大的那个并加一,就可以返回一个引用,然后在引用上加一,就是在x或者y上面加一。
三、函数指针
函数代码在内存中也占用一定的空间,其也有地址,函数入口的地址就是函数的指针。
返回类型 (*函数指针变量名)(形式参数列表)
int max(int a, int b);//函数原型
int (*p)(int a, int b);//定义函数指针变量
p = max; //绑定指针和函数 //可以更换,指向形参一样的函数
c = p(a, b);
指向函数的指针,能够将函数调用的方式,由静态的方式,变成动态的方式,可以调用多个函数。
double integral(double a,double b,double (*f)(double x)) { //求定积分
int n=1000, i;
double h, x, s=0.0;
h=(b-a)/n;
for(i=1;i<=n;i++) {
x=a+(i-1)*h;
s=s+(f(x)+f(x+h))*h/2; //调用f函数求f(x)、f(x+h)
}
return s;
//f函数不确定,可以作为变量输入
四、动态分配内存
不需要预先分配存储空间
分配的空间可以随时扩大和缩小。
int *p1, *p2;
char *pz1;
p1= new int(10);
p2= new int;
pz1= new char[80];
delete p1;
delete [] pz1; //迷途指针
new 与 delete 必须成对使用。有分配必须有释放,不然会产生内存泄漏。不释放会导致内存占用,释放多次会导致程序崩溃。
动态分配的生存期是由程序员决定,类似于全局变量,直到delete后才会消亡,要及时将释放的指针设置为空。
所以 int a[n]不行, 但是 new int a[n]可以,静态内存的n不能是变量。
可以在程序运行的时候生成任意大小的数组;
生成n维度数组的时候:以二维为例子,总的长度是n*n,第三行第四列的地址应该是12号,只能通过地址运算:
double *A = new double [n*n];
*(A+i*n+j) = 1; //第n行第j列的地址。从0开始数
delete [] A;
char *p=new char[1000];
cin >> p;
cout << p;
delete [] p;
五、结构体
struct STUDENT{
int no;
char name[10];
char sex;
char qq[12];
} d1,d2; //可以直接实例化
STUDENT a,b; //也可以后续实例化
结构体的声明一边放在开头,使得全局都可以使用。
是一个类型的名称,不会分配存储空间。
结构体里的成员也可以是结构体。
实例化(instance)
初始化:
STUDENT s1={1001,"Liming",'M',{1980,10,6},3110.1}
s1.Name = "Liming"
s2 = s1; //结构体可以整体赋值,但不能算术和关系运算。
结构体数组:
STUDENT s[100]; //用大括号里面套大括号初始化
s[0].name = "Liming";
结构体里套结构体:
s[0].L[1].sum = 0;
结构体的地址:
char *p1;
p1 = &s[1].name; // 指向第1个人的name的存储地址
struct STUDENT m,*p;
p = &m;
用指针引用:
(*p).name;//相当于s.name
p->name;//直接引用
p->s->name;//多个结构体嵌套,s也应该是一个结构体的地址,一个指针
六、共用体类型
共用体共享存储空间,结构体内部各自有单独的存储空间:
union B{
int m;
char a;
short n;
};
共用体是按照内部最大占用空间的个体来分配内存,只能同时存在一个,他们共享空间。结构体则是他们的和,可以同时出现。
同时只能初始化一个值。输出的时候,若不足,只输出低字节的。相当于用float输出short,不同的类型决定了使用这个值的总体还是部分,低字节还是高字节。对其中一个对象复制,其他的全部改变。
对 输入的类型未知的时候,可以按照共用体先存储,之后可以任意决定输出的形式。
七、枚举类型
enum DAYS {MON=1,TUE=2};//在声明时指定常量
常量只能作为右值。
八、Typedef
typedef 已有类型名 新类型名;
typedef unsigned char BYTE;