数组和指针
头文件:把函数原型和已定义的字符常量放在头文件中是一个良好的编程习惯
指针取址运算符 &
用于拿到变量的存储地址
指针是一个值为内存空间的变量,指针的值就是地址
间接运算符 *
间接运算符能够拿到指针所指向的地址的内存空间中存放的值
普通变量把值作为基本量,把地址作为通过&运算符获得的派生量,而指针变量把地址作为基本量,把值作为通过*运算符获得的派生量。
数组:数组由一系列类型相同的元素组成。需要使用数组时,通过声明数组告诉编译器数组中内含多少元素和这些元素的类型。编译器根据这些信息正确地创建数组,普通版变量可以使用的类型数组都能使用。
数组可以使用const关键字声明为只读类型
数组创建时可以不初始化,也可以不完全初始化,也可以不声明数组大小,编译器会根据初始化时赋的值的个数进行分配数组大小
C99新特性,新增一个指定初始化器:可以在数组初始化时指定想要初始化的数组元素。
如果指定初始化之后,则后续的值会跟在指定初始化之后,如:int i[] = {1,[2] = 2,3},则数组为{1,0,2,3}
C中不允许把数组作为一个单元赋值给另外一个数组
数组边界:数组在申明和使用过程中需要防止数组下标越界
在C标准中,数组下标越界是未定义的,所以编译器不会报错,但是,错误下标的数组元素中的值可能会存储到一个错误的位置,从而导致程序出现错误。
变长数组:在C99新标准之后才允许声明的数组
多维数组:数组的数组,每一个维度下的每一个子元素都是可以作为一个数组存在
二维数组:其中每一个元素都是一个一维数组。
指针和数组:
指针能够有效的处理数组,数组表示法其实是变相的使用指针
指针的值是它所指向的对象的地址,地址的表达方式依赖于计算机内部的硬件,许多计算机都是按照字节编址的,
意思是内存中的每一个字节都按照顺序编号,这里一个较大对象的地址通常是该对象的第一个字节的地址
指针加一,指针的值递增它所指向的类型的大小。
PS:itn * ptr; int i [2] = {1,2}; ptr = i; ptr+1 相当于指针地址加一,(ptr+1),相当于数组中的第二个元素,ptr+1,相当于数组的第一个元素的值加一
在声明函数原型时,可以把数组形参声明为指针类型形参,两者是等价的。
可以在函数形参中使用两个指针类型的形参表示一个数组,一个表示数组开始位置地址,一个表示数组结束位置地址。
指针表示法和数组表示法:
处理数组的函数实际上用指针作为参数,但是在编写这样的函数时,可以选择使用数组表示法还是指针表示法
指针的基本操作:
赋值:可以把地址值赋予给指针,注意地址值应当与指针的类型兼容,
解引用:解引用运算符给出指针在地址上储存的值,
取址:和所有的变量一样,指针变量也有自己的地址和值,对于指针而言,使用&运算符给出指针本身的地址。
指针和整数相加:可以使用 + 运算符把指针和整数相加,无论那种情况,整数都会和指针指向的类型的大小相乘,然后把结果和初始地址相加,
递增指针:递增指向数组元素的指针可以让该指针移动到数组的下一个元素。
指针减去一个整数:计算方式和指针整数相加类似,都是先相乘再进行相减。
递减指针:指针移动到前一个元素
指针求差:计算两个指针之间的差值,,只有两个求差的指针都指向同一个数组时才能准确的求出差,差值的单位是数组类型
可以对形参使用const,将其声明为无法改变的类型/。创建指针时可以使用两次const,使这个指针指向的地址值不能改变,其指针指向的内容也不能改变。
指针和多维数组:在多维数组中,i[0]代表了数组首位元素i[0][0]的地址值,效果等同于 i和&i[0][0]
指向一个二维数组的指针:int ( pz)[2];
多维数组中,每多一个维度则,指针解引用次数加一
指针的兼容性:指针类型之间的赋值比数组类型之间的赋值更加严格,决不能跨类型给指针赋值同时:
int ar[3][2]; int (pz)[3]; 不能将ar赋值给pz,因为ar数组和pz指针所指向的对象不一样。
只能把非const的数据赋给指针,但是在C中能够把const指针赋给非const指针
通常,使用函数处理数组的时候, 这样特定的函数中解决待定的问题,有助与实现程序的模块化,在把数组作为实际参数时,传递给函数的不是整个数组,而是数组的地址(因此,函数对应的形参是指针)
为了处理数组,函数必须知道从何处开始读取数据,和要寒促里多少数组元素,数组地址提供了‘地址’,‘元素个数’,可以内置在函数中,或作为单独的参数传递。
小结:
数组是一组数据类型相同的元素,元素按照顺序存储在内存中,通过整数下标,可以访问各元素,在C中,数组首元素的下标是0,所以对于内含n个元素的数组,其最后一个元素的下标是n-1;
在C中,把数组名解释为该数组的首元素的地址,就是说,数组名与指向该数组的首元素的指针等阶,对于C而言,不能把整个数组作为参数传递给函数,但是可以传递数组的地址,
然后函数可以函数可以用传入的地址操控原始数组。如果函数没有修改原始数组的意图,则可以使用const声明形参,在被条函数中可以使用数组表示法或则指针表示法,无论那种表示法,
最终使用的都是指针变量。
C中处理多维数组的传统方法是把数组名传递给类型匹配的指针形参,声明这样的指针形参要指定多有的数组维度,除了第一个维度之外,通常把第一个维度作为第二个参数传递进函数。
处理字符串数组时,有个特殊的规则,由于字符串数组的结尾是拥有一空字符的,所以,可以通过这个就知道字符串的结尾,不需要通过其余方式进行判断。
网友评论