C语言 指针(3)

一、函数和指针

1. 函数指针(指向函数的指针)。 例如: int (*pf)( ); 

    例:

#include <stdio.h>

void print()
{
    printf("Hello\n");
}

int add(int x, int y)
{
    return (x+y);
}

int main()
{
    int m;

    void (*p)();
    p = print;
    p();

    int (*q)(int, int);
    q = add;
    m = q(1, 2);

    printf("%d", m);

    return 0;
}

其中 p = print; 和 q = add;  是将地址赋值给指针,函数名就是一个地址;

2. 指针函数(指针里保存函数)。例如:int *p( );

    例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *Init()
{
    char *tmp = (char *)malloc(sizeof(char)*10);
    
    return tmp;
}

int main()
{
    char *str;
    str = Init();

    strcpy(str, "hello");

    printf("%s", str);
    return 0;
}

其中 str = Init();是将函数赋给指针函数 ,等号两边等价。

3.练习(1)int     * ( * ( * fp ) ( int ) ) [10] ;

                  * fp   // fp是一个指针

                  * ( * fp ) ( int )   // 指针指向一个有int型参数的函数,函数的返回值是一个指针

                  int     * ( * ( * fp ) ( int ) ) [10]   // 指针指向一个有10个元素的数组,数组中的每个元素都是int型的指针

          (2)int   * ( * ( * array [5] )( ) ) ( ) ;

                   * array [5]   // array是一个有五个元素的数组,每个元素都是一个指针

                   * ( * array [5] )( )  // 每个指针指向一个函数,函数的返回类型是一个指针

                   int   * ( * ( * array [5] )( ) ) ( ) ;  // 每个指针指向一个函数,函数的返回类型是一个int型指针

二、数组和指针

1. 指向二维数组的指针的表示方式 

表示形式

含义

地址值

&a

指向二维数组的指针

1000

a

二维数组名,指向一维数组a[0],即第0行首地址

1000

a[0] , *(a+0) , *a

0行第0列元素地址

1000

a+1 , &a[1]

1行首地址

1006

a[1] , *(a+1)

1行第0列元素地址

1006

a[1]+2 , *(a+1)+2 , &a[1][2]

1行第2列元素地址

1010

*(a[1]+2) , *(*(a+1)+2) , a[1][2]

1行第2列元素的值

元素值为11

 &a[i]a+i指向行,而a[i]或*(a+i)指向列 

例:

#include <stdio.h>

int main()
{
    int a[3][4] = {{1, 2, 3, 4}, {3, 4, 5, 6}, {5, 6, 7, 8}};
    int i;
    int (*p)[4] = a, *q = a[0];

    for(i = 0; i < 3; i++)
    {
        if(i == 0)
        {
            (*p)[i + i/2] = *q + 1;
        }
        else
        {
            p++, ++q;
        }
    }

    for(i = 0; i < 3; i++)
    {
        printf("%d,", a[i][i]);
    }

    printf("\n");
    printf("%d,%d\n", *((int *)p), *q);
    return 0;
}

其中int ( * p ) [ 4 ] = a ;p是指针,指向一个有4个元素的数组。因为a + 1是加一行(4个元素,16字节),所以p + 1也要加16个字节,数组中元素个数取4。

2. 二维数组指针

#include <stdio.h>

int main()
{
    int i, j;
    int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    int (*p)[4] = a;

    for(i = 0; i < 3; i++)
    {
        for(j = 0; j < 4; j++)
        {
            printf("%d ", a[i][j]);
            printf("%d ", *(*(p + i) + j));
            printf("%d ", p[i][j]);
            printf("%d ", (*(p + i))[j]);
        }
        printf("\n");
    }
    return 0;
}

其中 a[ i ] [ j ] === * ( * ( p + i) + j ) === ( * ( p + i ) ) [ j ] === p[ i ] [ j ]

三、指向指针的指针

例1:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void MemoryInit(char **str)
{
    *str = (char *)malloc(sizeof(char) * 64);
}
int main()
{
    char *ptr = NULL;

    MemoryInit(&ptr);

    strcpy(ptr, "Helloworld");

    printf("%s\n", ptr);
    return 0;
}

函数传地址时 &ptr = **str; 其中ptr是指针也是地址,&ptr是地址的地址,**str也是地址的地址

                                                 &ptr 是函数调用要传递地址(参见两数交换的程序) 

例2:

#include <stdio.h>

int main()
{
    char *name[] = {"Follow", "BASIC", "Great", "For", "Computer"};
    char **p;
    int i;

    for(i = 0; i < 5; i++)
    {
        p = name + i;
        printf("%s\n", *p);
    }
    return 0;
}

定义时 name[ ]是数组名也是一个地址,*name[ ]是地址的地址,+1加到下一个元素 

            **p也是地址的地址,所以p = name + i成立

输出时 *p是取值, 就少了一层地址,还剩一层地址,而数组本身就是一个地址,就相当于取数组的值

四、命令行参数(main函数的函数) 

1. main (int argc,char *argv[])

             argc(第一个形参)必须是整型变量,表示参数的个数

             argv( 第二个形参)必须是指向字符串的指针数组,表示具体的参数

2. 使用命令行参数编写字符串排序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void sort(char *a[], int length)
{
        int i, j;
        char *tmp;

        for (i = 1; i <= length - 1; i++)
        {
                for (j = 1; j <= length - i - 1; j++)
                {
                        //if (a[j + 1] < a[j])
                        if (strcmp(a[j + 1], a[j]) > 0)
                        {
                                tmp = a[j + 1];
                                a[j + 1] = a[j];
                                a[j] = tmp;
                        }
                }
        }
}

void print(char *a[], int length)
{
        int i;
        for (i = 1; i < length; i++)
        {
                printf("%s ", a[i]);
        }
        printf("\n");
}

int main(int argc, char *argv[])
{
        int i, j, tmp;
    int length = argc;

        sort(argv, length);

        print(argv, length);

        return 0;
}

 运行时  ./sort.c aaa bbb ccc ddd (输入需要比较的字符串)

猜你喜欢

转载自blog.csdn.net/qq_41998576/article/details/81253195