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

    //使用递归来计算阶乘
    #include<stdio.h>
    long rfact(int n);
    int main()
    {
    int num;

    printf("This program calculate factorials. ");
    printf("Enter a value in the range 0-12(q to quit): ");
    while(scanf("%d",&num)==1)
    {
    if(num <0 )
    printf("No negative number,please. ");
    else if(num > 12)
    printf("Keep input under 12. ");
    else
    printf("recursion: %d factorial = %ld ",num,rfact(num));

    printf("Enter a value in the range 0-12(q to quit): ");
    }
    printf("Bye. ");
    return 0;

    }


    long rfact(int n)
    {
    long ans;

    if(n > 0)
    ans = n * rfact(n-1);
    else
    ans = 1;

    return ans;
    }

    //以二进制形式输出整数
    #include<stdio.h>
    void to_binary(unsigned long n);

    int main()
    {
    unsigned long number;
    printf("Enter an integer (q to quit): ");
    while(scanf("%lu",&number)==1)
    {
    printf("Binary equivalent: ");
    to_binary(number);
    putchar(' ');
    printf("Enter an integer (q to quit): ");

    }
    printf("Done. ");

    return 0;
    }

    void to_binary(unsigned long n)
    {
    int r;
    r = n % 2;
    if(n >= 2)
    to_binary(n / 2);
    putchar('0' + r);

    }

    //scanf("%*s");可以跳至下一个空白字符

    指针:
    /*
    指针要说明所指变量的类型,因为有些指针操作需要知道变量类型所占用的存储空间,同时程序也需要知道地址中存储的是何种类型。
    大多数系统,指针是由无符号整数表示,但不能把它看作整数类型,是一种新的数据类型,%p作为输出格式。
    不能进行相加

    编写程序时: 一个变量一般有两种属性:变量名,数值;
    编译和加载后:同一个变量在计算机中有两个属性是地址和数值。
    */

    函数返回值类型:
    函数返回值的类型和声明的类型不相同时,实际返回值会将指定的值转化为声明类型。

    在初始化前,和普通变量类似,数组元素的数值是不定的。


    小技巧:如果days是数组,那么可以用:sizeof days / sizeof day[0]来计算出数组中元素的数目。


    例题:

    int a[] = {21,43};这种格式在元素个数有误时,我们可能意识不到

    int a[] = {31,43,[1] = 45};后面的指定初始化会覆盖前面的数值,其他没有指定的都为0


    不允许的赋值方式:


    int a[]={34,34}; 可以
    int b[2];

    b = a; 不可以
    b[2]={2,5};不可以

    数组说明:
    使用超出数组边界的索引会改变其他变量的数值,程序也许能够运行,但是运行结果会很奇怪

    小技巧:在数组声明中使用符号常量,然后程序中需要使用数组大小的地方都直接引用符号常量


    数组是顺序存储的

    多维数组的初始化 a[][]={{},{},} 与a[][] = {}在数值个数不够时,效果是不同的。


    数组名同时也是数组首元素地址

    指针说明:
    对一个指针加1的结果也是对该指针增加一个存储单元,不是加一个字节


    对于包含多个字节的数据类型,对象的地址通常指的是其首字节的地址
    指针数值就是它所指向的对象的地址,地址的内部表示方式由硬件来决定

    小技巧:
    被调用的子函数可以得到数组的地址但它不知道数组中元素的数量,两种选择:1.函数代码中写上固定的数组大小 2.传递一个参数表示数量

    声明数组参量:
    int sum(int *ar,int n);
    int sum(int *,int);
    int sum(int ar[],int n);
    int sum(int [],int n);

    定义时名称是不可以省略的:
    int sum(int *ar,int n)
    int sum(int ar[],int n)

    数组和指针的补充:
    C保证在为数组分配存储空间的时候,指向数组之后的第一个位置的指针也是合法的,但对里面的内容不作任何保证

    *str++ 由于* ++具有相同的优先级,但结合是从右到左,所以++先作用


    ar是一个指针变量时,才可以用ar++,数组名不可以

    指针的运算:

    求有效差值前提是两个指针指向同一个数组(或其中一个指向数组后面的第一个地址)

    减去一个整数是会,移动的存储单元,不是字节


    比较两个指针的值的前提是:两个指针具有相同的类型


    注意:
    不能对未初始化的指针取值
    如:int *pt; *pt = 5; 此时不知道5会存储在什么位置,该位置可能对系统产生危害。

    系统分配用来存储指针本身的内存地址空间,而不分配用来存储数据的内存空间

    const的一些用法:

    例子:rates是数组名,const double * pd = rates; *pd =29.89,和pd[2]是不允许的,rates[0] = 99.99是允许的。

    将常量和非常量的地址赋给指向常量的指针式合法的

    当const放*前面,指向常量,值不可变,位置可变
    当const放*后面,指向变量,值可变,位置不可变。


    *zippon = zippon[0] = &zippon[0][0]

    int (* pz)[2];指向一个包含2个int值的数组 ,[]的优先级是高于*号的

    int *pz[2];两个指针组成的数组


    指针的赋值不支持类型转化,类型一定要一样

    把非const指针赋给const指针是允许的,这样的赋值有一个前提:只进行一层间接运算
    如例题:
    const int **p2;
    int *p1;
    const int n = 13;
    pp2 =&p1; //假设允许
    *pp2 =&n;
    *p1 = 10;
    //这题中,n的地址给*pp2,于是间接给了p1,然后p1就可以改变n了,所以不成立。

    二维数组的参数传递:
    假设junk是指向由4个int值构成的数组的指针;
    声明可以如下:
    1.void somefunction(int (* pt)[4])
    2.void somefunction(int pt[][4]);
    如果在声明中第一个[]中填入数字也是可以的,但是编译器将忽略掉,合理做法可以加一个参数。


    多维数组的声明:
    void sum(int (*ar)[34][34][34],int rows);
    void sum(int ar[][34][43][43],int rows)


    变长数组的(VLA)
    1.变长数组的“变”并不表示在创建数组后,可以改变其大小。是指其维数大小可以用变量来指定

    例子如下:

    声明:int sum(int rows,int cols,int ar[rows][cols]);//ar是一个指向由cols个int组成的数组

    C99中可以用:int sum(int,int,int ar[*][*]);

    函数定义如下:
    int sum(int rows,int cols,int ar[rows][cols])
    {
    int r;
    int c;
    int tot = 0;

    for(r = 0;r < rows;r++)
    for(c = 0;c < cols;c++)
    tot += ar[r][c];
    return tot;

    }

    C不支持把整个数组作为函数参数进行传递的


    复合文字(一个代码,要支持C99编辑器):
    #include<stdio.h>
    #define COLS 4
    int sum2d(int ar[][COLS],int rows);
    int sum(int ar[],int n);
    int main()
    {
    int total1,total2,total3;
    int * pt1;
    int (*pt2)[COLS];

    pt1 = (int [2]){10,20};
    pt2 = (int [2][COLS]){{1,2,3,-9},{4,5,6,-8}};

    total1 = sum(pt1,2);
    total2 = sum2d(pt2,2);
    total3 = sum((int []){4,4,4,5,5,5},6);
    printf("total1 = %d ",total1);
    printf("total2 = %d ",total2);
    printf("total3 = %d ",total3);

    return 0;
    }

    int sum(int ar[],int n)
    {
    int i;
    int total = 0;

    for(i = 0;i < n;i++)
    total += ar[i];

    return total;

    }

    int sum2d(int ar[][COLS],int rows)
    {
    int r;
    int c;
    int tot = 0;

    for(r = 0;r < rows;r++)
    for(c = 0;c < COLS;c++)
    tot += ar[r][c];

    return tot;
    }

  • 相关阅读:
    Exception in thread "main" com.sun.xml.internal.ws.streaming.XMLStreamReaderException: unexpected XML tag.
    Navicat的快捷键
    win7虚拟机起不来,报错transport vmdb error -44 message the vmware authorization
    fedora19配置 SSH 免密码登陆
    Linux下Django的安装
    linux下为用户添加sudo命令功能
    ubuntu修改系统环境变量文件导致起不来
    fedorea19安装redis
    java下载csv文件,中文标题
    POJ A Simple Problem with Integers | 线段树基础练习
  • 原文地址:https://www.cnblogs.com/zxj-262410/p/6691243.html
Copyright © 2011-2022 走看看