C语言刷题(3)——指针概念

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: C语言刷题(3)——指针概念

1.关于指针的概念,错误的是:( )

A.指针是变量,用来存放地址

B.指针变量中存的有效地址可以唯一指向内存中的一块区域

C.野指针也可以正常使用

D.局部指针变量不初始化就是野指针


解析:

答案是:C

野指针不可以正常使用。

知识点:

1、指针就是地址,但口语中说的指针通常指的是指针变量。

2、指针变量:指针变量是用来存放地址的,地址是唯一标识一个内存单元的。(我们通过&出变量的起始地址,把地址存放到一个变量中,这个变量就是指针变量)。

3、野指针

       (1)概念:野指针就是指针指向的位置是不可知的——就像一条野狗。

       (2)野指针成因:

               ①指针未初始化;

               ②指针越界访问;

               ③指针指向的空间释放。

       (3)如何规避野指针

               ①指针初始化(没有明确初始化的指针初始化NULL(本质是0))

               ②小心指针越界

               ③指针指向空间释放,及时置NULL

               ④避免返回局部变量的地址

               ⑤指针使用前检查有效性

               补充:NULL本质是0,在C++可以直接写0,但是C不可以,C要写成NULL

             //为什么要写成NULL,变量一旦赋值为NULL你就知道这是一个指针,让你容易识别

             //0地址是用户不能使用的,使用的话程序会崩溃。


2.以下系统中,int类型占几个字节,指针占几个字节,操作系统可以使用的最大内存空间是多大( )


A.32位下:4,4,2^32 64位下:8,8,2^64

B.32位下:4,4,不限制 64位下:4,8,不限制

C.32位下:4,4,2^32 64位下:4,8,2^64

D.32位下:4,4,2^32 64位下:4,4,2^64


解析:

答案是:C

①int类型在32位64位平台下都是4字节;
②指针在32位平台是4字节,在64位平台下是8字节;
③操作系统可以使用的内存空间:地址空间的个数32位平台是2^32个,64位平台是2^64个


3.下面代码的结果是:( )

#include <stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5 };
    short* p = (short*)arr;//arr是int*类型,将int*强制转换为short*
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        *(p + i) = 0;
    }
    for (i = 0; i < 5; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

A.1 2 3 4 5

B.0 0 3 4 5

C.0 0 0 0 5

D.1 0 0 0 0


解析:

答案是:B

知识点:

指针的类型:

①指针的解引用:指针的类型决定了,对指针解引用操作时有多大的权限;

②指针+-整数:指针的类型决定指针向前或向后走一步有多大。

指针类型的意义:指针的不同类型,其实提供了不同的视角去观察和访问内存。


图解:

4.下面关于指针运算说法正确的是:( )

A.整形指针+1,向后偏移一个字节

B.指针-指针得到是指针和指针之间的字节个数

C.整形指针解引用操作访问4个字节

D.指针不能比较大小

解析:

答案是:C

A.整形指针+1,向后偏移4个字节

B.指针减指针,指针必须指向同一块内存空间,得到是两个指针之间的元素个数

D.指针能比较大小

知识点:

 1.指针的类型:

        指针的类型决定了,指针+-整数的步长,指针解引用操作时的权限。 2.指针的运算

①指针+-整数:指针的类型决定了指针向前或向后走一步有多大;

②指针-指针:a.前提:两个指针要指向同一块内存空间(数组)

           b.指针减指针的绝对值,得到的是两个指针之间的元素个数。

③指针的关系运算(比较指针的大小):

    标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与第一个元素之前的那个内存位置的指针进行比较。


5.在小端机器中,下面代码输出的结果是:( )

#include <stdio.h>
int main()
{
    int a = 0x11223344;
    char* pc = (char*)&a;
    *pc = 0;
    printf("%x\n", a);
    return 0;
}

A.00223344

B.0

C.11223300

D.112233

解析:

答案是:C


在VS2019是小端,如下内存中的表示:

二、编程题

1.写一个函数打印arr数组的内容,不使用数组下标,使用指针。

arr是一个整形一维数组。

分析:

       使用函数打印数组,需要两个参数:

               ①数组的首元素地址;②数组的元素个数。

#include<stdio.h>
void print(int* p, int sz)
{
  //数组元素只能逐个引用,而不能一次引用整个数组(字符串除外)
  //逐个使用数组中的每一个元素时,通常借助for循环语句
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%d ", *(p + i));
  }
  printf("\n");
}
int main()
{
  int arr[] = { 0 ,1 ,2, 3, 4, 5 ,6, 7, 8, 9, 10 };
  //计算数组元素个数
  int sz = sizeof(arr) / sizeof(arr[0]);
  //调用函数实现
  //打印数组:①知道数组的地址②知道数组的元素个数
  print(arr, sz);
  return 0;
}


2.点击链接,做题

字符逆序__牛客网 (nowcoder.com)

分析:


代码1:数组的形式

#include <stdio.h>
#include<string.h>
//使用数组的方式实现
void reverse(char* str)
{
    //左下标从0开始
    int left = 0;
    //右下标=元素个数-1
    int right = strlen(str) - 1;
    //循环交换--条件:left<right
    while (left < right)
    {
        //交换
        char tmp = *(str + left);
        *(str + left) = *(str + right);
        *(str + right) = tmp;
        //循环调整——趋于循环结束的语句
        left++;
        right--;
    }
}
int main()
{
    char arr[10000] = { 0 };
    //注:scanf默认读取的时候遇到空格就结束
    //输入字符串
    gets(arr);
    //调用函数实现
    reverse(arr);
    //输出
    puts(arr);
    return 0;
}

代码2:指针的形式

#include <stdio.h>
#include<string.h>
//使用指针的方式实现
void reverse(char* str)
{
    //左边的起始地址
    char* left = str;
    //右边的地址
    char* right = str + strlen(str) - 1;
    while (left < right)//指针的关系运算
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
int main()
{
    char arr[10000] = { 0 };
    gets(arr);
    //调用函数实现
    reverse(arr);
    //输出
    puts(arr);
    return 0;
}

3.用C语言在屏幕上输出菱形图案:

分析:关键在于找出行数与空格、*之间的关系。


#include<stdio.h>
int main()
{
  int line = 0;
  scanf("%d", &line);
  //上-line行
  int i = 0;
  for (i = 0; i < line; i++)
  {
    //打印一行
    //先打印空格
    int j = 0;
    for (j = 0; j < line - 1 - i; j++)
    {
      printf(" ");
    }
    //再打印*
    for (j = 0; j < 2 * (i+1) - 1; j++)
    {
      printf("*");
    }
    printf("\n");
  }
  //下--line-1行
  for (i = 0; i < line - 1; i++)
  {
    //打印一行
    //先打印空格
    int j = 0;
    for (j = 0; j <= i; j++)
    {
      printf(" ");
    }
    //再打印*
    for (j = 0; j < 2 * (line-1-i) - 1; j++)
    {
      printf("*");
    }
    printf("\n");
  }
  return 0;
}

如输入6,运行结果:


4.求出0~100000之间的所有“水仙花数”并输出。

“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”。

分析:

判断一个数i是否为水仙花数

1.计算出i是几位数——n

2.计算i的十进制的n次方之和,并判断是否等于i本身

补充:水仙花数其实就是自幂数

#include<stdio.h>
#include<math.h>
int main()
{
  int i = 0;
  for (i = 0; i <= 100000; i++)
  {
    //判断i是否为水仙花数
    //1.计算出i是几位数--n(注:使用一个中间变量tmp,防止i被改变)
    int n = 1;//一个数最小是一位
    int tmp = i;
    while (tmp > 9)
    {
      tmp /= 10;
      n++;
    }
    //2.计算i的十进制的n次方之和,并判断是否等于i本身
    tmp = i;
    int sum = 0;
    while (tmp)
    {
      sum += (int)pow(tmp % 10, n);//pow是算次方的函数,返回类型为double
      tmp /= 10;
    }
    if (sum == i)
    {
      printf("%d ", i);
    }
  }
  return 0;
}

运行结果:


5.求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字,

例如:2+22+222+2222+22222

/*
  分析:a=2  k=0 sum=0
    k=0*10+2=2
    k=2*10+2=22
    k=22*10+2=222
    k=222*10+2=2222
    k=2222*10+2=22222
    循环:第i项为k,则i+1项 = k*10+a;sum += k;
*/
#include<stdio.h>
int main()
{
  int a = 0;
  int n = 5;
  scanf("%d", &a);
  //计算
  int i = 0;
  int k = 0;
  int sum = 0;
  for (i = 0; i < n; i++)
  {
    k = k * 10 + a;
    sum += k;
  }
  //输出
  printf("%d\n", sum);
  return 0;
}


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