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

      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 dio.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 

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

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  

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    

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  

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使前面10-m个数值向后移动m个位置,最后m个数变成前面的m个数

代码:

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

结果:

你可能感兴趣的:(c语言,算法,开发语言)