C语言--指针的初始化、运算以及和一维数组、二维数组的关系

1.用变量a给出下面的定义

a) 一个整型数:

b) 一个指向整型数的指针:

c) 一个指向指针的的指针,它指向的指针是指向一个整型数:

d) 一个有10个整型数的数组:

e) 一个指向有 10个整型数数组的指针:

答: a)int a;     b)int *a;     c)int **a;     d)int a[10]      e)int (*a) [10] 

2.在 int a = 3, int *p = &a;中,*p 的值是(D ) 

A.变量 a 的地址值;

B.无意义;

C.变量 p 的地址值;

D.3

分析:定义变量a存放整型数值3,定义整型指针p并存储变量i的存储地址,对p进行解值运算,即为通过a的地址获取a存储数据内容--3;

3.下列定义中,( A)是定义了一个指向数组的指针p

A.int(*p)[7]

B.int *p[7]

C. (int *)p[7]

D. int *p[]

分析:指向数组的指针--说明他的数据类型是整型数组,并且他本身是个指针,即 int (*p)[7];

C是定义了一个数据类型为整形指针的一维数组,B、D都是定义了一个指针数组;

4.有以下说明语句,则正确的赋值语句是( D)

int a[5][5]; int *p, **q;

A. p = a;

B. q = *a;

C. q = a;

D. p = *a;

分析:a[5][5]是一个二维数组,p是一个整型指针,q是一个二级指针;A无法让一个指针指向二维数组的首地址,因为二维数组的首地址是第一行所有元素,B是将一个二级指针指向一个一级指针,这也是不对的;

5.设 char *s1, *s2; 分别指向两个字符串,可以判断字符串 s1 和 s2 是否相等的表达式为(D )

A. s1 = s2

B. s1 == s2

C. strcpy(s1, s2) == 0;

D. strcmp(s1, s2) == 0;

分析:A是赋值运算,很显然不对,B是比较两个字符串的地址,两个字符串即使值相等地址也不相等,除非是一个字符串,只有D是比较两个字符串;

6.求 n 的值。n=__5____

int a[20];

char *p1 = (char *)a;

char *p2 = (char *)(a+5);

int n = p2-p1;

分析:p1指针存储数组a的首地址,即a[0]的地址,p2存储数组a中第6个元素即a[5]的地址,p2-p1是两个指针之间的元素数量,a[5]-a[0]一共有五个元素;

7.若有说明int(*p)[3],以下叙述正确的是(D

A. p是指针数组

B. (*p)[3]和 *p[3]等价

C. p是指向一维数组中任何一个元素的指针

D. p是指向含有3个整形元素的一维数组的指针

分析:int(*p)[3]是定义了一个数据类型为整型数组的指针,而 int *p [3]才是定义一个指针类型的数组,p是指向一维数组的首地址而不是指向任何一个元素;

8.设数组a[5]=(10,20,30,40,50],已知指针p指向a[1],则表达式*++p的值是 (B ) 

A. 31             B. 30          C. 21          D. 20

分析:*++p可以分成两步:①++p ②* (++p),已知p指向a[1],++p是前缀运算符,先自增后赋值,而++指针意味着指向下一元素,然后进行解值运算即为a[2]=30;

9.有以下程序段,执行后,mul的值为( C) 

int a[] = {1, 3, 5, 7, 9};

int mul, *data, x;

mul=1;

data=&a[1];

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

{

    mul *= *(data+x);

}

printf("%d\n", mul);

A. 945            B. 315              C. 105              D. 15

分析:首先data指向的是a[1]的地址,其次是三次for循环,当x=0时,mul=mul* *(data+x);此时第一个*为乘法运算,第二个*为解值运算符,data+0为指向当前元素,即为a[1],mul=1*3=3;当x=1时,mul=3* *(data+1)即为3*5=15;当x=2时,mul = 15* *(data+2)即为15*7=105;

10.在32位计算机系统上,以下代码的输出结果是什么?

int *a;

char *b;

char c[20];

printf("%d, %d, %d", sizeof(a),  sizeof(b), sizeof(c));

答:4,4,20;

分析: 在32位的计算机系统上,不论什么数据类型的指针,内存都只会分配32位即4字节的内存,所以前两个为4,而c是一个数组在初始化时,他申明多少内存就分配多少,所以是20;

11.有以下定义:int a[]={1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10}, *p = a

下列哪个表达式的值为3:( A

A. p += 2, *(p++)             B. p += 2, *++p

C. p += 3, *p++                D. p += 2, ++*p

分析:a是一个一维数组,p指向数组a的首地址,指针的加法运算是指向下几个元素,当p=&a[3]时,解值后的值为3,因此需要p+=2,p++是后缀运算符-先赋值再自增,所以*(p++)是3,而*++p则是先加再赋值,结果为a[4]=4,++*p则是先解值p为3然后++后输出,结果为4;

12.若已定义:int a[6], *p = a, 不能表示 a[1] 地址的表达式是:( C)

A. p+1           B. a+1               C. a++        D. ++p

分析:在一维数组中,p==a==&a[0],所以p+1==a+1都是指向下一元素即为a[1];a++是后缀运算符,先赋值再自增,因此a++仍为a[0];

13.有定义: int x, *p;能使指针变量P指向变量x的语句是:___B_____ 

A. *p=&x;           B. p=&x;           C. *p=x;            D. p=*&x;

14.若有说明int a=2, *p=&a, *q=p;则以下非法的赋值语句是( D)

A. p=q          B. *p=*q          C. a=*q              D. q=a

分析:int *p =&a是指针p指向a的地址,*q=p是用已经初始化的指针给另一个指针赋值,因此q=p,*p=*q=a==2,a=*q,而D是将一个整型变量赋值给指针变量 是不对的;

15.请写出输出结果

int main()

{

    int a[10] = {0};

    int *p = a;

    int *q = &a[6];

    printf("%d\n", q-p);

    printf("%d\n", (int)q - (int)p);

}

答:6  24

 分析:两个指针相减指的是二者之间的元素数量,p指向a[0],q指向a[6],两者之间差6个元素,而第二个输出将指针强制类型转化,此时输出的就是两个地址之间的差值,以字节为单位,6个整型元素在32为计算机系统中占24字节,因此结果为6,24;

16.下面的程序输出的结果是__4____

#include <stdio.h>

int a[] = {0, 2, 4, 6, 8};

main()

{

    int i;

    int *p = a;

    for(i = 0; i < 4; i++) a[i] = *p++;

    printf("%d\n", a[2]);

}

分析:因为p++是后缀运算符--先赋值再自增,所以a[i]=*p++实质上是a[i]=p[i],因此当i=2

时,a[2]=p[2]=4;

17.数组声明为:short a[3][4],引用第3行第1列的元素写作___a_____

a. **(a+2)           b. *(*a+2)               c. a[3][1]          d. *(a[3]+1)

分析:指针变量指向的是第一行的所有元素,而a+2指的是指向下两行即第三行,然后对第三行再次解值就是第三行的第一列元素,所以为**(a+2);而*(*a+2)是第一行第三列;

18.指针变量p1和p2类型相同,要使p1,p2指向同一个变量,正确的是___a_____。

a. p2=*&p1               b. p2=**p1            c. p2=&p1              d. p2=*p1

分析:因为*与&互为逆运算,二者相互抵消,使得p2和p1指向一个变量

19.下列哪个引用是不正确的? (  ACD

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

A. a[p-a];     B. *(&a)    C. p;    D. *(*(a+1));

分析:p-a是要用一个指针变量减一个数组名,显然不合法;p只是一个指针,引用也不合法;*(a+1)=a[1],而*(*(a+1))无法再进一步解值;

20.下面程序的结果是多少? 

p1=(unsigned char *)0x801000;

p2=(unsigned long *)0x810000;

请问:

p1+5=

p2+5=

分析:因为char类型所占字节为1,因此p1+5十六进制为0x801005,转为十进制就是8392709;

而long类型占4个字节,因此p2+5十六进制为0x810000+5*4=0x8010014,转为十进制为8454164;

21.请写出以下程序输出内容。(小端环境) 

void main()

{

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

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

    int *p2 = (int *)((char *)a + 1);

    printf("0x%x, 0x%x", *(p1-1), *p2);

}

答:0x02 00 00 00

22.用 C 语言编程,向内存0xff9527地址上存入一个整型数0x123 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
    // 声明一个指向整型的指针,并将其指向特定的内存地址
    int *ptr = (int *)0xff9527; 
    // 向该地址写入整型数 0x123
    *ptr = 0x123;
    // 打印出写入的值以验证
    printf("Value at 0xff9527: 0x%x\n", *ptr);
    return 0;
}

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值