C语言(指针练习2)

  1. 编写函数,要求用指针做形参,分别实现以下功能: (1)求一个字符串长度 (2)在一个字符 串中统计大写字母的个数 (3)在一个字符串中统计数字字符的个数

    c 复制代码
    #include <stdio.h>
    
    int str1(const char *str)
    {
      int length = 0;
      while (*str != '\0')
      {
        length++;
        str++;
      }
      return length;
    }
    int str2(const char *str)
    {
      int count = 0;
      while (*str != '\0')
      {
        if (*str >= 'A' && *str <= 'Z')
        {
          count++;
        }
        str++;
      }
      return count;
    }
    int str3(const char *str)
    {
      int count = 0;
      while (*str != '\0')
      {
        if (*str >= '0' && *str <= '9')
        {
          count++;
        }
        str++;
      }
      return count;
    }
    
    int main(int argc, char *argv[])
    {
      char str[] = "Hello,World! 123\n";
    
      printf("字符串的长度为:%d\n", str1(str));
      printf("字符串中大写字母的个数为:%d\n", str2(str));
      printf("字符串中数字的个数为:%d\n", str3(str));
      return 0;
    }

在主函数中,定义了一个字符串str,并调用了str1、str2和str3函数来输出字符串的长度、大写字母的个数和数字的个数。

代码分析如下:

str1函数:通过使用指针遍历字符串的每个字符,每遍历一个字符,就将长度加1,直到遇到字符串的结束符'\0',返回长度。

str2函数:同样使用指针遍历字符串的每个字符,如果字符是大写字母,则计数器加1,返回计数器的值。

str3函数:同样使用指针遍历字符串的每个字符,如果字符是数字,则计数器加1,返回计数器的值。

主函数中,定义了一个字符串str,并将其作为参数传递给str1、str2和str3函数,分别输出字符串的长度、大写字母的个数和数字的个数。

最后,返回0表示程序执行成功结束。

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

    c 复制代码
    #include <stdio.h>
    #define N 3 // 假设二维数组是 3x3 的
    
    void trans(int (*p)[N], int size)
    {
      for (int i = 0; i < size; i++)
      {
        for (int j = 1 + i; j < size; j++)
        {
          int temp = p[i][j];
          p[i][j] = p[j][i];
          p[j][i] = temp;
        }
      }
    }
    void get2(int (*p)[N], int size)
    {
      for (int i = 0; i < size; i++)
      {
        for (int j = 0; j < size; j++)
        {
          printf("%d ", p[i][j]);
        }
        printf("\n");
      }
    }
    
    int main(int argc, char *argv[])
    {
      int array[N][N] = {
          {1, 2, 3},
          {4, 5, 6},
          {7, 8, 9}};
      printf("转置前的数组:\n");
      get2(array, 3);
      trans(array, 3);
      printf("转置后的数组:\n");
      get2(array, 3);
      return 0;
    }

代码分析如下:

str1函数:通过使用指针遍历字符串的每个字符,每遍历一个字符,就将长度加1,直到遇到字符串的结束符'\0',返回长度。

str2函数:同样使用指针遍历字符串的每个字符,如果字符是大写字母,则计数器加1,返回计数器的值。

str3函数:同样使用指针遍历字符串的每个字符,如果字符是数字,则计数器加1,返回计数器的值。

主函数中,定义了一个字符串str,并将其作为参数传递给str1、str2和str3函数,分别输出字符串的长度、大写字母的个数和数字的个数。

最后,返回0表示程序执行成功结束。

  1. 编写函数,要求用指针做形参,实现统计二维数组上三角中的0 的数量:

    c 复制代码
    #include <stdio.h>
    
    // 函数声明,统计二维数组上三角中0的数量
    int coun(int *matrix, int rows, int cols)
    {
      int count = 0;
      for (int i = 0; i < rows; i++)
      {
        for (int j = i + 1; j < cols; j++)
        {
          if (*(matrix + i * cols + j) == 0)
          {
            count++;
          }
        }
      }
      return count;
    }
    
    int main()
    {
      int matrix[3][3] = {
          {1, 0, 0},
          {0, 3, 0},
          {4, 0, 0}};
    
      int rows = 3;
      int cols = 3;
    
      int zeroCount = coun((int *)matrix, rows, cols);
      printf("上三角中的0的数量: %d\n", zeroCount);
    
      return 0;
    }

这段代码实现了一个函数coun,该函数用于统计二维数组上三角中0的数量。函数接受一个指向二维数组的指针,以及数组的行数和列数作为参数。在函数内部,使用嵌套的循环遍历二维数组的上三角部分,即i < j的元素,如果元素的值为0,则将计数器加1。最后,函数返回计数器的值。

在main函数中,声明一个3x3的二维数组matrix,并初始化值。然后,调用coun函数,传入matrix的指针以及行数和列数作为参数。最后,打印出上三角中0的数量。

代码的输出结果为:上三角中的0的数量: 4

  1. 编写一个指针函数,返回二维数组中最大元素的地址。

    c 复制代码
    #include <stdio.h>
    
    // 函数声明,返回指向二维数组中最大元素的指针
    int *find(int *array, int rows, int cols)
    {
      int max = array[0];
      int *maxptr = &array[0];
    
      for (int i = 0; i < rows; i++)
      {
    
        for (int j = 0; j < cols; j++)
        {
          int *cur = &array[i * cols + j];
          if (*cur > max)
          {
            max = *cur;
            maxptr = cur;
          }
        }
      }
      return maxptr;
    }
    
    int main()
    {
      int array[3][4] = {
          {1, 3, 5, 7},
          {2, 6, 9, 4},
          {8, 0, 10, 12}};
    
      int rows = 3;
      int cols = 4;
    
      // 调用函数并获取最大元素的地址
      int *maxEle = find((int *)array, rows, cols);
    
      // 打印最大元素的值和它的地址
      printf("最大元素为: %d\n", *maxEle);
      printf("最大元素的地址为: %p\n", maxEle);
    
      return 0;
    }

在main函数中定义了一个3行4列的二维数组array,然后调用find函数并传入数组的首地址(int *)array,以及数组的行数和列数。

在find函数中,首先定义了一个变量max来保存最大的元素值,以及一个指针变量maxptr来保存最大元素的地址。

然后使用两个嵌套的循环遍历二维数组的每一个元素,通过计算当前元素在一维数组中的索引i * cols + j来访问元素。

在循环中,将当前元素的地址保存在指针变量cur中,然后判断当前元素是否大于max,如果是,则更新max和maxptr的值。

最后,find函数返回maxptr,即最大元素的地址。

在main函数中,通过printf函数打印最大元素的值和它的地址。

整个程序的执行结果将会输出为:

最大元素为: 12 最大元素的地址为: 0x7fffa4d37268

  1. 面试题

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

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

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

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

    5)定义p为指向(含有n个整形元素的一维数组)的指针变量;

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

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

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

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

  2. 动态申请一个具有10个float类型元素的内存空间,从一个已有的数组中拷贝数据,并找出第一次出现 12.35 的下标位置,并输出。

    c 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
      // 已有的数组
      float originalArray[] = {1.1, 2.2, 3.3, 12.35, 4.4, 5.5, 12.35, 6.6, 7.7, 8.8};
      int originalSize = sizeof(originalArray) / sizeof(originalArray[0]);
      int copySize = 10; // 我们想要拷贝的元素数量
    
      // 动态分配内存
      float *dynamicArray = (float *)malloc(copySize * sizeof(float));
      if (dynamicArray == NULL)
      {
        printf("Memory allocation failed\n");
        return 1; // 分配失败,返回错误代码
      }
    
      // 拷贝数据
      for (int i = 0; i < copySize && i < originalSize; i++)
      {
        dynamicArray[i] = originalArray[i];
      }
    
      // 查找12.35的下标
      int index = -1; // 初始化下标为-1,表示未找到
      for (int i = 0; i < copySize; i++)
      {
        if (dynamicArray[i] == 12.35)
        {
          index = i; // 找到后更新下标
          break;     // 找到第一个就退出循环
        }
      }
    
      // 输出结果
      if (index != -1)
      {
        printf("The first occurrence of 12.35 is at index %d in the dynamic array.\n", index);
      }
      else
      {
        printf("12.35 not found in the dynamic array.\n");
      }
    
      // 释放动态分配的内存
      free(dynamicArray);
    
      return 0;
    }

    首先,已经有一个包含一些浮点数的原始数组originalArray。通过sizeof运算符,我们可以得到originalArray的元素数量originalSize。

然后,我们定义了一个变量copySize,表示我们希望拷贝的元素数量。copySize的值被设置为10。

接下来,我们使用malloc函数动态分配了copySize个float类型的内存空间,并将返回的指针赋给dynamicArray。如果内存分配失败(即dynamicArray为NULL),则输出错误消息,并返回1结束程序。

然后,我们使用一个for循环来将originalArray中的元素拷贝到dynamicArray中。仅当拷贝的元素数量小于copySize且小于originalSize时,才进行拷贝。

接下来,我们使用一个for循环在dynamicArray中查找值为12.35的第一个元素的下标。如果找到了,我们将下标赋给变量index,并使用break语句退出循环。如果未找到,index的值保持为-1。

最后,根据index的值,我们输出结果。如果index不等于-1,则表示找到了值为12.35的元素,输出其下标。否则,输出未找到的消息。

最后,我们使用free函数释放动态分配的内存。

总体来说,这段代码可以在动态数组中查找特定值的下标,并输出结果。

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

    c 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
      int n = 10;                                  // 数组的大小
      int *array = (int *)malloc(n * sizeof(int)); // 动态分配内存
      if (array == NULL)
      {
        printf("Memory allocation failed\n");
        return 1;
      }
    
      // 给数组元素赋值
      for (int i = 0; i < n; i++)
      {
        array[i] = i + 1; // 假设数组元素为1, 2, 3, ..., 10
      }
    
      // 打印原始数组
      printf("Original array:\n");
      for (int i = 0; i < n; i++)
      {
        printf("%d ", array[i]);
      }
      printf("\n");
    
      // 模拟删除第3个元素(索引为2)
      int indexToDelete = 2;
      if (indexToDelete >= 0 && indexToDelete < n - 1)
      { // 确保索引有效且不是最后一个元素
        for (int i = indexToDelete; i < n - 1; i++)
        {
          array[i] = array[i + 1]; // 将后续元素向前移动
        }
        n--; // 更新数组的实际大小(注意:这里的n只是用于逻辑上的大小,内存大小仍然是原来的)
      }
      else
      {
        printf("Invalid index for deletion\n");
      }
      printf("Array after simulating deletion of element at index 2:\n");
      for (int i = 0; i < n; i++)
      { // 注意:这里使用更新后的n
        printf("%d ", array[i]);
      }
      printf("\n");
    
      // 释放动态分配的内存(注意:即使我们"删除"了一个元素,内存大小仍然是原来的)
      free(array);
    
      return 0;
    }
  2. 动态申请一个整型数组,并给每个元素赋值,要求在第4个元素后插入100;

    c 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
      int n = 10;                                  // 初始数组的大小
      int *array = (int *)malloc(n * sizeof(int)); // 动态分配内存
      if (array == NULL)
      {
        printf("Memory allocation failed\n");
        return 1;
      }
    
      // 给数组元素赋值
      for (int i = 0; i < n; i++)
      {
        array[i] = i + 1; // 假设数组元素为1, 2, 3, ..., 10
      }
    
      // 打印原始数组
      printf("Original array:\n");
      for (int i = 0; i < n; i++)
      {
        printf("%d ", array[i]);
      }
      printf("\n");
    
      // 插入新元素的位置(在第4个元素后,即索引为3之后)
      int insertIndex = 3;
    
      // 重新分配内存以容纳新元素
      int *newArray = (int *)realloc(array, (n + 1) * sizeof(int));
      if (newArray == NULL)
      {
        printf("Memory reallocation failed\n");
        free(array); // 不要忘记释放原始内存
        return 1;
      }
      array = newArray; // 更新指针
    
      // 将新元素插入到指定位置
      for (int i = n; i > insertIndex; i--)
      {
        array[i] = array[i - 1]; // 将后续元素向后移动
      }
      array[insertIndex] = 100; // 插入新元素
    
      // 更新数组大小
      n++;
    
      // 打印修改后的数组
      printf("Array after inserting 100 at index %d:\n", insertIndex);
      for (int i = 0; i < n; i++)
      {
        printf("%d ", array[i]);
      }
      printf("\n");
    
      // 释放动态分配的内存
      free(array);
    
      return 0;
    }

    首先,在程序开始处,使用了函数malloc来动态分配了一个大小为n的整型数组array。如果内存分配失败,会打印"Memory allocation failed"并返回1。

然后,使用循环给数组元素赋值,假设数组元素为1, 2, 3, ..., 10。

接下来,打印原始数组。

然后,指定插入新元素的位置,这里是在第4个元素后面。

然后,使用函数realloc重新分配内存,把原始的数组array扩展一个元素的大小。如果内存重新分配失败,会打印"Memory reallocation failed",释放原始内存并返回1。

然后,将newArray赋值给array,更新指针。

然后,使用循环将插入位置之后的元素依次向后移动。

然后,将新元素100插入到指定位置。

然后,更新数组大小。

然后,打印修改后的数组。

最后,使用函数free释放动态分配的内存。

整个程序的功能是在数组的指定位置插入一个新元素,并打印修改后的数组。

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

    c 复制代码
    	#include <stdio.h>
    #include <stdlib.h>
     
    // 函数声明
    int sumDiagonal(int** matrix, int n);
     
    int main() {
        int n;
        printf("请输入一个整数 n: ");
        scanf("%d", &n);
     
        // 动态分配内存给二维数组(矩阵)
        int** matrix = (int**)malloc(n * sizeof(int*));
        for (int i = 0; i < n; i++) {
            matrix[i] = (int*)malloc(n * sizeof(int));
        }
     
        // 初始化矩阵元素(这里为了示例简单,将矩阵元素初始化为行号和列号的和)
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = i + j;
            }
        }
     
        // 打印矩阵
        printf("矩阵为:\n");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                printf("%d ", matrix[i][j]);
            }
            printf("\n");
        }
     
        // 计算对角线上元素的和
        int sum = sumDiagonal(matrix, n);
        printf("对角线上元素的和为: %d\n", sum);
     
        // 释放内存
        for (int i = 0; i < n; i++) {
            free(matrix[i]);
        }
        free(matrix);
     
        return 0;
    }
     
    // 计算对角线上元素的和的函数
    int sumDiagonal(int** matrix, int n) {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += matrix[i][i];  // 主对角线
            // sum += matrix[i][n-i-1];  // 如果需要副对角线,取消注释
        }
        // 注意:如果包括副对角线,需要确保 n 是奇数或者调整逻辑以避免重复计算中心元素(对于奇数 n)
        return sum;
    }
  2. .附加题【选做】: 编写⼀个函数,实现 memmove 的功能。

c 复制代码
// 实现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;
}
相关推荐
silver68733 分钟前
使用C语言连接MySQL
c语言
pl00201 小时前
C++对象数组&对象指针&对象指针数组
算法·对象数组·对象指针·对象指针数组
白#泽1 小时前
课上测试:商用密码接口实现
服务器·数据库·算法
sahuid1 小时前
Redis 中 IntSet 底层数据结构
数据结构·数据库·redis
saku2 小时前
赛博斗蛐蛐?B站微博知乎大混战中学透GraphRAG
人工智能·后端·算法
野風_199602012 小时前
代码随想录第51天
算法
-cc- Lynn2 小时前
字符串类算法
算法·leetcode·职场和发展
坊钰2 小时前
【Java 数据结构】如何写一副扑克牌 (附:全部码源) !!!
java·开发语言·前端·数据结构·学习
HUT_Tyne2652 小时前
力扣--LCR 129.字母迷宫
算法·leetcode·职场和发展
初学者丶一起加油2 小时前
C语言基础:数组(字符数组)
linux·c语言·开发语言·数据结构·vscode·算法·ubuntu