首页 > 代码库 > 指针、函数和数组

指针、函数和数组

    C语言的学习,比较难的是指针的用法,指针搞不明白,那说明没有学好C语言。

    下面将举例说明指针的一些用法,包括指针数组、数组指针、指针函数、函数指针和函数指针数组。

    1. 指针

    通常说所的指针是指针变量的简称,指针变量存放的是内存单元的地址,在32位处理器中地址是32位的,所以所有类型的指针都占32位即4字节。

    一级指针存放非指针变量的地址,二级指针存放一级指针变量的地址。

    下面来看一段程序:

#include <stdio.h>
int main(void)
{
        int a[5] = {1, 2 ,3, 4, 5}; 
        int  i;  
        for(i = 0; i < 5; i++)
                printf("a[%d] = %d %d %d %d\n", i, a[i], *(a+i), *(i+a), i[a]);
        return 0;
}

    数组名a代表&a[0],是一个地址常量,对数组的操作本质是对指针的操作。i[a]这种写法也是可以的,i[a]等价于*(i+a),即*(a+i)。


    2.指针数组

    我们来看一个程序

#include <stdio.h>

int main(void)
{
        int a[5] = {1, 2, 3, 4, 5}; 
        int *p[5], i;
        for(i = 0; i < 5; i++)
                p[i] = &a[i];
        for(i = 0; i < 5; i++)
                printf("*p[%d]=%d\n", i, *p[i]);
        return 0;
}

    数组a和数组p的区别在于数组a的每个元素都是整型变量,而数组p的每个元素都是整型指针变量。

    给元素赋值: 

    for(i = 0; i < 5; i++)
                p[i] = &a[i];

    数组p的每个元素存放数组a的元素的地址。

    编译运行程序的结果是:

    *p[0]=1
    *p[1]=2
    *p[2]=3
    *p[3]=4
    *p[4]=5

    

    3. 数组指针

    先看一个程序    

 #include <stdio.h>

int main(void)
{
        int a[5] = {1, 2, 3, 4, 5}; 
        int (*p)[5], i;
        p = &a; 
        for(i = 0; i < 5; i++)
                printf("a[%d]=%d \n", i, *(*p+i));
        return 0;
}

    这里p是数组指针,p指向的对象是具有10个元素的一维数组。注意p指向的对象一维数组,因此存放的必须是一维数组整体的地址,程序中的“p = &a”不能改为“p = a”,数组名代表首元素的地址,即a等价于&a[0]。

    程序运行结果:   

    a[0]=1 
    a[1]=2 
    a[2]=3 
    a[3]=4 
    a[4]=5

    现在我们来看看另外一个程序。   

#include <stdio.h>
int main(void)
{
        int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
        int (*p)[3], i, j;
        p = a;
        for(i = 0; i < 2; i++)
                for(j = 0; j < 3; j++)
                        printf("a[i][j]=%d %d %d %d %d %d\n", a[i][j],
         *(a[i]+j), *(*(a+i)+j),  p[i][j], *(p[i] +j), *(*(p+i)+j));
        return 0;
}

    指针p指向的是一维数组,因此要把一维数组的地址赋给p,赋值语句“p=a”把二维数组a的首元素地址&a[0]赋值给p,a[0]是一维数组,这是正确的。可以把p等价于a使用,最后用6种方式输出二维数组a的所有元素,结果如下:

    a[i][j]=1 1 1 1 1 1
    a[i][j]=2 2 2 2 2 2
    a[i][j]=3 3 3 3 3 3
    a[i][j]=4 4 4 4 4 4
    a[i][j]=5 5 5 5 5 5
    a[i][j]=6 6 6 6 6 6

   4. 指针函数

    指针函数是指返回值是地址的函数,例如:  

  int * fun(int a. int b);

    函数fun的返回值是整型指针。

    5. 函数指针

    函数指针是指向函数的指针,下面看一个程序。

#include <stdio.h>
int fun(int x, int y)
{
        return x + y;
}
int main(void)
{
        int a = 5, b = 4, c;
        int (*p)(int x, int y); //函数指针
        p = fun;
        c = p(a, b); 
        printf("%d + %d = %d\n", a, b, c); 
        return 0;
}

     定义语句“int (*p)(int x, int y)”定义了p是指向具有两个整型参数,并且返回值是整型的函数的指针。然后把具有两个整型参数,并且返回值是整型的函数fun赋给p,这样p就指向函数fun的入口地址,使用时传入相应的参数。

    这个程序的运行结果如下:   

    5 + 4 = 9

    6. 函数指针数组

    函数指针数组是多个相同类型函数指针的集合,下面看一个程序。

#include <stdio.h>
int fun1(int x, int y)
{
        return x + y;
}
int fun2(int x, int y)
{
        return x - y;
}
int main(void)
{
        int a = 5, b = 4, c, d;
        int (*p[2])(int x, int y); 
        p[0] = fun1;
        p[1] = fun2;
        c = p[0](a, b); 
        d = p[1](a, b); 
        printf("%d + %d = %d\n", a, b, c); 
        printf("%d - %d = %d\n", a, b, d); 
        return 0;
}

    定义语句“ int (*p[2])(int x, int y);”定义了一个函数指针数组,数据p有两个元素,p[0]是一个指向具有两个整型参数,并且返回值是整型的函数的指针。然后把具有两个整型参数,并且返回值是整型的函数fun1赋给p[0],这样p[0]就指向函数fun1的入口地址,使用时传入相应的参数。

本文出自 “兵疯千里” 博客,请务必保留此出处http://slientradio.blog.51cto.com/7241495/1530759