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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 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;
}
相关文章
|
25天前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
77 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
25天前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
48 9
|
25天前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
42 7
|
1月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
122 13
|
28天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
28天前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
102 3
|
29天前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
28天前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
39 1
|
1月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
1月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。