现在的位置: 首页 > 09 字符串和指针 > 正文

二级程序设计题高频考点:选择性复制数组和字符串

2013年09月01日 09 字符串和指针 ⁄ 共 144字 ⁄ 字号 二级程序设计题高频考点:选择性复制数组和字符串已关闭评论

选择性复制数组和字符串在全国二级C分值高达24分的程序设计题中屡见不鲜。

【问题:复制数组】

函数的功能:将数组s(长度为n)的所以元素复制到数组t,返回复制的元素的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
int copy_array(int s[], int t[], int n)
{
    int i, j=0;
    for (i=0; i<n; i++)
        t[j++] = s[i];
    return j;
}
 
int main()
{
    int s[6] = {3,6,9,11,18,20}, t[6];
    int i, n;
    n = copy_array(s, t, 6);
    for (i=0; i<n; i++)
        printf("%5d",t[i]);
    printf("\n");
    return 0;
}

最简单的版本

1
2
3
4
5
6
7
8
#include <stdio.h>
int copy_array(int s[], int t[], int n)
{
    int i;
    for (i=0; i<n; i++)
        t[i] = s[i];
    return n;
}

如果数组 t 不用下标 i,而是使用和 i 完全一样的变量 j

1
2
3
4
5
6
7
int copy_array(int s[], int t[], int n)
{
    int i, j;
    for (i=0, j=0; i<n; i++, j++)
        t[j] = s[i];
    return n;
}

再改变一下变量 j 的位置,并根据后缀向后移的原则,可以获得下面的程序

1
2
3
4
5
6
7
int copy_array(int s[], int t[], int n)
{
    int i, j=0;
    for (i=0; i<n; i++)
        t[j++] = s[i];
    return j;
}

【问题:有选择的复制数组 】

函数的功能:将数组s(长度为n)中的偶数依次复制到数组t,返回复制的元素个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
int copy_array(int s[], int t[], int n)
{
    int i, j=0;
    for (i=0; i<n; i++)
        if (s[i]%2==0)
            t[j++] = s[i];
    return j;
}
 
int main()
{
    int s[6] = {3,6,9,11,18,20}, t[6];
    int i, n;
    n = copy_array(s, t, 6);
    for (i=0; i<n; i++)
        printf("%5d",t[i]);
    printf("\n");
    return 0;
}

函数的功能:删除数组s(长度为n)中的奇数,返回剩余元素的个数。

分析:删除奇数,就是保留偶数,或者说将数组s中的所有偶数复制到数组s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
int copy_array(int s[], int n)
{
    int i, j=0;
    for (i=0; i<n; i++)
        if (s[i]%2==0)
            s[j++] = s[i];
    return j;
}
 
int main()
{
    int s[6] = {3,6,9,11,18,20}, t[6];
    int i, n;
    n = copy_array(s, 6);
    for (i=0; i<n; i++)
        printf("%5d",s[i]);
    printf("\n");
    return 0;
}

如果是字符串,就不需要在函数中传递字符串的长度,因为可以直接根据'\0'标记来判断字符串的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int string_length(char s[])
{
    int i, n=0;
    for (i=0; s[i]!='\0'; i++)
        n++;
    return n;
}
 
int main()
{
    char s[10] = "abcdefgh";
    printf("%d\n", sizeof(s));
    printf("%d\n",string_length(s));
    return 0;
}

在这个例子中,给字符串预先分配的空间是10,实际使用的空间是8,其中8个字符,一个结束标记'\0'。预先分配的空间可以用sizeof求得,字符串的长度可以使用库函数strlen计算。本例提供了strlen的一种实现方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int string_length(char s[])
{
    int n=0;
    while (*s!='\0') {
    	n++; s++;
    }
    return n;
}
或者
int string_length(char s[])
{
    int n=0;
    for ( ;*s!='\0'; s++)
    	n++;    
    return n;
}

采用地址算术运算的方式

1
2
3
4
5
6
7
int strlen(char *s)
{
    char *p = s;
    while (*p != '\0')
        p++;
    return p - s;
}

【问题:字符串的复制】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
void string_copy(char s[], char t[])
{
    int i;
    for (i=0; s[i]!='\0'; i++)
        t[i] = s[i];
    t[i]='\0';
}
 
int main()
{
    char a[10] = "abcdefgh", b[10];
    string_copy(a, b);
    printf("%s\n", b);
    return 0;
}

如果递增的不是i,而是s,则程序如下:

1
2
3
4
5
6
7
void string_copy(char s[], char t[])
{
    int i;
    for (i=0; *s!='\0'; s++)
        t[i++] = *s;
    t[i]='\0';
}

如果t也采取地址递增的方式

1
2
3
4
5
6
7
#include <stdio.h>
void string_copy(char s[], char t[])
{
    for (; *s!='\0'; s++)
        *(t++) = *s;
    *t='\0';
}

再来欣赏一下库函数中的字符串复制函数是怎么实现的:

1
2
3
4
5
6
void strcpy(char *s, char *t)
{
    while ((*s = *t) != '\0') {
        s++;    t++;
    }
}

将递增合并到运算中,得到

1
2
3
4
5
void strcpy(char *s, char *t)
{
    while ((*s++ = *t++) != '\0')
        ;
}

和'\0'比较是多余的

1
2
3
4
5
void strcpy(char *s, char *t)
{
    while (*s++ = *t++)
        ;
}
1
 

抱歉!评论已关闭.