2.14 指针练习

1、选择题

1.1、若有下面的变量定义,以下语句中合法的是(   A   )。

int ia[10]*p

A p=a+2;       B) p=a[5];    

 C) p=a[2]+2;      D p=&(i+2);

解析:指针是用来存储变量地址,数组的地址可以用变量名代替,a+2表示数组首地址后移2位,表示a[2]的地址,所以合法,a[5]表示的是数组元素的值,不是地址,所以不合法,a[2]+2表示数组第二个元素的值+2,得到的是一个值,不是地址,所以也不合法,表达式i+2产生的是一个整数值,不能对整数取地址,所以也不合法

1.2、有以下程序

main()

{

   int  a[3][3],*p,i;

   p=&a[0][0];

   for(i=0;i<9;i++)

      p[i]=i;

   for(i=0;i<3;i++)

      printf("%d ",a[1][i]);

}

程序运行后的输出结果是    D     

A)0 1 2

B)1 2 3

C)2 3 4

D)3 4 5

解析:for(i=0;i<9;i++ ) p[i]=i; 这句是将0~9赋给数组a[3][3], for(i=0;i<3;i++) printf("%d ",a[1][i]);这句是打印第二行的元素a[1][0]~a[1][2],即3 4 5

1.3、有以下程序

int  main()

{   int  a[3][2]={0}, (*ptr)[2],i,j;

    for(i=0;i<2;i++)

    {   ptr=a+i;

        scanf("%d",*ptr);

        *ptr++;

    }

    for(i=0;i<3;i++)

    {

        for(j=0;j<2;j++)

           printf("%2d",a[i][j]);

        printf("\n");

    }

}        

若运行时输入:1  2  3<回车>,则输出结果为     D      

A)产生错误信息

B1 0

    2 0

   0 0

C1 2

   3 0

    0 0

D1 0

    2 0

   3 0

解析:定义了一个3x2的二维数组a,并初始化为0。定义了一个指向包含2个整数的数组的指针ptr。使用循环,每次将ptr指向a的某一行,并读取一个整数到这一行。输入1 2 3将分别被读取到a[0][0]a[1][0]a[2][0]。所以结果为 1 0  2 0  3 0

1.4、有以下程序

main()

{   int  a[]={1,2,3,4,5,6,7,8,9,0},*p;

    for(p=a;p<a+10;p++)

      printf("%d,",*p);

}

程序运行后的输出结果是     A      

A1234567890

B23456789101

C0123456789

D111111111,,1

解析:程序首先定义了一个包含10个整数的数组a,然后定义了一个指向整数的指针p。接着,程序使用for循环遍历数组a的每一个元素,并使用指针p来访问和打印这些元素的值。程序中的循环从p=a开始,即指针p指向数组a的第一个元素。每次循环中,p都会递增,指向下一个元素,直到p达到a+10,即数组a的最后一个元素之后的位置。在循环的每次迭代中,*p都会解引用指针p,得到它当前指向的元素的值,并使用printf函数打印这个值。由于数组a的元素是按照{1,2,3,4,5,6,7,8,9,0}的顺序排列的,因此程序会按照这个顺序打印出数组中的每一个元素。所以,程序运行后的输出结果是:1,2,3,4,5,6,7,8,9,0

1.5、有以下程序

main()

{

   char  s[]="159",*p;

   p=s;

   printf("%c",*p++);

   printf("%c",*p++);

}

程序运行后的输出结果是       A        

A1 5 B1 6 C1 2 D5 9

解析:指针 p 被声明,并且被赋值为 s 的地址,也就是 s 数组第一个字符 '1' 的地址。printf("%c",*p++); 语句中,*p++ 表示先解引用指针 p(也就是获取指针当前指向的字符),然后将指针 p 向后移动一位。所以,第一次执行此语句时,会打印出 s 数组的第一个字符 '1',然后 p 会指向 '5'。第二次执行 printf("%c",*p++); 时,同样先解引用 p(此时 p 指向 '5'),然后打印出 '5',接着 p 会向后移动一位,指向 '9'。因此,程序运行后的输出结果是:15

1.6、有以下程序

point(char  *p)

{

   p+=3;

}

int  main()

{   char  b[4]={'a','b','c','d'}, *p=b;

    point(p);    printf("%c\n",*p);

}

程序运行后的输出结果是     D     

Aa Bb Cc Dd

解析:在这个程序中,point函数接收一个字符指针p作为参数,并将这个指针向后移动3个位置。在main函数中,定义了一个字符数组b,并用指针p指向它的起始位置。接下来,调用point函数并将p作为参数传递。在point函数中,p被增加了3,这意味着p现在指向了数组b中第4个元素的位置。然后,打印出p所指向的字符程序将输出'd'。因此,程序运行后的输出结果是 d

1.7、设有如下定义语句 int m[ ]={2,4,6,8}, *k=m;

以下选项中,表达的值为 6的是    A     

A *(k+2) B k+2 C *k+2 D *k+=2

解析:*(k+2):这个表达式先计算k+2,得到指向m[2]的指针。然后,通过解引用这个指针,我们得到m[2]的值,即6。k+2:这个表达式计算了k指针加上2,得到指向m[2]的指针。但是,它并没有解引用这个指针,所以它的值是m[2]的地址,而不是它的值。*k+2:这个表达式先解引用k,得到m[0]的值,即2。然后,将2加上2,得到4。*k+=2:这个表达式先解引用k,得到m[0]的值,即2。然后,将这个值加2,并将结果(4)存回m[0]。但是,这个表达式本身的值是m[0]加2之前的值,即2。

1.8、若有定义语句int year=2009*p=&year,以下不能使变量 year 中的值增至 2010 的语 句是(    D    )

A)*p+=1 B)( *p)++ C)++(*p) D)*p++

解析:*p+=1;这个语句会解引用指针p(即访问 p 所指向的内存位置),然后将该位置的值增加1。因此,year的值会从2009增加到2010。(*p)++;这个语句也是先解引用指针p,然后将其值增加1。同样,year的值会从 2009 增加到 2010。++(*p);这个语句同样是先解引用指针p,然后将其值增加1。year的值会从2009增加到 2010。*p++;包含两个部分:*pp++。首先,*p会解引用指针p,获取其指向的值(即 year 的值)。但是,由于后面紧跟着 p++,指针p会被递增,指向下一个内存位置。然而,这个操作并没有改变year的值,只是改变了指针p的指向。因此,year的值仍然是 2009,而p现在指向了year之后的内存位置。综上所述,不能使变量year中的值增至2010的语句是*p++;

1.9、设有定义double x[10],*p=x;以下能给数组 x 下标为 6 的元素读入数 据的正确语句是   C  

A)scanf("%f",&x[6]); B)scanf("%lf",*(x+6));

C)scanf("%lf",p+6); D)scanf("%lf",p[6])

解析:scanf("%f",&x[6]);这个选项使用了 %f 格式说明符,这是不正确的,因为 x[6] 是一个 double 类型的变量,应该使用 %lf

scanf("%lf",*(x+6));这个选项使用了 %lf 格式说明符,这是正确的。但是,*(x+6) 实际上是解引用操作,这会得到 x[6] 的值,而不是它的地址。scanf 需要变量的地址来存储输入,所以这是不正确的。

scanf("%lf",p+6);这个选项也是正确的。p+6 是正确的,因为它给出了数组 x 第 6 个元素的地址。%lf 格式说明符也是正确的。

scanf("%lf",p[6]);这个选项是错误的。p[6] 会得到 x[6] 的值,而不是它的地址。scanf 需要变量的地址来存储输入。

因此,正确的选项是scanf("%lf",p+6);

1.10、若有定义语句char s[3][10], (*k)[3], *p; ,则以下赋值语句正确的是     BD    

A)p=s; B)p=s[0]; C)p=k; D)k=s;

解析:p=s;这个赋值是错误的。因为s是一个二维数组,其类型是char[3][10],而p是一个字符指针(char*)。它们不兼容,因此不能直接将二维数组的地址赋给一个字符指针。

p=s[0];这个赋值是正确的。s[0]是二维数组s的第一个元素,它是一个一维字符数组(类型是char[10])。s[0]的地址可以赋给一个字符指针p,因为p可以指向一个字符数组的首字符。

p=k;这个赋值是错误的。k是一个指向包含3个元素的数组的指针,而p是一个字符指针。它们不兼容,因此不能直接将k的地址赋给p

k=s;这个赋值是正确的。s是一个二维数组,其类型是char[3][10]k是一个指向包含3个元素的数组的指针,每个元素都是一个字符数组(实际上是char(*)[10]类型)。因此,s的地址可以赋给k,因为k可以指向一个二维数组的首行。

综上所述,正确的赋值语句是p=s[0]; 和k=s;

1.11、有定义语句int *p[4]以下选项中与此语句等价的是     D      

Aint p[4]; B)int **p; C)int *(p[4]); D)int (*p)[4];

解析:int (*p)[4];这个定义声明了一个指针,它指向一个包含4个整数的数组。这与原语句等价,因为原语句也是一个包含4个元素的数组,每个元素都是一个指针。

1.12、若有定语句int a[4][10], *p, *q[4]; 0≤i<4,则错误的赋值       B        

Ap=a  Bq[i]=a[i]  Cp=a[i]  Dp=&a[2][1]

解析:q[i]=a[i];这是错误的。q是一个指向指针的数组,每个元素都是一个指针。而a[i]是一个包含10个整数的数组,不是一个指针。因此,不能将数组a[i]赋值给指针q[i]

1.13、若有以定义

int x[10],*pt=x;

x 数组元的正确应用是     BD     

A*&x[10] B*x+3

3C*pt+10 Dpt+3

解析:*(x+3)这是正确的。x 是一个指向数组第一个元素的指针,所以 x+3 会得到数组中第4个元素的地址。通过解引用这个地址(使用 *),我们可以得到数组中第4个元素的值。

pt+3这是正确的。pt 是一个指向整数的指针,初始时指向数组 x 的第一个元素。pt+3 会得到数组中第4个元素的地址。这个表达式本身并不解引用指针,所以它是安全的。

1.14、有以程序

#include <stdio.h> 

main()

{ int a[ ]={1,2,3,4},y,*p=&a[3];

--p; y=*p; printf(y=%d\n,y);

}

程序的运行结      D       

Ay=0 By=1 Cy=2 Dy=3

解析:程序中有一个整数数组 a,其元素初始化为 {1, 2, 3, 4}。接着,定义了一个整数指针 p,并使其指向数组 a 的最后一个元素(即 a[3]),其值为 4。然后,程序执行了 --p; 操作,这将指针 p 向前移动一个位置,使其指向数组 a 的倒数第二个元素(即 a[2]),其值为 3。接下来,程序执行了 y=*p;,这将指针 p 所指向的值(即 a[2] 的值)赋给了变量 y,因此 y 的值为 3。最后,程序输出了 y 的值,即 y=3。因此,程序的运行结果是 y=3

1.15、设char  *s = “\ta\017bc”;则指针变量s指向的字符串所占的字节数是      C       

   A)  6   B)  2   C)   5   D) 9

解析:给定的字符串是 s = "\ta\017bc";。在这个字符串中,\t 是一个制表符(tab),a 是一个字符,\017 是一个八进制表示的字符(其ASCII值是15,即0x0F或017,但在这个上下文中它不会作为一个结束标志,因为它不是 \0),b 和 c 也是字符。因此,字符串中的字符是:\t(1字节)、a(1字节)、\017(1字节)、b(1字节)、c(1字节)。所以字符串的总字节数是5字节。

1.16、  若有定义语句char s[3][10], (*k)[3], *p;,则以下赋值语句正确的是    CD     

A)p=s; B)p=k; C)p=s[0]; D)k=s;

解析:p=s[0];这是正确的。s[0] 是二维数组 s 的第一个元素,它是一个一维数组(类型为 char[10])。s[0] 的值(即地址)可以被赋给一个字符指针 p,因为 p 可以指向一个字符数组的首地址。

k=s;这是正确的。s 是一个二维数组,其类型是 char[3][10]k 是一个指向包含3个元素的数组的指针,每个元素也是一个数组。因此,s 的地址可以被赋给 k,因为 k 的类型与 s 的类型兼容。

综上所述,正确的赋值语句是p=s[0]; 和k=s;

2、填空题

2.1以下序的输出结果是     6       

#include<stdio.h> 

main()

{ int a[5]={2,4,6,8,10}, *p;

p=a+2;

printf(%d,*p++);

}

解析:定义了一个包含5个整数的数组 a,其初始值为 {2, 4, 6, 8, 10}。接着定义了一个整数指针 p。然后,p=a+2; 这行代码将指针 p 指向数组 a 的第三个元素(索引为2的元素),即值为6的那个元素。接下来,printf(“%d”,*p++); 这行代码做了两件事:1.*p 表示指针 p 当前指向的值,即6。2.p++ 将指针 p 向后移动一个位置,使其指向数组的下一个元素,即值为8的那个元素。但是,由于 p++ 是后自增操作,所以在 printf 函数中使用的仍然是 p 自增之前的值,即指向值为6的那个元素。因此,程序的输出结果是 6

2.2、以下程序段的定义语句中x[1]的初值是  2  ,程序运行后输出的内容是   3  5  7  9  

#include<stdio.h>

main()

{ int x[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},*p[4],i;

for(i=0;i<4;i++)

{ p[i]=&x[2*i+1]; printf(%d ,p[i][0]);

}

printf(\n);

}

解析:当 i=0p[0] 指向 x[1],即 p[0] 的初值是 &x[1],即 x[1] 的地址。当 i=1p[1] 指向 x[3]。当 i=2p[2] 指向 x[5]。当 i=3p[3] 指向 x[7]。因此,程序将输出 3 5 7 9 

2.3  以下段的输出结果是(     rgb      )

#include <sthio.h> 

mian()

{ char *ch[4]={“red”,”green”,”blue”}; int i=0;

while(ch[i]);

{ putchar(ch[i][0]; i++;   }

}

解析:这个程序的目的是输出数组中每个字符串的第一个字符,直到遇到'\0',数组 ch 包含三个字符串:"red", "green", "blue"。每个字符串的第一个字符分别是 'r', 'g', 'b'。因此,程序的输出结果是:rgb

 2.4、以下程序的功能是:借助指针变量找出数组元素中最大值所在的位置并输出该最大值。 请在输出语句中填写代表最大值的输出项。

#include  <stdio.h>  

int   main()

{ int a[10], *p, *s;

for(p=a; p-a<10; p++

scanf(%d, p)

for(p=a,s=a;p-a<10;p++

if(*p>*s) s=p;

printf(max=%d,  序号:%d\n” *s, s - a );

}

解析:printf语句中,*s代表最大值,而s - a代表最大值在数组中的位置(从0开始的索引)。因为a是数组的首地址,s是指向最大值的指针,所以s - a就是最大值在数组中的位置。

2.5 有以下程序,输出结果为    2,5    

      main() 

{  

int a[5]={1,2,3,4,5};    

int *ptr=(int *)(&a+1);    

printf("%d,%d",*(a+1),*(ptr-1)); 

解析:*(a + 1)a是一个数组名,它本身就是一个指针,指向数组的第一个元素。因此,a + 1实际上是指向数组的第二个元素a[1]的地址。通过解引用这个地址,我们得到a[1]的值,即2。

*(ptr - 1):由于ptr指向的是数组a之后的内存位置,ptr - 1实际上是指向数组a的最后一个元素a[4]的地址。通过解引用这个地址,我们得到a[4]的值,即5。

2.6  以下程序的功能是:借助指针变量找出数组元素中最大值所在的位置并输出该最大值。 请在输出语句中填写代表最大值的输出项。

#include <stdio.h> 

int main( )

{ int a[10], *p, *s;

for(p=a;p-a<10; p++

scanf(%d,p);

for(p=a,s=a;p-a<10;p++)

if(*p>*s) s=p;

printf(max=%d\n” , *s );

解析:在 printf 语句中,*s 代表最大值,因为 s 是一个指向数组元素的指针,而 *s 就是该元素的值。这样程序就会输出数组中的最大值

3、编程题

3.1、 有一个整型数组int [10] = {10,20,30,40,50,60,70,80,90,100};标准输入一个整型数值m(0<m<10) ,使前面10-m个数值向后移动m个位置,最后m个数变成前面的m个数

代码:

#include <iostream>
using namespace std;
int main()
{int arr[10]={10,20,30,40,50,60,70,80,90,100};int m;//从标准输入读取一个整型数值mcin >> m;//检查m是否在有效范围内if(m>0&&m<10){//临时数组,用于存储后m个元素int temp[m];//将后m个元素存储到临时数组中for(int i=0;i<m;++i){temp[i]=arr[9-i];}//将前10-m个元素向后移动m个位置for(int i=9;i>=m;--i){arr[i]=arr[i-m];}//将临时数组中的元素放回数组的前m个位置for(int i=0;i<m;++i){arr[i]=temp[i];}//输出移动后的数组for(int i=0;i<10;++i){cout << arr[i] << " ";}cout << endl;}else{cout << "输入的m值不在有效范围内(0 < m < 10)" << endl;}return 0;
}

结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/469159.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【sql】sqlite3数据库

一、介绍 SQLite是一个轻量级的、开源的嵌入式数据库&#xff0c;由D. Richard Hipp使用C语言编写。由于其资源占用少、性能良好和零管理成本的特点&#xff0c;SQLite在嵌入式系统中得到了广泛应用&#xff0c;如Android和iPhone等操作系统中都有内置的SQLite数据库供开发人员…

VueCLI核心知识综合案例TodoList

目录 1 拿到一个功能模块首先需要拆分组件&#xff1a; 2 使用组件实现静态页面的效果 3 分析数据保存在哪个组件 4 实现添加数据 5 实现复选框勾选 6 实现数据的删除 7 实现底部组件中数据的统计 8 实现勾选全部的小复选框来实现大复选框的勾选 9 实现勾选大复选框来…

耳机壳UV树脂制作私模定制耳塞需要注意什么问题?

制作私模定制耳塞需要注意以下问题&#xff1a; 耳模制作&#xff1a;获取准确的耳模是制作私模定制耳塞的关键步骤。需要使用合适的材料和方法&#xff0c;确保耳模的准确性和稳定性。材料选择&#xff1a;选择合适的UV树脂和其它相关材料&#xff0c;确保它们的质量和性能符…

Sentinel 流控-链路模式

链路模式 A B C 三个服务 A 调用 C B 调用 C C 设置流控 ->链路模式 -> 入口资源是 A A、B 服务 package com.learning.springcloud.order.controller;import com.learning.springcloud.order.service.BaseService; import org.springframework.beans.factory.annotatio…

TiDB 在医疗保障信息平台的应用实践

文章介绍了 TiDB 在医疗保障信息平台中的应用。东软医保云应用管理平台通过与 TiDB 联合&#xff0c;成功满足了医疗保障业务中高并发、实时性和复杂查询的要求。在某地市医疗保障信息平台的实践中&#xff0c;TiDB 分布式数据库有效实现了在线交易和实时分析服务&#xff0c;日…

Linux查看日志的几种方法总结

文章目录 摘要1、tailtail命令参数&#xff1a;tail命令的具体例子&#xff1a; catcat 命令的基本用法cat 命令的参数 与其他命令组合使用示例 1&#xff1a;搜索特定文本示例 2&#xff1a;显示匹配行的行号示例 3&#xff1a;忽略大小写搜索示例 4&#xff1a;显示不匹配的行…

vue3+ts+vite+uniapp项目常见问题

vue3tsvite中""路径失效的问题 ""需要进行配置&#xff1a; 首先npm install types/node --save-dev&#xff08;需要用到node其中的path&#xff09;接着在vite.config.ts配置文件中进行配置&#xff1a; 引入 import path from ‘path’&#xff0c;然…

Spring 事务原理总结五

很抱歉&#xff0c;Spring事务本来应该在上一篇就结束的&#xff0c;但因为梳理过程中发现了更多的未知知识&#xff0c;所以便再啰嗦几篇。本篇主要针对前一篇文章——《Spring 事务原理总结四》——末尾提到的几个问题进行梳理&#xff0c;这里再回顾一下这几个问题&#xff…

JavaWeb学习|i18n

学习材料声明 所有知识点都来自互联网&#xff0c;进行总结和梳理&#xff0c;侵权必删。 引用来源&#xff1a;尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版 i18n 国际化&#xff08;Internationalization&#xff09;指的是同一个网站可以支持多种不同的语言&…

数据库从入门到精通(一)数据库基础操作

mysql数据库基础操作 cmd下启动mysql数据库操作命令数据库重要的删除操作数据库增删改查操作插入数据更新数据删除数据查询数据查询指定记录in查询满足指定范围之内的条件记录not in查询不在指定范围之内的条件记录带between and 的范围查询带like的字符匹配查询(d%以d开头,%d以…

如何使用idea连通服务器上的Redis(详细版本)

这里我使用的是阿里云的服务器 打开阿里云的安全组&#xff0c;设置端口为6379 在redis.conf文件中&#xff0c;注释bind 127.0.0.1 将protected-mode设置为no&#xff0c;即关闭保护模式 更改服务器中的防火墙&#xff0c;放行6379端口 # 放行端口 firewall-cmd --zo…

【lesson53】线程控制

文章目录 线程控制 线程控制 线程创建 代码&#xff1a; 运行代码&#xff1a; 强调一点&#xff0c;线程和进程不一样&#xff0c;进程有父进程的概念&#xff0c;但在线程组里面&#xff0c;所有的线程都是对等关系。 错误检查: 传统的一些函数是&#xff0c;成功返回0&…