zoukankan      html  css  js  c++  java
  • 数组与指针

    数组

    一维数组

    数组初始化之前数组元素是不确定的,当数值数量少于数组元素时,多余的数组元素被初始化为0

    只读数组初始化后不能再对它赋值

    如何计算一个数组的大小: sizeof(a)/sizeof(a[0]) 即数组大小除以单个元素的大小

    c99新特性:int arr[6]={12,[5]=22,23,[1]=35};这一语句代表第1个元素值为35,第5个值为22,第6个值为23

    数组的赋值方式:

    1. 只可以用循环来赋值
    2. 不可以用花括号赋值(仅限于数组初始化),不可以将一个数组赋给另一个数组

    数组的边界问题需要程序员来保证,编译器检查索引的合法性,因为c语言信任程序员的原则,不检查边界可以让程序运行更快,解决方法是将数组大小全部定义为符号常量,使用数组大小的时候全部直接引用符号常量

    c99之前声明数组时方括号内只能使用整数常量表达式, sizeof被认为是一个整数常量,因此可以放在数组的声明里

    指针

    在c中,对一个指针加1的结果是对该指针增加1个存储单元。这就是为什么声明指针的时候必须声明它指向的对象类型。

    将数组作为参数传入函数时,一般要同时传入数组的大小。因为作为参数传入的实际是一个指向数组元素类型的指针,在函数内部无法用sizeof得出数组的大小,只能得出这个指针的大小。

    函数原型允许省略名称:

    int sum(int *ar,int n);
    int sum(int *,int);
    int sum(int ar[],int n);
    int sum(int [],int);
    

    函数定义不可以省略名称:

    int sum(int *ar,int n){
      //代码
    }
    int sum(int ar[],int n){
      //代码
    }
    

    使用数组的函数有两种方式:

    1. 传入数组元素个数
    2. 传入两个指针,一个指向起始地址,一个指向结束地址(结束地址指向的是数组最后一个元素之后,c语言中指向数组之后的第一个元素的指针也是合法的,仅仅是指针合法,所指的值不合法!

    *++的优先级:优先级相同,但是结合时从右往左进行。

    指针操作

    1. 赋值
    2. 求值或取值。用*可取出指针指向地址中存储的数值
    3. 去指针地址
    4. 将一个整数加给指针。该整数会先和指针所指类型的字节数相乘,然后所得的结果加到初始地址上
    5. 增加指针的值。ptr++
    6. 从指针中减去一个整数
    7. 减小指针的值
    8. 求差值。通常对指向同一个数组的内的两个元素的指针求差值,以求出元素之间的距离
    9. 比较。前提:两个指针具有相同的类型

    常见错误:对未初始化的指针取值,其危害在于未初始化的指针中的初值未知,因此不知道会覆盖哪里的数据。

    int *ptr;
    *ptr=5;
    

    切记:当创建了一个指针时,系统只是分配了用来存储指针本身的内存空间,并不分配用来存吃数据的内存空间!

    指针最基本的功能在于同函数交换信息

    保护数组内容

    如果希望函数不改变数组的内容,可以在函数原型和定义的形式参量声明中使用关键字const,作用是告诉编译器,函数应当将该数组作为包含常量数据的数组对待。好处是,这样做并不要求原数组是固定不变的

    关于const

    1. 用const可以定义指向常量的指针,这样就不可以用该指针来修改它所指的数值,此时const放在 * 前

    2. 将常量或非常量数据的地址赋给指向常量的指针是合法的,但只有非常量数据的指针才可以赋给普通指针。原因:如果指向常量的指针可以赋给普通指针,那么就可以通过该普通指针修改被认为是常量的数据了

      用处:如果函数的原型中形式参数声明使用const,那么该函数既可以接收普通指针,又可以接收指向常量的指针。但是如果函数原型中不使用const,那么就不可以接收指向常量的指针!

    3. 用const可以保证指针不会指向别处,此时const放在 * 之后

    4. 同时用两个const表示既不可以修改所指的数值,又不可以更改所指地址

    指针与多维数组

    int zippo[4][2]
    

    其中zippo是所指向对象的大小是两个int,zippo[0]所指向的对象是一个int

    注意:*(zippo+2)表示zippo[2][0]的地址,*(*(zippo+2)+1)表示zippo[2][1]的值

    如何定义指向二维数组的指针?

    int (*pz)[2];	//一定要加括号,表示指向一个包含两个int值的数组
    pz=zippo;
    
    int *pax[2];	//表示定义两个指针组成的数组
    

    区别于指针可以将非const的指针赋给const的指针,不可以将非const的指针的指针赋给const的指针的指针,这种赋值只允许一层间接关系

    const int **pp2;
    int *p1;
    const int n=13;
    pp2=&p1;	//非法,但假设合法
    *pp2=&n;//合法,二者都是const,同时也会让p1指向n
    *p1=10;//合法,但此时会修改n的值
    

    函数与多维数组

    函数原型等价形式:

    void somefunction(int (*pr)[4],int rows);
    void somefunction(int pt[][4],int);
    void somefunction(int [][4],int rows);
    void somefunction(int [3][4],int rows);	//合法,但是3会被忽略
    

    每个函数都把pt看作指向包含4个int值的数组的指针,列数在函数体内定义,但行数需要作为参数传入

    变长数组

    C99标准引入变长数组,允许使用变量定义数组各维

    注意:

    1. 变长数组的“变”表示维数可以用变量来指定,而不是创建数组之后可以修改其大小
    2. 变长数组必须是自动存储类的,意味着它们必须在函数内部或作为函数参量声明,而且声明时不可以进行初始化。即不能定义在函数的外部,而且不可以初始化!
    int sum2d(int rows,int cols,int ar[rows][cols]);	//合法
    int sum2d(int,int,int ar[*][*]);	//合法,可以省略维数参量的名称,用星号代替
    int sum2d(int ar[rows][cols],int rows,int cols);	//非法,顺序不对
    

    复合文字

    C99新增复合文字,文字是非符号常量,复合文字没有名称,因此必须在创建它们的同时通过某种方法使用它们

    如何定义:

    (int [2]){10,20}
    (int [])={10,20,30}	//可以省略数组大小
    

    使用方法:

    1. 文字常量同时代表首元素的地址,可以用它给一个指向int的指针赋值
    2. 可以作为实参传递给带有类型与之匹配的形式参数的函数。该方法较为常用,好处在于可以给函数传递信息而不必先创建数组
  • 相关阅读:
    div布局的几点体会
    DIV高度的问题
    想修改CSS
    如何在EXCEL SHEET中 动态添加控件
    div的背景设置的问题
    CSS的资源
    远程调试
    Javascript跨域访问解决方案 Leone
    再谈PHP开发者常犯的10个MySQL错误 Leone
    开发人员需要熟知的常用Linux命令之八:Version、Kernel查看 Leone
  • 原文地址:https://www.cnblogs.com/xkf97/p/12283437.html
Copyright © 2011-2022 走看看