• 抬起头,继续前进吧,去把这个不完美的故事,变成你成所期望的样子
  • 登山路上我们会放弃很多东西,但这些被我们丢掉在我们登上山顶之际,都会一一回来
  • 不论开发还是逆向,数学水平的高低直接决定了”你的饭碗里有没有肉”
  • 万丈高楼平地起,勿在浮沙筑高台

《C语言程序设计:现代方法》第十二章练习

C 菜鸟 1年前 (2018-09-08) 8451次浏览 已收录 0个评论
[隐藏]

        本篇为菜鸟在学习《C 语言程序设计:现代方法》中第十二章指针和数组时做的练习题,如果有错误或疑问的话,欢迎大家指正~

1、指针声明

假设下列声明是有效的:
int a[] = {5, 15, 34, 54, 14, 2, 52, 72};
int *p = &a[1], *q = &a[5];
(a) *(p+3)的值是多少?
(b) *(q-3)的值是多少?
(c) p-q 的值是多少?
(d) p2、指针算术运算

假设 high、low 和 middle 都是具有相同类型的指针,并且 low 和 high 指向数组元素。下面的语句为什么是不合法的,如何修改它?
middle = (low + high) / 2;
答:*middle = (high – low) / 2;

3、*与++组合

在下列语句执行后,数组 a 的内容会是什么?

#define N 10

int a[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *p = &a[0], *q = &a[N - 1], temp;

while (p < q) {
    temp = *p;
    *p++ = *q;
    *q-- = temp;
}

答:数组 a 的内容为{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};

4、信息反向

(a) 编写程序,用来读一条信息,然后反向显示出这条信息。程序输出格式如下:
Enter a message: Don’t get mad, get even.
Reversal is: .neve teg ,dam teg t’noD
(b) 修改上述程序,用指针来代替整数来跟踪数组中的当前位置
答:

#include <stdio.h>

#define N 100

int main()
{
    char ch, a[N], *p = a;
    printf("Enter a message: ");
    while ((ch = getchar()) != '\n') {
        *p++ = ch;
    }
    *p = '\0';

    printf("Reversal is: ");
    while (p != a) {
        putchar(*--p);
    }
    printf("\n");
    
    return 0;
}

5、回文判定

(a) 编写程序,用来读一条信息,然后检查这条消息是否是回文(信息从左到右的字母和从右到左的字母完全一样):
Enter a message: He lived as a devil, eh?
Palindrom
Enter a message: Madam, I am Adam.
Not a palindrom
忽略所有不是字母的字符。用整型变量来跟踪数组内的位置
(b) 修改上述程序,使用指针来代替整数和数组中的位置
答:

#include <stdio.h>

#define N 100

int main()
{
    char ch, a[N], *p = a;
    int i, count = 0;

    printf("Enter a message: ");
    while ((ch = getchar()) != '\n') {
        if ((ch >= 'A') && (ch <= 'Z')) {
            ch += 32;
        }
        if ((ch >= 'a') && (ch <= 'z')) {
            *p++ = ch;
            count++;
        }
    }

    for (i = 0; i < count; i++) {
        if (*(a + i) != *--p) {
            break;
        }
    }

    if (i == count) {
        printf("Palindrom\n");
    } else {
        printf("Not a palindrom\n");
    }

    return 0;
}

6、栈函数

用指针变量 top_ptr 代替整型变量 top 来重新编写栈函数 make_empty、is_empty 和 is_full。
答:

#define N 10
int a[N], *top_ptr = a;
void make_empty()
{
    top_ptr = a
}

Bool is_empty()
{
    return top_ptr == a;
}

Bool is_full()
{
    return top_ptr == (a + N);
}

7、指针与数组

假设 a 是一维数组而 p 是指针变量。如果刚执行了赋值操作 p = a, 那么由于类型不匹配,下列哪些表达式是不合法的?正确的表达式中,哪些是真(即有非 0 值)?
(a) p == a[0]
(b) p == &a[0]
(c) *p == a[0]
(d) p[0] == a[0]
答:(a)不合法。正确的表达式全部为真

8、简化 1

请利用数组名可以用作指针的事实简化练习 4 中(b)的程序
答:

#include <stdio.h>

#define N 100

int main()
{
    char ch, a[N];
    int count = 0;
    printf("Enter a message: ");
    while((ch = getchar()) != '\n') {
        *(a + count++) = ch;
    }
    *(a + count) = '\0';

    printf("Reversal is: ");
    while(count > 0)) {
        putchar(*(a + --count));
    }
    printf("\n");

    return 0;
}

9、简化 2

请利用数组名可以用作指针的事实简化练习 5 中(b)的程序
答:

#include <stdio.h>

#define N 100

int main()
{
    char ch, a[N], *p = a;
    int i, count = 0;

    printf("Enter a message: ");
    while ((ch = getchar()) != '\n') {
        if ((ch >= 'A') && (ch <= 'Z')) {
            ch += 32;
        }
        if ((ch >= 'a') && (ch <= 'z')) {
            *p++ = ch;
            count++;
        }
    }

    for (i = 0; i < count; i++) {
        if (*(a + i) != *--p) {
            break;
        }
    }

    if (i == count) {
        printf("Palindrom\n");
    } else {
        printf("Not a palindrom\n");
    }

    return 0;
}

10、替换数组下标

用指针的算术运算代替数组的下标来重新编写下列函数。改动尽可能少

int sum_array(int a[], int n)
{
    int i, sum;
    
    sum = 0;
    for (i = 0; i < n; i++) {
        sum += a[i];
    }
    return sum;
}
答:
<pre class="prettyprint linenums" >
int sum_array(int a[], int n)
{
    int *p = a, i, sum;
    
    sum = 0;
    for (i = 0; i < n; i++) {
        sum += *p++;
    }
    return sum;
}

11、搜索元素

编写下列函数:
Bool search(int a[], int n, int key);
a 是要搜寻的数组,n 是数组内元素的数量,而且 key 是搜索键。如果 key 与数组 a 的某个元素匹配了,那么 search 函数必须返回 TRUE,否则返回 FALSE。
要求使用指针算术运算而不是下标来访问数组元素。
答:

#include <stdio.h>

#define N 5
#define TRUE 1
#define FALSE 0

typedef int Bool;

Bool search(int a[], int n, int key);

int main()
{
    int a[N], key, *p;
    Bool result;
    printf("Enter 5 number: ");
    for (p = a; p < a + N; p++) {
        scanf("%d", p);
    }

    printf("Enter the key: ");
    scanf("%d", &key);

    result = search(a, N, key); 

    if (result) {
        printf("The result is True\n");
    } else {
        printf("The result is False\n");
    }

    return 0;
}

Bool search(int a[], int n, int key) {
    int *q;
    for (q = a; q < a + n; q++) {
        if (key == *q) {
            return TRUE;
        }
    }
    return FALSE;
}

12、矩阵

8.2 节有一个代码段是用两个嵌套的 for 循环初始化数组 ident,此数组是用作恒等矩阵。请重新编写这段代码,采用一个指针来逐步访问数组中的元素,且每次一个元素。
提示:因为不能使用 row 和 col 来索引变量,所以不会很容易知道哪里存储 1。但是,可以利用数组的第一个元素必须是 1 这个事实,接着 N 个元素都必须是 0,再接下来的元素
是 1,以此类推。用变量来追踪连续的 0 的数量,并把此变量存储起来。当计数达到 N 时,就是存储 1 的时候了
答:

#include <stdio.h>

#define N 5

int main()
{
    int a[N][N], *p = a[0], count = -1, zeroNumber = 5;
    while (1) {
        if (!((p - a[0]) % 5)) {
            count++;
            if (count == N) {
                break;
            }
        }

        if (zeroNumber == N) {
            *p = 1;
            zeroNumber = 0;
        } else {
            *p = 0;
            zeroNumber++;
        }

        printf("%d", *p++);
        if (!((p - a[0]) % 5)) {
            printf("\n");
        }
    }

    return 0; 
}

13、温度查询

假设下列数组含有一周 24 小时的温度读数,数组的每一行是某一天的读数:
int temperatures[7][24];
编写语句,使用 search 函数在整个 temperatures 数组中寻找值 32
答:search(temperatures[0], (7 * 24), 32);

14、显示温度

编写循环用来显示出 temperatures 数组中行 i 存储的所有温度读数。利用指针来访问该行中的每个元素
答:

for (p = (temperatures[0] + (i - 1) * 24); p < (temperatures[0] + i * 24); p++) {
    printf("%d ", *p);
}

15、最高温度

编写循环来显示出 temperatures 数组一星期中每一天的最高温度。循环体应该调用 find_largest 函数,且一次传递数组的一行
答:

for (i = 0; i < 7; i++) {
    find_largest(temperatures[i], 24, &max);
    printf("%d \n", max);
}

学习心得 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明《C 语言程序设计:现代方法》第十二章练习
喜欢 (2)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址