指针练习题15道【C语言】

发布于:2024-12-20 ⋅ 阅读:(11) ⋅ 点赞:(0)

1.利用指针变量将一个数组中的数据反向输出。

声明:

void work1(int *, int); // 声明反向遍历
void work1_1(int *, int); // 声明正向遍历

实现:

// 利用指针变量将一个数组中的数据反向输出,反向遍历
void work1( int *p,int len)
{
    p += (len - 1);

    for(int i = 0; i < len; i++)
    {
        if(i%4 == 0 && i != 0)  printf("\n");
        printf("arr[%d]=%d \t", len - i, *(p-i));
    }

    printf("\n");
}
// 利用指针变量将一个数组中的数据正向输出,正向遍历
void work1_1( int *p,int len)
{   
    for(int i = 0; i < len; i++)
    {
        if(i%4 == 0 && i != 0)  printf("\n");
        printf("arr[%d]=%d \t", i, *(p+i));
    }

    printf("\n");
}

调用:

// 定义并初始化一个一维数组
    int arr[10] = {90,98,87,76,65,54,43,32,21,10};
    int len = sizeof(arr)/sizeof(arr[0]);
    printf("正向输出:\n");
    work1_1(arr, len);
    printf("反向输出:\n");
    work1(arr,len);

运行截图
在这里插入图片描述

2.利用指针变量计算下标为奇数的数组的和;

声明

int work2(int *,int); // 声明下标奇数之和

实现

// 下标奇数之和
int work2(int *p, int len)
{
    int sum = 0;
    for(int i = 0; i < len; i++)
    {
        if(i%2 != 0 && i != 0)
            sum += *(p + i);
    }
    
    return sum;
}

调用

// 定义并初始化一个一维数组
    int arr[10] = {90,98,87,76,65,54,43,32,21,10};
    int len = sizeof(arr)/sizeof(arr[0]);
    printf("数组下标是奇数的和:%d\n", work2(arr,len));

运行截图

在这里插入图片描述

3.确认整型,字符型,浮点型指针变量的大小;

int *a;
    float *b;
    char c;
    printf("整型:%ld,浮点型:%ld,字符型:%ld\n", sizeof(a), sizeof(b), sizeof(c));

运行截图:

在这里插入图片描述

4.利用指针变量输出字符数组中的所有字符。

函数实现:

void work4(char *p, int len)
{
    for(int i = 0; i < len; i++)
    {
        if(*(p + i) == '\0') break;
        printf("%c", p[i]);
    }
    printf("\n");
}

函数调用

char crr[20] = "iaofgaeuu932578";
    int len4 = sizeof(crr)/sizeof(crr[0]);
    work4(crr,len4);

运行截图
在这里插入图片描述

5.浮点型数组的平均值

实现

// 求浮点型数组元素的平均值
double work5(double *p, int len)
{
    double sum = 0.0;

    for(int i = 0; i < len; i++)
    {
        sum += *(p + i);
    }
    
    return sum/len;
}

调用

double drr[5] = {12.3,1.2,5.5,3.3,6.6};
    int len5 = sizeof(drr)/sizeof(drr[0]);
    printf("%lf\n", work5(drr,len5));

运行截图

在这里插入图片描述

6.编写函数,要求用指针做形参,分别实现以下功能:

(1)求一个字符串长度

实现

// 求字符串长度
int work6_1(char *p,int len)
{
    int i = 0;
    while(i < len )
    {
        if(p[i] != '\0')
        {
            i++;
        }
        else
        {
            break;
        }
    }

    return i;
}

调用

char crr[40] = "iaofgaKUDu932578";
    int len4 = sizeof(crr)/sizeof(crr[0]);
    printf("字符串的长度是:%d\n", work6_1(crr,len4));

(2)在一个字符串中统计大写字母的个数

实现

// 统计大写字母个数
int work6_2(char *p,int len)
{
    int n = 0, i = 0;
    while(i < work6_1(p,len) )
    {
        if(*(p+i) >= 'A' && *(p+i) <= 'Z') n++;
        i++;
    }
    return n;
}

调用

char crr[40] = "iaofgaKUDu932578";
int len4 = sizeof(crr)/sizeof(crr[0]);
printf("字符串大写字母个数是:%d\n", work6_2(crr,len4));

(3)在一个字符串中统计数字字符的个数

实现

// 统计数字字符
int work6_3(char *p, int len)
{
    int n = 0,i = 0;
    while(i < work6_1(p,len))
    {
        if(*(p+i) >= 48 && p[i] <= '9' ) n++;
        i++;
    }
    return n;
}

调用

char crr[40] = "iaofgaKUDu932578";
int len4 = sizeof(crr)/sizeof(crr[0]);
printf("字符串数字字符个数是:%d\n", work6_3(crr,len4));

运行截图

在这里插入图片描述

7编写函数,要求用指针做形参,实现将二维数组(行列相同)的进行转置(行列数据互换): int(*p)[N]

函数实现:

// 行列转置(行列相同)
void work7(int (*p)[3], int len)
{
    int a[len][len];
    for(int i = 0; i < len; i++)
    {
        for(int j = 0; j < len; j++ )
        {
            a[j][i] = p[i][j];
        }
        printf("\n");
    }
    for(int i = 0; i < len; i++ )
    {
        for(int j = 0; j < len; j++)
        {
            p[i][j] = a[i][j];
        }
    }
   printf("数组已转置\n");
}

函数调用

int arr7[3][3] = {11,12,13,
                      21,22,23,
                      31,32,33};
    int len7 = sizeof(arr7)/sizeof(arr7[0]);
    int (*p)[len7] = arr7;
    work7(p,len7);
    for(int i = 0; i < len7*len7; i++)
    {
        if(i != 0 && i%3 == 0) printf("\n");
        printf("%d  ",*(*arr7 + i));
    }
    printf("\n");

运行截图

在这里插入图片描述

8.上三角0的个数

实现

// 指针做形参,实现统计二维数组上三角中的0的数量
int work8(int* p,int row, int col)
{
    int n = 0;
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col - i; j++)
        {
            if(!*(p + j + i*col)) n++;
        }
    }
    return n;
}

调用

int arr8[4][4] = {1,1,1,0,
                      0,0,1,1,
                      0,1,0,1,
                      0,1,1,0};
    int row = sizeof(arr8)/sizeof(arr8[0]), col = sizeof(arr8[0])/sizeof(arr8[0][0]);
    printf("遍历数组:\n");
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            printf("%3d\t", arr8[i][j]);
        }
        printf("\n");
    }
    printf("\n上半角0的个数是:%d\n", work8(&arr8[0][0], row, col));

运行截图

在这里插入图片描述

9.返回二维数组的最大值元素的地址。

实现

// 返回最大值地址
int* work9(int* p, int len)
{
    int *max = p;
    for(int i = 0; i < len; i++)
    {
        if(*max < *(p+i)) max = p+i;
    }
    return max;
}

调用

int arr9[4][4] = {1,2,3,4,
                      5,6,7,999,
                      8,9,11,23,
                      44,55,66,77};

    int row = sizeof(arr9)/sizeof(arr9[0]), col = sizeof(arr9[0])/sizeof(arr9[0][0]);
    int *max = &arr9[0][0];
    printf("遍历数组:\n");
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            if(*max < arr9[i][j]) max = &arr9[i][j];
            printf("%3d\t", arr9[i][j]);
        }
        printf("\n");
    }
    printf("\n最大值的地址是%p,%p\n", work9(&arr9[0][0], row * col), max);

运行截图
在这里插入图片描述

10.面试题

1)定义整形变量i; // int i;

2)p为指向整形变量的指针变量;// int* p = &i;

3)定义整形一维数组p,它有n 个整形元素; // int n = 10, p[n];

4)定义一维指针数组p,它有n个指向整形变量的指针元素;// int *p[n];

6)p为返回整形函数值的函数; // int p(){}

7)p为返回一个指针的函数,该指针指向整形数据;// int* p(){}

8)p为指向函数的指针变量,该函数返回一个整形值;// int (*p)(int);

9)p是一个指向整形指针变量的指针变量;// int** p;

11.找出第一次出现 12.35 的下标位置,并输出。

实现

// 查找12.35的下标
int work11(float* p, int len, float n)
{
    int i = 0;
    for(;i < len; i++)
    {
        if(*(p+i) - n == 0) return i;
    }
    return -1;
}

调用

float a11[10] = {1.1,2.2,3.3,4.4,5.5,12.35,6.6,7.7,8.8,9.9};
    float* p11 = (float*)calloc(10,sizeof(float));
    if(!p11)
    {
        perror("内存申请失败!");
        return 0;
    }
    memcpy(p11,a11, 10 * sizeof(float));
    printf("遍历复制数据后的数组:");
    for(int i = 0; i < 10; i++ )
    {
        printf("%.2f  ", *(p11+i));
    }
    printf("\n");
    printf("12.35的下标位置是:a11[%d]\n", work11(p11,10,12.35));

    free(p11);
    p11 = NULL;

运行截图

在这里插入图片描述

12.动态申请一个整型数组,并给每个元素赋值,要求删除第3个元素;

代码:

int a12[5] = {1,2,3,4,5};
    int* p12 = (int*)calloc(5,sizeof(int));
    if(!p12)
    {
        perror("内存申请失败!");
        return -1;
    }
    // 对申请的堆内存进行初始化
    memcpy(p12, a12, 5*4);
    // 遍历申请的堆内存
    for(int i = 0; i < 5; i++)
    {
        printf("%d ", *(p12+i));
    }
    printf("\n");
    memset(p12+2, 0, 1*4);
    // 再次遍历
    for(int i = 0; i < 5; i++)
    {
        printf("%d ", *(p12+i));
    }
    printf("\n");
    
    free(p12);
    p12 = NULL;

运行截图:

在这里插入图片描述

13.动态申请一个整型数组,并给每个元素赋值,要求在第4个元素后插入100;

代码:

int* p13 = (int*)malloc(40);

    if(!p13)
    {
        perror("内存申请失败!");
        return -1;
    }
    memset(p13, 0, 40);
    // 遍历
    for(int i = 0; i < 10; i++)
    {
        printf("%d ", *(p13 + i));
    }
    printf("\n");
    // 再次遍历
    for(int i = 0; i < 10;  i++)
    {
        if(i > 3) p13[i] = 100;
        printf("%d ", *(p13+i));
    }
    printf("\n");

    free(p13);
    p13 = NULL;

运行截图

在这里插入图片描述

14.控制台输入一个n,要求创建一个n行n列的数列,求对角线上元素的和,要求使用指针实现

代码:

int n;
    printf("请输入行列的大小:\n");
    scanf("%d", &n);
    int *p = (int*)calloc(n*n,sizeof(int));
    if(!p)
    {
        perror("内存申请失败!");
        return -1;
    }
    // 给数组赋值
    printf("请输入数组元素\n");
    for(int i = 0; i < n*n; i++ )
    {
        scanf("%d", p+i);
    }
    // 遍历数组
    printf("赋值后的数组:\n");
    for(int i = 0; i < n*n; i++)
    {
        if(i != 0 && i % n == 0) printf("\n");
        printf("%d\t", *(p+i));
    }
    printf("\n");
    int sum = 0, sum2 = 0;
    for(int i = 0; i < n; i++)
    {
        //printf("%d ", *(p + i*n + i));
        sum += *(p+i*n + i);
        sum2 += *(p + n*i + n - 1 - i);
    }
    printf("主对角线之和是:%d\n", sum);
    printf("辅对角线之和是:%d\n", sum2);
    free(p); // 释放堆内存
    p = NULL; // 指针悬空

运行截图

在这里插入图片描述

15.附加题【选做】: 编写一个函数,实现 memmove 的功能。

实现

// 实现memmove的功能
void* work15(void* to, const void* from, unsigned long count)
{

    for(int i = 0; i < count; i++)
    {
        *(char*)(to + i) = *(char*)(from + i);
    }
    return to;
}

调用

char a15_1[10] = "123456789";
    char a15_2[5];
    work15(a15_2,a15_1+2, 5 );
    printf("原数组:%s\n", a15_1);
    printf("目标数组:%s\n", a15_2);

运行截图

在这里插入图片描述