C语言学习(8)

一、指针跟二维数组之间的关系

1. 熟练掌握二维数组跟指针有关的几种写法

例子1:int类型的二维数组

  int a[5][6]={78,96,741,5,12,74};

  哪些是指针,如果是指针,请问是什么类型的指针?哪些不是

  a a+1 是指针,表示该数组首元素(a[0])的地址&a[0],加了24个字节

  a的类型是: int (*)[6]; 数组指针

  &a &a+1 是指针,数组名前面加上&表示指向整个数组的一个指针

  整个数组 int [5][6]这种类型

  &a的类型是:int (*)[5][6]

  a[0] a[0]+1 是指针,把二维数组当成特殊的一维数组看待,a[0]就是第一个成员的名字,第一个成员就是int[6],数组名出现  在表达式表示该数组(int[6])首元素的地址

  a[0]的类型是: 等价于&a[0][0] int *

  &a[0] &a[0]+1 是指针

  &a[0]的类型是: int (*)[6]; 数组指针

  a[0][1] a[0][1]+1 不是指针

  &a[0][1] &a[0][1]+1 是指针, int *

#include <stdio.h>

int main()
{
    int a[5][6] = {78, 96, 741, 5, 12, 74};
    /* printf("a is:%p\n",a);
    printf("a+1 is:%p\n",a+1);
    printf("&a[0] is:%p\n",&a[0]);
    printf("&a[0]+1 is:%p\n",&a[0]+1);
    
    printf("&a is:%p\n",&a);
    printf("&a+1 is:%p\n",&a+1); */

    printf("a[0] is:%p\n", a[0]);
    printf("a[0]+1 is:%p\n", a[0] + 1);
}

 

 

#include <stdio.h>

int main()
{
    int i,j;
    char a[5][10]={"hello","world","gec","china","hehe"};
    
    //第一种:通过char *类型的指针访问二维数组
/*     char *p=&a[0][0];//或者  char *p=a[0];
    for(i=0; i<50; i++)
    {
        printf("*(p+%d) is:%c\n",i,*(p+i));
    } */
    
    //第二种:通过数组指针访问二维数组
    char (*q)[10]=&a[0];  //q+1每次跳过一个字符串
    /* for(i=0; i<5; i++)
        //printf("%s\n",(char *)(q+i));
        //printf("%s\n",*(q+i)); //18和19行结果一样 */
        
    for(i=0; i<5; i++)    
    {
        for(j=0; j<10; j++)
            //printf("%c\n",*(*(q+i)+j)); //做个了解,强烈不推荐你这么写
            printf("q[%d][%d]%c\n",i,j,q[i][j]);
    }
}

/*    
    推导过程:
        *(*(q+i)+j) --》*(*(&a[0]+i)+j)--》*(*(&a[i])+j)--》*(a[i]+j)
        --》*(&a[i][0]+j)
*/

 

练习

  char b[5][10]={"hello", ''world", "gechehe","china"};

  //思路: b理解成5个 char [10]

  //用字符c替换world中字符r

  *(b[1]+2)='c'; // b[1]是指针--》什么类型char * 等价于 &b[1][0]

  //p是数组指针

  char (*p)[10]=&b[2]; // b[2]数组名,&b[2]是个数组指针

  // p指向china

  p++;

  printf("p is:%s\n",(char *)p); // %s要求打印字符串,必须是char *类型

  printf("b[1] is:%s\n",b[1]);

#include <stdio.h>

int main()
{
    char b[5][10] = {"hello", "world", "gechehe", "china"};
    //思路: b理解成5个  char [10]
    //用字符c替换world中字符r
    *(b[1] + 2) = 'c'; //  b[1]是指针--》什么类型char * 等价于  &b[1][0]
    //p是数组指针
    char(*p)[10] = &b[2]; // b[2]数组名,&b[2]是个数组指针
    // p指向china
    p++;
    //printf("p is:%s\n",(char *)p);  //  %s要求打印字符串,必须是char *类型
    //跟13行结果一样  *p等价于--》*(&b[3])--》等价于b[3]
    printf("p is:%s\n", *p);
    printf("b[1]  is:%s\n", b[1]);
}

 

 

作业:

  1. 定义一个char类型的二维数组char buf[6][20],要求使用指针操作去除掉字符串中所有的非英文字母(只要不是英文字母的全部剔除)

  思路有两种:第一种采用char *指针去访问这个二维数组

  第二种采用数组指针 char (*p)[20] p[i][j]

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

/*
* 定义一个char类型的二维数组char  buf[6][20],要求使用指针操作去除掉字符串中所有的非英文字母(只要不是英文字母的全部剔除)
*/
int main()
{
    int i, j, k, len_2 = 0;
    char input[6][20] = {0};
    char(*pn)[20] = &input[0]; //取地址一组字符串的首地址
    printf("Please enter 6 string\n");
    for (i = 0; i < 6; i++)
        gets(input[i]);

    for (i = 0; i < 6; i++)
    {
        len_2 = strlen(input[i]);   //计算出这个字符长度
        for (j = 0; j < len_2; j++) //逐个比较
        {
            if (((pn[i][j] < 'a') && (pn[i][j] > 'Z')) || (pn[i][j] < 'A') || (pn[i][j] > 'z')) //当发现不是这个字母的时候
            {
                for (k = j; k <= len_2 - 1; k++) //将字符剔除
                {
                    pn[i][k] = pn[i][k + 1];
                }
                len_2--; //字符长度对应减少
                j--;     //重新比较
            }
        }
    }

    printf("==========divide===========\n"); //分界线
    for (i = 0; i < 6; i++)
        printf("%s\n", pn[i]);

    return 0;
}
View Code

 

  2. 定义一个char类型的二维数组char name[5][20],你从键盘输入5个字符串表示5个人的名字,编程实现用指针判断5个名字中是否包含了英文大小写以及数字,并且每个人的名字长度不能超过8个字符(人的名字要求:小写字母,大写字母,数字字符三种都要包含),如果名字符合要求就打印出来,不符合就打印缺少了那种字符(缺少了小写?大写?英文?printf打印提示即可)

  思路:用指针去遍历字符串,标记字符的类型(大写,小写,数字字符)

  定义三个int类型的变量去标记

  int flag1=0; // 1 大写 0 非大写

  int flag2=0; 1 小写 0 非小写

  int flag3=0; 1 数字字符 0 非数字字符

  hfdhskfhE86 //只要有一个字符不符合三种类型要求,直接退出循环

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

int main()
{
    int i, j, len_2 = 0;
    int Low_flag = 0, Hig_flag = 0, Num_flag = 0; //小写标志位/大写标志位/数字标志位
    //char *pn[5];
    char input[5][9] = {0};
    char(*pn)[9] = &input[0];
Begin:
    printf("Please enter 5 string\n");
    for (i = 0; i < 5; i++)
    {
        gets(input[i]);
        if (strlen(input[i]) > 8) //判断是否大于8个字符长度
        {
            printf("Error:you enter more than 8 characters!\n");
            goto Begin;
        }
    }

    printf("==========divide=============\n"); //分界线

    for (i = 0; i < 5; i++)
    {
        // pn[i] = input[i];           //取地址一组字符串的首地址
        len_2 = strlen(input[i]);   //计算字符长度
        for (j = 0; j < len_2; j++) //逐个判断:
        {
            if ((pn[i][j] >= 'A') && (pn[i][j] <= 'Z'))
            {
                Hig_flag = 1; //大写标志位置1
                continue;
            }
            if ((pn[i][j] >= 'a') && (pn[i][j] <= 'z'))
            {
                Low_flag = 1; //小写标志位置1
                continue;
            }
            if ((pn[i][j] >= '0') && (pn[i][j] <= '9'))
            {
                Num_flag = 1; //数字标志位置1
                continue;
            }
        }
        if (Low_flag == 1 && Hig_flag == 1 && Num_flag == 1) //只有3个标志位置1的说明无误
        {
            printf("%s\n", pn[i]); //打印本身字符串
        }

        if (Low_flag == 0)
        {
            printf("No.%d String lack Lowercase\n", i + 1); //缺少小写字符
        }
        if (Hig_flag == 0)
        {
            printf("No.%d String lack Uppercase\n", i + 1); //缺少大写字符
        }
        if (Num_flag == 0)
        {
            printf("No.%d String lack Number\n", i + 1); //缺少数字字符
        }

        Low_flag = 0; //用完清0,方便下次使用
        Hig_flag = 0;
        Num_flag = 0;
    }

    return 0;
}
View Code

 

posted @ 2020-03-09 17:34  Geek_Jian  阅读(261)  评论(0编辑  收藏  举报