C语言学习|指针和数组(10.21)

基本概念

一维数组

1.a[i]中,数组名a代表一维数组首地址
2.a[i]<->*(a+i)

二维数组

1.a[i][j]中,a[i]可以看作一维数组的数组名,即第i行一维数组首地址。例:a[i]等价于&a[i][0]。
2.a[i][j]<-> * (a[i]+j)<->* (* (a+i)+j)<-> * (* (a+i)+j)<->( *(a+i))[j]

行指针

int (*p)[4]; //是指向二维数组的行指针,它所指向的二维数组每行有4个元素
注意:必须显式指定指针变量所指向的一维数组的长度。
初始化方式:p = a; 或者 p = &a[0];
C语言学习|指针和数组(10.21)

#include <stdio.h>
#define N 4

void InputArray (int (*p)[N],int m,int n);
void OutputArray (int (*p)[N],int m,int n);

int main()
{
    int a[3][4];
    printf("Input 3*4 numbers:\n");
    InputArray (a,3,4);    //可替换为*a,a[0],&a[0][0]
    OutputArray (a,3,4);

    return 0;
}
void InputArray (int (*p)[N],int m,int n)
{
    int i,j;
    for (i = 0; i < m ; i++)
        for (j = 0; j < n; j++)
            scanf("%d",*(p+i)+j);   //可替换为&p[i][j]
}
void OutputArray (int (*p)[N],int m,int n)
{
    int i,j;
    for (i = 0; i < m ; i++)
        for (j = 0; j < n; j++)
            printf("%4d",*(*(p+i)+j));    //可替换为p[i][j]
    printf("\n");
}

列指针

int *p;
初始化方式:p = a[0]; 或者 p = *a; 或者 p = &a[0][0]; //此时可将a看作是一个由m * n个元素组成的一维数组。
a[i][j]等价于 * (p+i * n+j) 或 p[i * n+j] 。
&a[i][j]等价于 p+i * n+j 或 &p[i * n+j]。
每次增1减1操作时,移动的字节数为;基类型所占字节数
常用作函数参数,实现当二位数组行列数需要动态指令的场合。
注意:此时不能用p[i][j]表示数组元素,因为此时等价于一维数组。
C语言学习|指针和数组(10.21)

#include <stdio.h>

void InputArray (int *p,int m,int n);
void OutputArray (int *p,int m,int n);

int main()
{
    int a[3][4];
    printf("Input 3*4 numbers:\n");
    InputArray (*a,3,4);    //可替换为a[0],a,&a[0][0],均表示第0行第0列的地址
    OutputArray (*a,3,4);

    return 0;
}
void InputArray (int *p,int m,int n)
{
    int i,j;
    for (i = 0; i < m ; i++)
        for (j = 0; j < n; j++)
            scanf("%d",p+i*n+j);
}
void OutputArray (int *p,int m,int n)
{
    int i,j;
    for (i = 0; i < m ; i++)
        for (j = 0; j < n; j++)
            printf("%4d",*(p+i*n+j));
    printf("\n");
}

指针数组

是一个数组,指针作为数组的元素,形成了指针数组,用于表示多个字符串。

用途一:对多个字符串进行处理操作,加快字符串的排序速度。

字符串排序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 150
#define MAX_LEN 10

void SortString (char *p[],int n);

int main()
{
    int i,n;
    char name[N][MAX_LEN];
    char *p[N];     //定义指针数组
    printf("How many countries?");
    scanf("%d",&n);
    getchar();
    printf("Input their names:\n");
    for (i = 0; i < n; i++)
    {
        p[i] = name[i];    //初始化指针数组p[i],使其分别指向name的每一行
        gets(p[i]);    //对name进行赋值
    }
    SortString (p,n);
    printf("Sorted result:\n");
    for (i = 0; i < n; i++)
        puts(p[i]);

    return 0;
}
void SortString (char *p[],int n)
{
    int i,j;
    char *temp = NULL;
    for (i = 0; i < n-1; i++)
        for (j = i+1; j < n; j++)
        	/*改变指针数组*p[N]的指向,并没有改变name[N][MAX_LEN]*/
            if (strcmp(p[i],p[j]) > 0)
            {
                temp = p[i];
                p[i] = p[j];
                p[j] = temp;
            }
}

C语言学习|指针和数组(10.21)
物理排序:移动字符串在实际物理存储空间中存放的位置而实现的排序。
索引排序:移动字符串的索引地址而实现的排序,此方法执行效率更高。

用途二:用于表示命令行参数

#include <stdio.h>
/*argc存放命令行参数个数,argv为字符指针数组,接收命令行参数*/
int main(int argc,char *argv[])
{
    int i;
    printf("The number of command line arguments is:%d\n",argc);
    printf("The program name is:%s\n",argv[0]);
    if (argc > 1)
    {
        printf("The other arguments are following:\n");
        for (i = 1; i < argc; i++)
        {
            printf("%s\n",argv[i]);
        }
    }
    return 0;
}

假设此文件为Practice.c,编译链接后生成可执行文件Practice.exe
此可执行文件文件的位置为E:\CBcode\Practice\bin\Debug\Practice.exe
在运行中,输入cmd,回车,打开DOS命令提示符,输入如下命令行:
Practice.exe programming is fun
将显示如下程序运行结果(.exe也可以不输入)
C语言学习|指针和数组(10.21)
C语言学习|指针和数组(10.21)