内容正文:
8.1与8.2节:指针的基本概念、指针变量的使用与指针运算
一、单项选择题
1.以下关于计算机内存地址的描述,错误的是( )
A. 每个内存单元有唯一的地址编号
B. 地址是访问内存数据的依据
C. 不同数据类型的变量占用相同字节数的内存
D. 地址由硬件和操作系统共同管理
【答案】C
【解析】不同数据类型变量占用的内存字节数不同(如int通常4字节,char1字节),C错误。
2.定义一个指向int类型变量的指针变量,正确的语法是( )
A. int p; B. int *p; C. *int p; D. int &p;
【答案】B
【解析】指针变量定义格式为类型名 *指针变量名。
3.若int a = 10; int *p = &a;,则*p + 5的结果是( )
A. 10 B. 15 C. 地址值+5 D. 语法错误
【答案】B
【解析】*p等价于a(值为10),10 + 5 = 15,B正确。
4.若char c = 'A'; char *pc = &c;,则printf("%c",*pc);的值是( )
A. 'A'的ASCII码(65) B. 字符'A' C. c的地址 D. 语法错误
【答案】B
【解析】*pc解引用后是c的值,即字符'A'。
5.若int a = 10, b = 20; int *p = &a, *q = &b;,执行p = q;后,*p的值是( )
A. 10 B. 20 C. a的地址 D. b的地址
【答案】B
【解析】p = q后,p指向b,*p即b的值20,B正确。
6.执行以下代码的输出结果是( )
#include <stdio.h>
int main() {
int a = 5;
int *p = &a;
printf("%d", *p++);
return 0; }
A. 5 B. 6 C. 地址值 D. 语法错误
【答案】A
【解析】*p++等价于*(p++),先解引用p得到a的值5,再让p自增(指向下一个int位置),输出5,A正确。
7.若double d = 3.14; double *pd = &d;,则pd + 1移动的字节数是( )
A. 1 B. 4 C. 8 D. 16
【答案】C
【解析】double类型占8字节,pd + 1移动步长为sizeof(double)=8字节,C正确。
8.以下代码中,p和q的关系是( )
int a = 10;int *p = &a;int *q = p;
A. p和q指向不同的内存 B. p和q指向相同的内存
C. p是q的副本,但指向不同 D. 语法错误
【答案】B
【解析】q = p后,q存储的地址与p相同,即指向同一个变量a,B正确。
9.设有代码:int x=20, *p=&x;,修改 x 的值,写法错误的是( )
A. x=30; B. *p=30; C. p=30; D. *(&x)=30;
【答案】C
【解析】p 存储地址,不能直接赋值整数 30;其余写法均可修改 x 存储的数据。
10.以下指针初始化方式中属于 “定义同时赋值”的一项是( )
A. int a; int *p; p=&a; B. int a, *p=&a;
C. int *p; p=NULL; D. int *p; p=p+1;
【答案】B
【解析】定义变量时直接赋值地址为定义同时初始化;A、C 为先定义后赋值。
二、填空题。
1.定义一个指向float类型变量的指针变量pf,语句为:___________。
【答案】float *pf;
【解析】指针变量定义格式为类型名 *指针变量名;。
2.若int a = 20; int *pa = &a;,则*pa的值是___________。
【答案】20
【解析】*pa解引用后等价于a,值为20。
3.空指针常量在C语言中通常用宏___________表示,其值为0。
【答案】NULL
【解析】NULL是标准库定义的空指针宏,通常为(void*)0。
4.解引用运算符是___________,取地址运算符是___________。
【答案】* &
【解析】*用于解引用(访问指针指向的内容),&用于取变量地址。
5.若char c = 'B'; char *pc = &c;,则*pc的ASCII码值是___________。
【答案】66
【解析】字符'B'的ASCII码为66,*pc等价于c,其数值为66。
6.若int a = 15; int *p = &a;,执行(*p)++;后,a的值是___________。
【答案】16
【解析】(*p)++先解引用p得到a,再对a自增,故a变为16。
7.指针变量p指向int类型变量,若p的当前地址为0x1000,则p + 2的地址为___________(假设int占4字节,十六进制表示)。
【答案】0x1008
【解析】p + 2移动步长为2 × sizeof(int) = 8字节,0x1000 + 8 = 0x1008。
8.若int a = 12; int *p = &a;,则*&a的值是___________。
【答案】12
【解析】*&a先取a的地址再解引用,等价于a,值为12。
9.int m=9, *p=&m;修改 m 的值,可写___________p=99;。
【答案】*
【解析】*p 访问 m 对应内存,赋值修改原始数据。
10.int a=5,b=8; int *p1=&a,*p2=&b;表达式p2-p1代表两个地址间________个数。
【答案】int 型元素
【解析】指针相减结果单位为指向类型的元素数量,不是字节。
三、阅读程序题。
1.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main()
{ int a = 100;
int *p;
p = &a;
*p = 200;
printf("%d", a);
return 0; }
【答案】200
2.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main()
{ int num = 8;
int *p = #
printf("%d", &*p == &num);
return 0;}
【答案】1
3.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main()
{ int a = 6;
int *p = &a;
*p = *p + 4;
printf("%d", a);
return 0; }
【答案】10
4.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int x = 5;
int *ptr = &x;
int y;
y = (*ptr)++;
printf("x=%d, y=%d
", x, y);
return 0;}
【答案】x=6, y=5
5.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 10;
int *p = NULL;
if (p && *p > 5) printf("True ");
else printf("False ");
p = &a;
if (p && *p > 5)
printf("Yes ");
return 0; }
【答案】False Yes
6.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 30;
int *p = &a;
int sum = 0;
int i;
for(i = 0; i < 3; i++) {
if (i == 0) p = &a;
if (i == 1) p = &b;
if (i == 2) p = &c;
sum += *p; }
printf("%d
", sum);
return 0;}
【答案】60
7.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 5, b = 10;
int *p1 = &a, *p2 = &b;
int *temp;
temp = p1;
p1 = p2;
p2 = temp;
printf("%d, %d
", a, b);
return 0; }
【答案】5, 10
8.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 5;
int *p = &a;
*p += 2;
a = *p + 3;
*p = *p + a;
printf("%d
", a);
return 0; }
【答案】20
9.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int x = 5;
int *p = &x;
while (*p > 0) {
(*p)--;
}
printf("Final: %d
", x);
return 0;}
【答案】Final: 0
10.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int target = 0;
int *p = ⌖
int k;
for (k = 0; k < 5; k++) {
*p += k;
if (k == 2) {
*p = 0;
}
}
printf("%d
", target);
return 0; }
【答案】7
四、程序填空题(根据题意,将空缺的语句补上)
1.下列程序的功能是:定义三个整型变量 a, b, c 并初始化。定义三个整型指针 p1, p2, p3 分别指向这三个变量。通过交换指针的指向,使得按 p1 -> p2 -> p3 的顺序解引用后,数值呈现从小到大排列。最后输出排序后的结果。
#include <stdio.h>
int main() {
int a, b, c;
___________①_________
int *temp_ptr;
printf("请输入三个整数 (空格分隔): ");
scanf("%d %d %d", &a, &b, &c);
p1 = &a;
p2 = &b;
p3 = &c;
if (*p1 > *p2) { temp_ptr = p1; p1 = p2; p2 = temp_ptr; }
if (_______②_______) { temp_ptr = p1; p1 = p3; p3 = temp_ptr; }
if (*p2 > *p3) { temp_ptr = p2; p2 = p3; p3 = temp_ptr; }
printf("排序结果: %d, %d, %d
",________③________);
printf("原变量值: a=%d, b=%d, c=%d
", a, b, c);
return 0; }
【答案】①int *p1, *p2, *p3; ②*p1 > *p3 ③*p1, *p2, *p3
2.下列程序的功能是:使用指针对x、y变量的值进行交换。
#include <stdio.h>
int main() {
int x = 100, y = 200;
int *px = &x;
int *py = &y;
int temp;
printf("交换前: x=%d, y=%d
", x, y);
________①_______
*px = *py;
________②_______
printf("交换后: x=%d, y=%d
", x, y);
return 0; }
【答案】①temp = *px; ②*py = temp;
3.下列程序的功能是:定义两个正整数。定义两个指针指向它们,仅通过指针解引用获取数值,利用辗转相除法(欧几里得算法)求出这两个数的最大公约数并输出。
#include <stdio.h>
int main() {
int m = 48, n = 18;
int *pm = &m, *pn = &n;
int remainder;
while (________①_______) {
remainder = ________②_______
*pm = *pn;
*pn = _______③_______
}
printf("%d
", *pm);
return 0;
}
【答案】①*pn != 0 ②*pm % *pn; ③remainder;
4.下列程序的功能是:定义一个三位整数。定义一个指针指向它。通过指针解引用获取该数值,并利用数学运算分离出百位、十位、个位,分别存入三个新的变量中并输出。
#include <stdio.h>
int main() {
int num = 456;
int *p = #
int hundred, ten, one;
hundred = ________①_______;
ten = ________②________;
one = _______③______;
printf("%d %d %d
", hundred, ten, one);
return 0;
}
【答案】①*p / 100 ②(*p % 100) / 10 ③*p % 10
5.下列程序的功能是使用指针实现“动态选择求和或求积”
#include <stdio.h>
int main() {
int a = 6, b = 7, result;
int *pa = &a, *pb = &b, *pres = &result;
char op = '*';
char *pop = &op;
if (*pop == '+') {
_________①________
}
else if (*pop == '*') {
_________②_________
}
printf("Result: %d
", *pres);
return 0;
}
【答案】①*pres = *pa + *pb; ②*pres = *pa * *pb;
五、编程题。
1. 指针实现“牛顿迭代法”求平方根:求整数 25 的平方根(保留整数部分)。定义一个双精度浮点数变量 x 初始化为 25.0,定义一个指针 px 指向它。利用牛顿迭代公式 x = (x + 25/x) / 2,通过指针 px 进行迭代,直到前后两次迭代的差值小于 0.00001。
【参考代码】
#include <stdio.h>
#include <math.h>
int main() {
double x = 25.0, prev;
double *px = &x;
do {
prev = *px;
*px = (*px + 25.0 / *px) / 2.0;
} while (fabs(*px - prev) > 0.00001);
printf("Sqrt(25) is approx: %d
", (int)*px);
return 0;
}
2.指针实现“二进制位统计”:定义一个整数 num = 13(二进制为 1101)。定义一个指针 pnum 指向它。通过指针解引用获取数值,利用位运算(& 1 和 >> 1)统计该数二进制表示中 1 的个数并输出。
【参考代码】
#include <stdio.h>
int main() {
int num = 13;
int *pnum = #
int count = 0, temp;
int *ptemp = &temp;
*ptemp = *pnum;
while (*ptemp > 0) {
if (*ptemp & 1) count++;
*ptemp >>= 1;
}
printf("Count of 1s: %d
", count);
return 0;
}
3.指针实现“判断阿姆斯特朗数”:判断 153 是否为阿姆斯特朗数(1³ + 5³ + 3³ = 153)。定义变量 num=153 和指针 pnum 指向它。通过指针获取数值,分离各位并计算立方和,最后将结果与原数通过指针比较。
【参考代码】
#include <stdio.h>
int main() {
int num = 153;
int *pnum = #
int temp, digit, sum = 0;
int *ptemp = &temp, *psum = ∑
*ptemp = *pnum;
while (*ptemp > 0) {
digit = *ptemp % 10;
*psum += digit * digit * digit;
*ptemp /= 10;
}
if (*psum == *pnum) printf("1
");
else printf("0
");
return 0;
}
4.指针实现“阶乘累加(1! + 2! + ... + n!)”:计算 1! + 2! + 3! + 4! + 5! 的和。定义变量 n=5, fact=1, sum=0,以及对应的指针 pn, pfact, psum。在循环中,通过指针完成阶乘的递推计算(fact = fact * i)和累加。
【参考代码】
#include <stdio.h>
int main() {
int n = 5, fact = 1, sum = 0;
int *pn = &n, *pfact = &fact, *psum = ∑
int i;
for (i = 1; i <= *pn; i++) {
*pfact *= i;
*psum += *pfact;
}
printf("Sum of factorials: %d
", *psum);
return 0;
}
5.指针实现求GCD与LCM:定义两个整数 a=12, b=18,以及两个结果变量 gcd, lcm。定义四个指针 pa, pb, pgcd, plcm 分别指向它们。求出GCD后,直接通过 *pgcd 和 *plcm 写入结果,最后通过指针输出。
【参考代码】
#include <stdio.h>
int main() {
int a = 12, b = 18, gcd, lcm;
int *pa = &a, *pb = &b, *pgcd = &gcd, *plcm = &lcm;
int m, n, r;
int *pm = &m, *pn = &n, *pr = &r;
*pm = *pa;
*pn = *pb;
while (*pn != 0) {
*pr = *pm % *pn;
*pm = *pn;
*pn = *pr;
}
*pgcd = *pm;
*plcm = (*pa * *pb) / (*pgcd);
printf("GCD: %d LCM: %d
", *pgcd, *plcm);
return 0;
}
原创精品资源学科网独家享有版权,侵权必究!
学科网(北京)股份有限公司
$
8.1与8.2节:指针的基本概念、指针变量的使用与指针运算
一、单项选择题
1.以下关于计算机内存地址的描述,错误的是( )
A. 每个内存单元有唯一的地址编号
B. 地址是访问内存数据的依据
C. 不同数据类型的变量占用相同字节数的内存
D. 地址由硬件和操作系统共同管理
2.定义一个指向int类型变量的指针变量,正确的语法是()
A. int p; B. int *p; C. *int p; D. int &p;
3.若int a = 10; int *p = &a;,则*p + 5的结果是()
A. 10 B. 15 C. 地址值+5 D. 语法错误
4.若char c = 'A'; char *pc = &c;,则printf("%c",*pc);的值是()
A. 'A'的ASCII码(65) B. 字符'A' C. c的地址 D. 语法错误
5.若int a = 10, b = 20; int *p = &a, *q = &b;,执行p = q;后,*p的值是()
A. 10 B. 20 C. a的地址 D. b的地址
6.执行以下代码的输出结果是()
#include <stdio.h>
int main() {
int a = 5;
int *p = &a;
printf("%d", *p++);
return 0; }
A. 5 B. 6 C. 地址值 D. 语法错误
7.若double d = 3.14; double *pd = &d;,则pd + 1移动的字节数是()
A. 1 B. 4 C. 8 D. 16
8.以下代码中,p和q的关系是()
int a = 10;int *p = &a;int *q = p;
A. p和q指向不同的内存 B. p和q指向相同的内存
C. p是q的副本,但指向不同 D. 语法错误
9.设有代码:int x=20, *p=&x;,修改 x 的值,写法错误的是()
A. x=30; B. *p=30; C. p=30; D. *(&x)=30;
10.以下指针初始化方式中属于 “定义同时赋值”的一项是()
A. int a; int *p; p=&a; B. int a, *p=&a;
C. int *p; p=NULL; D. int *p; p=p+1;
二、填空题。
1.定义一个指向float类型变量的指针变量pf,语句为:___________。
2.若int a = 20; int *pa = &a;,则*pa的值是___________。
3.空指针常量在C语言中通常用宏___________表示,其值为0。
4.解引用运算符是___________,取地址运算符是___________。
5.若char c = 'B'; char *pc = &c;,则*pc的ASCII码值是___________。
6.若int a = 15; int *p = &a;,执行(*p)++;后,a的值是___________。
7.指针变量p指向int类型变量,若p的当前地址为0x1000,则p + 2的地址为___________(假设int占4字节,十六进制表示)。
8.若int a = 12; int *p = &a;,则*&a的值是___________。
9.int m=9, *p=&m;修改 m 的值,可写___________p=99;。
10.int a=5,b=8; int *p1=&a,*p2=&b;表达式p2-p1代表两个地址间________个数。
三、阅读程序题。
1.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main()
{ int a = 100;
int *p;
p = &a;
*p = 200;
printf("%d", a);
return 0; }
2.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main()
{ int num = 8;
int *p = #
printf("%d", &*p == &num);
return 0;}
3.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main()
{ int a = 6;
int *p = &a;
*p = *p + 4;
printf("%d", a);
return 0; }
4.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int x = 5;
int *ptr = &x;
int y;
y = (*ptr)++;
printf("x=%d, y=%d
", x, y);
return 0;}
5.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 10;
int *p = NULL;
if (p && *p > 5) printf("True ");
else printf("False ");
p = &a;
if (p && *p > 5)
printf("Yes ");
return 0; }
6.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 30;
int *p = &a;
int sum = 0;
int i;
for(i = 0; i < 3; i++) {
if (i == 0) p = &a;
if (i == 1) p = &b;
if (i == 2) p = &c;
sum += *p; }
printf("%d
", sum);
return 0;}
7.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 5, b = 10;
int *p1 = &a, *p2 = &b;
int *temp;
temp = p1;
p1 = p2;
p2 = temp;
printf("%d, %d
", a, b);
return 0; }
8.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int a = 5;
int *p = &a;
*p += 2;
a = *p + 3;
*p = *p + a;
printf("%d
", a);
return 0; }
9.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int x = 5;
int *p = &x;
while (*p > 0) {
(*p)--;
}
printf("Final: %d
", x);
return 0;}
10.写出下列程序段的输出结果:________________。
#include <stdio.h>
int main() {
int target = 0;
int *p = ⌖
int k;
for (k = 0; k < 5; k++) {
*p += k;
if (k == 2) {
*p = 0;
}
}
printf("%d
", target);
return 0; }
四、程序填空题(根据题意,将空缺的语句补上)
1.下列程序的功能是:定义三个整型变量 a, b, c 并初始化。定义三个整型指针 p1, p2, p3 分别指向这三个变量。通过交换指针的指向,使得按 p1 -> p2 -> p3 的顺序解引用后,数值呈现从小到大排列。最后输出排序后的结果。
#include <stdio.h>
int main() {
int a, b, c;
___________①_________
int *temp_ptr;
printf("请输入三个整数 (空格分隔): ");
scanf("%d %d %d", &a, &b, &c);
p1 = &a;
p2 = &b;
p3 = &c;
if (*p1 > *p2) { temp_ptr = p1; p1 = p2; p2 = temp_ptr; }
if (_______②_______) { temp_ptr = p1; p1 = p3; p3 = temp_ptr; }
if (*p2 > *p3) { temp_ptr = p2; p2 = p3; p3 = temp_ptr; }
printf("排序结果: %d, %d, %d
",________③________);
printf("原变量值: a=%d, b=%d, c=%d
", a, b, c);
return 0; }
2.下列程序的功能是:使用指针对x、y变量的值进行交换。
#include <stdio.h>
int main() {
int x = 100, y = 200;
int *px = &x;
int *py = &y;
int temp;
printf("交换前: x=%d, y=%d
", x, y);
________①_______
*px = *py;
________②_______
printf("交换后: x=%d, y=%d
", x, y);
return 0; }
3.下列程序的功能是:定义两个正整数。定义两个指针指向它们,仅通过指针解引用获取数值,利用辗转相除法(欧几里得算法)求出这两个数的最大公约数并输出。
#include <stdio.h>
int main() {
int m = 48, n = 18;
int *pm = &m, *pn = &n;
int remainder;
while (________①_______) {
remainder = ________②_______
*pm = *pn;
*pn = _______③_______
}
printf("%d
", *pm);
return 0;
}
4.下列程序的功能是:定义一个三位整数。定义一个指针指向它。通过指针解引用获取该数值,并利用数学运算分离出百位、十位、个位,分别存入三个新的变量中并输出。
#include <stdio.h>
int main() {
int num = 456;
int *p = #
int hundred, ten, one;
hundred = ________①_______;
ten = ________②________;
one = _______③______;
printf("%d %d %d
", hundred, ten, one);
return 0;
}
5.下列程序的功能是使用指针实现“动态选择求和或求积”
#include <stdio.h>
int main() {
int a = 6, b = 7, result;
int *pa = &a, *pb = &b, *pres = &result;
char op = '*';
char *pop = &op;
if (*pop == '+') {
_________①________
}
else if (*pop == '*') {
_________②_________
}
printf("Result: %d
", *pres);
return 0;
}
五、编程题。
1. 指针实现“牛顿迭代法”求平方根:求整数 25 的平方根(保留整数部分)。定义一个双精度浮点数变量 x 初始化为 25.0,定义一个指针 px 指向它。利用牛顿迭代公式 x = (x + 25/x) / 2,通过指针 px 进行迭代,直到前后两次迭代的差值小于 0.00001。
2.指针实现“二进制位统计”:定义一个整数 num = 13(二进制为 1101)。定义一个指针 pnum 指向它。通过指针解引用获取数值,利用位运算(& 1 和 >> 1)统计该数二进制表示中 1 的个数并输出。
3.指针实现“判断阿姆斯特朗数”:判断 153 是否为阿姆斯特朗数(1³ + 5³ + 3³ = 153)。定义变量 num=153 和指针 pnum 指向它。通过指针获取数值,分离各位并计算立方和,最后将结果与原数通过指针比较。
4.指针实现“阶乘累加(1! + 2! + ... + n!)”:计算 1! + 2! + 3! + 4! + 5! 的和。定义变量 n=5, fact=1, sum=0,以及对应的指针 pn, pfact, psum。在循环中,通过指针完成阶乘的递推计算(fact = fact * i)和累加。
5.指针实现求GCD与LCM:定义两个整数 a=12, b=18,以及两个结果变量 gcd, lcm。定义四个指针 pa, pb, pgcd, plcm 分别指向它们。求出GCD后,直接通过 *pgcd 和 *plcm 写入结果,最后通过指针输出。
原创精品资源学科网独家享有版权,侵权必究!
学科网(北京)股份有限公司
$