数组
数组是一组相同类型元素的集合。
数组分为一维数组和多维数组。
sizeof(数组名)/&数组名,这里的数组名表示整个数组;除外都为数组首元素地址。
一维数组:
数组名的值是一个指针常量,也就是数组第一个元素的地址,它的类型取决于数组元素的类型。数组 具有和指针完全不同的性质,例如,数组具有确定数量的元素,而指针只是一个标量值。但是在两种情况下,数组名不是用指针常量表示:1.当数组名作为sizeof操作符;2.数组名作为单目操作符&的操作数。
数组创建:type 数组名 [ ] ,[ ] 内必须是常量,不能是变量。
初始化:在创建数组时候给数组内容一些合理初始值。注意:因为编译器只知道初始值不够,但无法知道缺少的有哪些值,初始化如果要省,只能省最后几个初始值。
字符数组的初始化:
char a[ ]="abcdef", 字符数组的初始化
char *a="abcdef" , 字符串常量
数组的使用:1.数组是使用下标来访问的,下标是从0开始;2.数组的大小可以通过计算得到的。通过数组名+整数的运算,可以获取到数组每个元素的地址。
数组在内存中的存储:数组在内存中是连续存放的。
二维数组:创建二维数组 type 数组名[ ] [ ], 二维数组也是通过下标方式访问,在内存中也是连续存放的。
多维数组:如果某个数组的维数不止一个,它就称为多维数组。
存储顺序:多维数组的元素存储顺序按照最右边的下标率先变化的原则。多维数组与一维数组的区别是多维数组第一维的元素实际上是另一个数组。
数组作为函数参数时,实际传递给函数的是一个指向数组第一个元素的指针,对实参进行修改不影响原来数组元素,但是对指针参数时,允许函数修改原先的数组元素。数组形参即可以声明为数组,也可以声明为指针。这两种声明形式只有当它们作为函数的形参时才是相等的。
指针
1)指针是存放地址才出现的,地址是为了提示一块地址空间的;
2)指针让地址有地方存放 ,指针让内存的访问更加方便;
3)指针的大小在32平台是4个字节,在64平台上是8字节。
指针类型: type+ *的方式
指针类型决定了对指针解引用的时候的权限有多大,比如: char* 的指针解引用只能访问一个字节,而int* 的指针的解引用能访问四个字节。
二级指针:指针变量也是变量,是变量就有地址,存放指针变量的地址的就是二级指针。
另外注意:访问NULL指针,将隐藏错误,不容易找出,并终止程序。
指针数组
指针数组是数组,是一个存放指针的数组,如 int *a[ 10] 。
数组指针:是一个指向数组的指针。如 int (*p) [10] 。注意:[ ] 的优先级高于 * 号,所以要加上()保证p先和*结合。
函数指针
指向函数的指针 ,如 int (*p) ();
下面来看两个例子:
1).(*(void(*)())0)(); 意为:0强制转化为函数指针类型,在解引用,0的地址内容,函数为无参类型,返回值为void;
2). void (*signal(int,void(*)(int))) (int) ; 意为:signal为函数声明,signal有两个参数,一个int ,一个是函数指针,该函数指针指向int 型,返回值为void 型,signal指向 int 型,返回void 型。
函数指针数组
把一个函数的地址存到一个数组中,这个数组叫函数指针数组,定义为:int (*p[10]) ()。
指向函数指针数组的指针
指向函数指针数组的指针是一个指针,指针指向数组,数组内容是函数指针。
回调函数:
回调函数就是一个通过函数指针调用的函数。如果把函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就称为回调函数。