C语言数组和指针

来源:互联网 发布:搭建php开发环境 编辑:程序博客网 时间:2024/06/14 12:07
1. 数组和指针的声明:    1. 指向整数的指针声明:int *x;    2. 整数数组声明:int y[ ];2. 如果把int mango[100]用int *mango来使用,就会发生类型不匹配错误(一个是指针,一个数数组名)。3. 声明和定义:    1. 定义只能进行一次,只能出现在一个地方。定义相当于特殊的声明,它为对象分配内存。    2. 声明可以多次出现。它所说的并非自身,而是描述其他地方的创建的对象。声明中并没有为数组分配内存,所以并不需要提供关于数组长度的信息。对于多维数组,需要提供除最左边一维之外其他维的长度。4. C语言要求表达式的左值是可以修改的,数组名也用于确定对象在内存中的位置,也是可以修改的左值,但是它不能作为赋值的对象。数组名是不可修改的左值。通俗的讲,只能给可以修改的东西赋值。5. 数组名是一种符号,其地址在编译时可知。如果编译器需要一个地址来执行某种操作,它就可以直接进行操作,而不需要增加指令首先取得具体的地址。但是对于指针,必须首先在运行时取得它的当前值,然后才能对它进行解除引用操作。这就是为什么 char a[ ]和char a[100]等价的原因。这两个声明都提示a是一个数组,也就是一个内存地址,数组内的字符可以从这个地址找到。编译器并不需要知道数组总共有多长,因为它只产生偏离起始地址的偏移地址。6. 定义为指针,可以按照数组的方式引用,但是定义为数组的变量不能按照指针的方式来引用。例如int *p, p[2]这种引用方式是合法的(首先获得p指向的变量地址,然后在此基础上加2。结果为将p声明为数组是下标为2的值),但是对声明为数组的变量指针引用是不合法的(会将数组名作为指针寻得所指地址并在此基础上加偏移量索引,有内存泄露和程序崩溃的风险)。7. 数组和指针的对比:    1. 指针保存数据的地址。数组保存数据。    2. 指针间接访问数据,首先取得指针的内容,把它作为地址,然后从这个地址提取数据,如果指针有一个下标[I],就把指针的内容加上I作为地址,从中提取数据。数组直接访问数据,a[I]只是简单地以a+I为地址取得数据。    3. 指针通常用于动态数据结构。数组通常用于存储固定数目且数据类型相同的元素。    4. 指针相关的函数有malloc( ),free( )。数组隐式分配和删除内存。    5. 指针通常指向匿名的数据。数组自身即为数据名。    6. 用指针定义的字符串常量不能被修改,数组定义的字符串常量可以被修改。8. 所有作为函数参数的数组名总是可以通过编译器转化为指针。9. 对编译器而言,一个数组就是一个地址,一个指针是地址的地址。10. 下列情况下,对数组的引用不能用指向该数组第一个元素的指针来代替:    1. 数组作为sizeof( )函数的操作符。显然此时需要的是整个数组的大小,而不是指针所指向的第一个元素的大小。    2. 使用&操作符取数组的地址。    3. 数组是一个字符串(或宽字符串)常量初始值。11. 什么时候数组和指针是相同的:    1. 表达式中的数组名(与声明不同)被编译器当做一个指向该数组第一个元素的指针。例:int a[10], *p, i =2。下面的三种方式都可以访问a[i]:        1. p=a; p[i];        2. p=a;*(p+i);        3. p=a+i;*p;    2. 下标总是与指针的偏移量相同。指针和偏移量是底层硬件所使用的基本模型,但是在处理一维数组的时候,指针并不见得比数组快。指针和数组的同等实现:    3. 在函数参数的声明中,数组名被编译器当做指向该数组第一个元素的指针。作为参数传递的时候,编译器只是向函数传递数组的地址,而不是数组的拷贝。因此下面三种传递方式都是合法的:        1. my_function(int *turnip){...}        2. my_function(int turnip[ ]){...}        3. my_function(int turnip[200]){...}

这里写图片描述

0 1
原创粉丝点击