数组
定义
由数据类型相同的一系列元素组成
size_t arr[index]={ }
*当{}内列出元素的值,可以让编译器自己数出数组大小,此时index可省略不写。数组的长度可以用(sizeof arr)/(sizeof arr[0])间接得出
初始化
不完全初始化时,编译器会把剩余的未初始化的数组初始化为0.
C99中在大括号内对指定元素赋值可用{[index] = data}的形式表示
未初始化的数组不要随意使用,内部数据是随机值。
不能使用变量定义数组(新手极易犯此种错误)
ps:C99引入了“变长数组”,可以用变量定义数组,但是声明时不允许初始化。
用const声明数组
只读数组用const声明,只能检索不能修改,程序稳定性更高。
数组溢出
对于定义的type arr[index],实际的下标边界是从0~index-1
多维数组
size_t arr[index1] [index2]={ }
*二维数组的定义和赋值形式如上,不能缺省二维的长度说明
二维数组的遍历需要双重循环
用途:char类型的一维数组存放字符串:char a[ ]={‘t’,‘e’,‘x’,‘t’,’\0’}等价于char a[ ]=“text”;,二维数组能够存放多个字符串,且采用初值表进行初始化时‘\0’必须给出。此时arr[i] [j]表示引用某个字符,而arr[i]表示引用某个字符串
字符串数组
char s[]={‘h’,‘o’,‘y’,’\0’}或者char s[]={“hoy”} 输出时printf()内用%s的格式
(内部的原理是从首地址逐个取出,直到遇到‘\0’为止)
如果输出遇不到\0:按照定义变量时的存储规则(定义的先后存储时地址从大到小也是从下到上),会打印出相邻地址的字符。注意:‘\0’对应的ASCII值是‘0’,若数组后位为0也不会错误。
数组传参
将数组传入目标函数,传入的是首个元素的地址,无法在内部用sizeof(arr)/sizeof(0)得到数组长度,所以必须要在外部算出数组长度再把长度一起传入。/将数组传入函数时,要单独传入数组的大小/
一定记住!传入的是地址 地址 !不是整个数组的值!必须同时传入长度 长度 长度!
长度要在主函数内算出来
k
深入理解数组
在C中数组名表示第0个元素的地址,即对于定义的a[index]数组,a等价于&a[0],实质是一个地址常量,其值不能更改,做比较也无意义。
- 存储:连续存放
- 数组名:首元素的地址。 *arr——读取首元素的值
例外!:sizeof()内部单独放一个数组名,计算的是整个数组占的字节大小。&数组名,取出的是整个数组的地址,虽然和首元素地址相同但是跨度是整个数组!
指针
定义
存放变量的地址。一定要指向一个变量
int *p = &x;
同一个变量可以有多个指针指向它,但一个指针不能同时指向多个变量,指针的指向可以修改
空指针:给指针赋一个NULL值 int *p = NULL; p的地址为0x0
检查空指针:
- if(p) //如果非空(可访问)则执行
- if(!p) //如果为空(不可访问)则执行
*多级指针:int *pp 存放*p的地址
*解引用操作符:通过地址找到对象。对pp的解引用找到的是p, 而*p就访问到x
指针的运算
-
指针的递增递减:p++ (p–)用指针代替数组,因其自增自减的性质,从而便于顺序访问内存中的每一个元素。注意区分*p++——(++的对象是指针)和§++——(p所指对象++)
数组名称不能做加减运算操作,只有指针才可以;指针的加减按照单元(根据类型分配字节数)。
-
指针的比较:地址的比较,可以用作遍历数组的循环条件等。
应用场景
1、函数需要返回多个值,即需要保存多个变量的改变量
2、函数返回运算状态,结果由指针返回
传入数组就是传入指针,指针可以当作数组使用,只要传入大小. *数组是const的指针,即int b [ ] ;等价于int * const b ;
const int p=&i; 表示不能通过p去修改i,但变量仍可被赋值,p也可以指向其他的变量。
在函数中改变数组的元素,main中的数组元素的值也改变。
3、用指针来存放字符串,字符串存储在常量区,无法对**p[0]**进行修改,
数组保存的字符串以变量形式存储在栈中
需要使用时即调用,效率高,开辟的存储空间少。
常用重定义:typedef char * string;
指针数组
实质是数组,存放指针。
int* arr[3] = {&a,&b,&c};
深入理解指针的存储
指针本身需要计算机用内存存储。
无论什么类型的指针,占据的内存区大小是相同的
这就是为什么sizeof一个数组时(数组跟指针有互通之处)得出的值恒为8或4了。
函数指针
void ( funcP) ();* 定义
funcP = function; 指向函数,不要写成function()
(*funcP)(); 等价于 funcP(); 等价于 function(); 使用