C语言之指针部分必备练习题

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: C语言之指针部分必备练习题

1.


语言中哪一种形式声明了一个指向char类型变量的指针p,p的值不可修改,但p指向的变量值可修改?( )


作业内容


A.const char *p


B.char const *p


C.char*const p


D.const char *const p


答案解析:


A:错误,const修饰*p,表示p指向的内容不能修改


B:错误,同上


C:正确,const修饰p本身,表示p的指向不能修改,p指向的空间中内容可以修改


D:错误,第一个const表示p指向的内容不能修改,第二个const表示p不能指向其他变量


因此,选择C


2.


以下关于指针的说法,正确的是( )


作业内容


A.int *const p与int const *p等价


B.const int *p与int *const p等价


C.const int *p与int const *p等价


D.int *p[10]与int (*p)[10]等价



答案解析:


A:错误,int* const p中,const修饰指针变量p本身,表示p的指向不能改变,


 int const *p中,const修饰p指针解引用之后的结果,表示p指向的内容不能改变


 因此,不等价


B:错误,同上


C:正确,const都修饰p指针解引用之后的结果,表示p指向的内容不能改变


D:错误,int *p[10]定义了一个指针数组,数组中10个元素,每个元素都是int*类型的指针


 int (*p)[10]定义了一个数组指针,该指针只能指向存储10个整形元素的数组


因此:选择C


3.


程序死循环解释


作业内容


VS开发环境调试下面的代码,画图解释下面代码的问题


#include <stdio.h>
int main()
{
    int i = 0;
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    for(i=0; i<=12; i++)
    {
        arr[i] = 0;
        printf("hello bit\n");
    }
    return 0;
}

答案解析为:


程序崩溃的原因在于数组越界访问


对于该程序,访问不属于该数组的元素!


0a2653c851af460fa595bd959398a8f1.png2d65d23f6d4748949b924e4057485923.png


答案解析:


以下代码有两个问题:1. 数组访问越界   2. 死循环


以下代码再vs2013下会造成死循环,原因:


栈内存:


   

|CC  CC  CC  CC|
         arr[0]|01  00  00  00|\
         arr[1]|02  00  00  00| \
         arr[2]|03  00  00  00|  \
         arr[3]|04  00  00  00|   \
         arr[4]|05  00  00  00|    \
         arr[5]|06  00  00  00|    /  arr的空间
         arr[6]|07  00  00  00|   /
         arr[7]|08  00  00  00|  /
         arr[8]|09  00  00  00| /
         arr[9]|0A  00  00  00|/
               |CC  CC  CC  CC|
               |CC  CC  CC  CC|
               |00  00  00  00| i的空间
               |CC  CC  CC  CC|


for循环中,i的内容是从0,一直增加到12,而数组只有10个空间,因此会越界


每次访问arr数组i号位置时,都会将该位置内容设置为0,当访问到arr[12]时,也会将该位置内容设置为0,而位     置恰好为i的位置,即a[12]恰巧将i设置为0,因此造成死循环。


4.


调整奇数偶数顺序


作业内容


调整数组使奇数全部都位于偶数前面。


题目:


输入一个整数数组,实现一个函数,


来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,


所有偶数位于数组的后半部分。


参考代码为:


#include <stdio.h>
void fun(int* arr, int sz)
{
  int i = 0;
  int* left = arr;
  int* right =arr+ sz - 1;
  while (left < right)  //调整数组使奇数(数组元素)全部都位于偶数前面。
  {
  while (*left % 2 == 1)
  {
    left++;
  }
  while (*right % 2 == 0)
  {
    right--;
  }
  if (left < right)
  {
    int tmp = *left;
    *left = *right;
    *right = tmp;
  }
  }
  for (i = 0; i < sz; i++)
  {
  printf("%d ", arr[i]);
  }
}
int main()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  fun(arr, sz);
  return 0;
}


代码的运行结果为:


6de278e6d6694ce5bb08e7e842b7e74b.png


另一种思路为:


/*

思路:

1. 给定两个下标left和right,left放在数组的起始位置,right放在数组中最后一个元素的位置

2. 循环进行一下操作

a. 如果left和right表示的区间[left, right]有效,进行b,否则结束循环

b. left从前往后找,找到一个偶数后停止

c. right从后往前找,找到一个奇数后停止

d. 如果left和right都找到了对应的数据,则交换,继续a,

*/

void swap_arr(int arr[], int sz)
{
  int left = 0;
  int right = sz-1;
  int tmp = 0;
  while(left<right)
  {
     // 从前往后,找到一个偶数,找到后停止
  while((left<right)&&(arr[left]%2==1))
  {
    left++;
  }
  // 从后往前找,找一个奇数,找到后停止
  while((left<right)&& (arr[right]%2==0))
  {
    right--;
  }
     // 如果偶数和奇数都找到,交换这两个数据的位置
     // 然后继续找,直到两个指针相遇
  if(left<right)
  {
    tmp = arr[left];
    arr[left] = arr[right];
    arr[right] = tmp;
  }
  }
}


5.


strcpy实现


作业内容


模拟实现库函数strcpy



//库函数strcpy函数的实现  
//strcpy函数是字符串拷贝函数
#include <stdio.h>
void my_strcpy(int* arr1[], int* arr2[],int sz)
{
  int i = 0;
  for (i = 0; i < sz; i++)
  {
  arr1[i] = arr2[i];
  }
}
int main()
{
  int arr1[10] = { 0 };
  int arr2[10] = { 1,2,3,4,5,6,7,8,9,0 };
  int sz = sizeof(arr1) / sizeof(arr1[0]);
  my_strcpy(arr1, arr2, sz);
  int i = 0;
  for (i = 0; i < sz; i++)
  {
  printf("%d ", arr1[i]);
  }
  return 0;
}


代码的运行结果为:


12c3b7f3f8814309a195c64f051d4445.png


6.


strlen实现


作业内容


模拟实现库函数strlen


//strlen是一个只负责字符串的库函数!
//计算的是字符串 \0 之前的长度,不包括\0
#include <stdio.h>
int my_strlen(char* arr)   //千万不能写成  char* arr[]
{
  int count = 0;
  while (*arr)
  {
  count++;
  arr++;
  }
  return count;
}
int main()
{
  char arr[] = "abcdefgh";
  int len = my_strlen(arr);
     printf("%d\n", len);
  return 0;
}


代码的运行结果为:


34e8d716411043c08c7ffba9fbba23de.png    


7.牛客网链接为:有序序列判断_牛客题霸_牛客网 (nowcoder.com)


有序序列判断



输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)。


数据范围: 3 \le n \le 50 \3≤n≤50  序列中的值都满足 1 \le val \le 100 \1≤val≤100


输入描述:

第一行输入一个整数N(3≤N≤50)。


第二行输入N个整数,用空格分隔N个整数。


输出描述:

输出为一行,如果序列有序输出sorted,否则输出unsorted。


示例1

输入:


5

1 6 9 22 30

输出:


sorted

示例2

输入:


5

3 4 7 2 10

输出:


unsorted

示例3

输入:


5

1 1 1 1 1

输出:


sorted

参考代码为:


#include <stdio.h>
int main()
{
    int a[50]={0};
    int n = 0;
    int  flag1 = 0;
    int flag2 = 0;
    int i = 0;
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
        if (i > 0)
        {
            if (a[i] < a[i - 1])
            {
                flag1 = 1;
            }
            else if (a[i] > a[i - 1]) 
            {
                flag2 = 1;
            }
        }
    }
    if (flag1 && flag2)
        printf("unsorted\n");//只有当flag1和flag2都为1的时候序列无序
    else
        printf("sorted\n");
    return 0;
}

8.牛客网链接为:最高分与最低分之差_牛客题霸_牛客网 (nowcoder.com)


最高分与最低分之差


描述


输入n个成绩,换行输出n个成绩中最高分数和最低分数的差。


输入描述:

两行,第一行为n,表示n个成绩,不会大于10000。


第二行为n个成绩(整数表示,范围0~100),以空格隔开。


输出描述:

一行,输出n个成绩中最高分数和最低分数的差。


示例1

输入:


10

98 100 99 97 95 99 98 97 96 100

输出:


参考代码为:

#include <stdio.h>
int main()
{
    int n = 0;
    int max = 0;
    int min = 100;
    scanf("%d", &n);
    int i = 0;
    int tmp = 0;//存放内次读取的成绩
    for(i=0; i<n; i++)
    {
        scanf("%d", &tmp);
        if(tmp > max)
            max = tmp;
        if(tmp < min)
            min = tmp;
    }
    printf("%d\n", max-min);
    return 0;
}
相关文章
|
16天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
41 0
|
15天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
11 2
|
16天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
16天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
22天前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
22天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
22天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
23天前
|
C语言
C语言指针(3)
C语言指针(3)
11 1
|
23天前
|
C语言
C语言指针(2)
C语言指针(2)
12 1
|
15天前
|
编译器 C语言
【c语言】指针就该这么学(2)
本文详细介绍了指针与数组的关系,包括指针访问数组、一维数组传参、二级指针、指针数组和数组指针等内容。通过具体代码示例,解释了数组名作为首元素地址的用法,以及如何使用指针数组模拟二维数组和传递二维数组。文章还强调了数组指针与指针数组的区别,并通过调试窗口展示了不同类型指针的差异。最后,总结了指针在数组操作中的重要性和应用场景。
13 0