S1E22 :指针和数组 课后作业

测试题:来自
f+G"p<qy !=}vLK{>9&PBIhTZ@Rm
0. str[3] 用指针法如何表示?

答:*(str + 3)P

答案:*(str + 3)

1. 假设整型指针变量 p 存放的地址值是 0x11008888,那么请问 p + 1,p + 2,p + 4 和 p + 8 的地址分别是?

答:p+1= 0x1100888c   p+2 =0x11008890a   p+4=0x11008898   p+8=0x110088a8

int的存储为32位,4个字节

答案:由于在我们的操作系统中 sizeof(int) == 4,0x 开头表示该地址是 16 进制表示。
于是:Powered

p + 1 == 0x11008888 + 4 == 0x1100888C
p + 2 == 0x11008888 + 8 == 0x11008890
p + 4 == 0x11008888 + 16 == 0x11008898
p + 8 == 0x11008888 + 32 == 0x110088A8

2. 请问 str[20] 是否可以写成 20[str]?

答:不能(错误)

答案:可以,因为在访问数组的元素的时候,数组名被解释为数组第一个元素的地址。JS2?FT
所以 str[20] == *(str + 20) == *(20 + str) == [20]strBJ

3. 你能猜出下边关键代码段是用于干啥的吗?o7B3:eky5+
U

……
while (n-- && (*target2++ = *target1++) != '\0')
……

答:对比两段地址存储的数据是否一致

答案:实现 strncpy 函数的功能(具体实现代码见下方动动手)。Nk)(,a_q:
这道题比较考“经验”了,初学者很难想象出来的(So,想不出来不要泄气,以后看到就晓得~)。

4. 接上一题,请问代码写成下方形式,能否正确实现要求

……
while ((*target2++ = *target1++) != '\0' && n--)
……

答:能实现(错误)

答案:不能。
因为这么做会超出要求 1 个字符(比如要求拷贝 5 个字符,实际拷贝了 6 个),因为代码的逻辑是 *target2++ = *target1++ 先赋值,再判断 n--。

动动手:Powered by 
0. 获取字符串的长度 —— strlen 函数o1h*dKp
基础要求:版权属于
使用 fgets 函数(使用文档 -> 传送门)读取用户输入的字符串(英文),并用指针法来计算字符串的字符个数。&cFrX@ab?'
程序实现如下:来自:

答:'\0'   而非  “\0”

#include <stdio.h>

int main()
{
    char str[1024];
    char *target = str;
    int length = 0;
    
    printf("请输入一个字符串:"); 
    fgets(str,1024,stdin);
    
    while( *target++ != '\0')
    {
        length++;
    }
    printf("总共输入了%d字符!\n",length - 1);
    return 0;
}

答案:
1. 你可能觉得我用一个指针指向数组是有点多此一举,但如果不这么做,程序将报错(不信你试试看~)。
2. 你们可能对 *target++ != '\0' 这一行代码有疑问,这里我给大家解释下。首先在“运算符的优先级和结合性,可以查到自增运算符(++)的优先级比取值运算符(*)要高,所以 *target++ 相当于 *(target++),先执行自增运算符,再取值。但由于这是一个后缀的自增运算符,所以自增的效果要在下一条语句才会生效,因此这里取出来的依然是 target 地址自增前指向的数组元素的值。

#include <stdio.h>

#define MAX 1024

int main()
{
        char str[MAX];
        char *target = str;
        int length = 0;

        printf("请输入一个字符串:");
        fgets(str, MAX, stdin);

        while (*target++ != '\0')
        {
                length++;
        }

        printf("您总共输入了 %d 个字符!\n", length - 1);

        return 0;
}


进阶要求:Powered by 
你可能发现写出来的代码只能统计英文字符的个数,遇到中文字符结果就会出错。请自行观察你当前系统对中文字符的处理方式,并设计一个可以统计中文字符以及中英文混合字符的程序。
程序实现如下:版权属于:

答:我的编译器中,中文字符只占两个字节

#include <stdio.h>

int main()
{
	char str1[100];
	char *target1 = str1;
	int length = 0;
	char ch; 
		
	printf("请输入一个字符串:");
	fgets(str1,100,stdin);
	
	while(*target1++ != '\0')
	{
		ch = *target1;
		if(ch < 0)
		{
			target1 += 1;   //我的编译器中,中文字符只占两个字节 	
		}
		length++;	
	}
	printf("您总共输入了 %d 个字符!\n", length - 1);	
}

答案:答案中,中文字符占了三个字节

#include <stdio.h>

#define MAX 1024

int main()
{
        char str[MAX];
        char *target = str;
        char ch;
        int length = 0;

        printf("请输入一个字符串:");
        fgets(str, MAX, stdin);

        while (1)
        {
                ch = *target++;
                if (ch == '\0')
                {
                        break;
                }
                if ((int)ch < 0)
                {
                        target += 2;
                }
                length++;
        }

        printf("您总共输入了 %d 个字符!\n", length - 1);

        return 0;
}

代码分析:来自:
先用以下代码做个实验:版权属于

#include <stdio.h>

int main()
{
        char str[] = "中";
        int length, i;

        length = sizeof(str) / sizeof(str[0]);

        printf("length of str: %d\n", length);

        for (i = 0; i < length; i++)
        {
                printf("str[%d] = %d\n", i, str[i]);
        }

        return 0;
}

不难发现,每个中文字符在我们的系统中是占用 3 个字节的存储空间,并且都是负数。以此规律,我们只要检测一个字符对应的整型值是否为负数,如果是(中文字符),则将指针往后移动两个字节。

1. 拷贝字符串 —— strcpy 和 strncpy 函数X:O$!
基础要求:来自:
使用 fgets 函数读取用户输入的字符串(英文)并存储到字符数组 str1 中,并利用指针,将 str1 中的字符串拷贝到字符数组 str2 中。`z"0yD
程序实现如下:来自:
[

答:

#include <stdio.h>

int main()
{
    char str1[100];
    char str2[100];
    char *target = str1;
    int length = 0;
    printf("请输入一个字符串到str1z中:");
    fgets(str1,100,stdin);
    printf("\n开始拷贝str1的内容到str2中...");
    while(*target++ != '\0')
    {        
        str2[length] = str1[length];
        length++;
    }
    printf("\n拷贝完毕!现在,str2中的内容是:%s",str2) ;
}

答案:

#include <stdio.h>

#define MAX 1024

int main()
{
        char str1[MAX];
        char str2[MAX];

        char *target1 = str1;
        char *target2 = str2;

        printf("请输入一个字符串到 str1 中:");
        fgets(str1, MAX, stdin);

        printf("开始拷贝 str1 的内容到 str2 中...\n");
        while ((*target2++ = *target1++) != '\0')
                ;

        printf("拷贝完毕!");
        printf("现在,str2 中的内容是:%s", str2);

        return 0;
}

进阶要求:Powered by
Ky(&4X*R7+0<9li5kpmq#J`S
实现 strncpy 函数,让用户输入需要拷贝的字符个数(注意:该程序需要能够正确拷贝中英混合的字符串)。(JTRN]fli
程序实现如下:版权属于:
 

答:中文输入,拷贝字符与用户输入不符(程序有问题,错误

#include <stdio.h>

int main()
{
    char str1[100];
    char str2[100];
    char *target = str1;
    int length = 0;
    printf("请输入一个字符串到str1z中:");
    fgets(str1,100,stdin);
    printf("请输入需要拷贝的字符个数:");
    scanf("%d",&length);
    
    printf("\n开始拷贝str1的内容到str2中...");
    int i = 0;
    while(length--)
    {    
        str2[i] = str1[i];
        i++;
    }
    printf("\n拷贝完毕!现在,str2中的内容是:%s",str2) ;
}

答案:

#include <stdio.h>

#define MAX 1024

int main()
{
        char str1[MAX];
        char str2[MAX];

        char *target1 = str1;
        char *target2 = str2;

        char ch;
        int n;

        printf("请输入一个字符串到 str1 中:");
        fgets(str1, MAX, stdin);

        printf("请输入需要拷贝的字符个数:");
        scanf("%d", &n);

        printf("开始拷贝 str1 的内容到 str2 中...\n");
        while (n--)
        {
               ch = *target2++ = *target1++;
               if (ch == '\0')
               {
                       break;
               }
               if ((int)ch < 0)
               {
                       *target2++ = *target1++;
                       *target2++ = *target1++;
               }
        }

        *target2 = '\0';

        printf("拷贝完毕!\n");
        printf("现在,str2 中的内容是:%s\n", str2);

        return 0;
}

2. 连接字符串 —— strcat 和 strncat 函数`hN=:
基础要求:来自:
使用 fgets 函数接收用户输入的两个字符串到 str1 和 str2 中,将 str2 连接到 str1 后边,并打印出来。uTw+;RKv
程序实现如下:来自


进阶要求:来自
实现 strncat 函数,让用户输入需要连接到 str1 后边的字符个数(注意:该程序需要能够正确拷贝中英混合的字符串)。M!`ml
程序实现如下:版权属于

答:

#include <stdio.h>

int main()
{
	char str1[100];
	char str2[100]; 
	char sum_str[200];
	char *target1 = str1;
	char *target2 = str2;
	char *sum_target = sum_str; 
	int length1 = 0;
	int length2 = 0;
	int length = 0;
	
	printf("请输入第一个字符串:");
	fgets(str1,100,stdin);
	
	printf("请输入第二个字符串:");
	fgets(str2,100,stdin);
	
	while(*target1++ != '\0')
	{
		length1++;
	}
	while(*target2++ != '\0')
	{
		length2++;	
	}
	
	length1 = length1-1; //length1会多一个结束符 
	length2 = length2-1; //length2会多一个结束符 
	
	printf("请输入需要连接的字符个数:");
	scanf("%d",&length); 
	int i,j,k = 0;
	if(length <= length1)  
	{
//		printf("进入length1,length = %d,length1=%d\n",length,length1); 
		while(length--)
		{
			sum_str[i]= str1[i];
			i++; 
		}
	}
	else{
//		printf("进入length2,length = %d,length1=%d,length2=%d\n",length,length1,length2);
		length = length - length1;
		k =  length1;
		while(length1--)
		{
			sum_str[i]= str1[i];
			i++;
		} 
		
		while(length--)
		{
			sum_str[j+k]= str2[j];
			j++;
		}	
	}	
	printf("连接后的结果是:%s",sum_str);	
}

答案:

#include <stdio.h>

#define MAX 1024

int main()
{
        char str1[2 * MAX]; // 确保连接后不越界
        char str2[MAX];

        char *target1 = str1;
        char *target2 = str2;

        char ch;
        int n;

        printf("请输入第一个字符串:");
        fgets(str1, MAX, stdin);

        printf("请输入第二格字符串:");
        fgets(str2, MAX, stdin);

        printf("请输入需要连接的字符个数:");
        scanf("%d", &n);

        // 将指针指向 str1 的末尾处
        while (*target1++ != '\0')
                ;
        // 我们希望 str1 最后边的 '\0' 和 '\n' 都被覆盖掉
        target1 -= 2;

        while (n--)
        {
                ch = *target1++ = *target2++;
                if (ch == '\0')
                {
                        break;
                }
                if ((int)ch < 0)
                {
                        *target1++ = *target2++;
                        *target1++ = *target2++;
                }
        }

        *target1 = '\0';

        printf("连接后的结果是:%s\n", str1);

        return 0;
}

3. 比较字符串 —— strcmp 和 strncmp 函数IF%r1n&g
基础要求:版权属于:
使用 fgets 函数接收用户输入的两个字符串(仅支持英文)到 str1 和 str2 中,对比 str1 和 str2,如果两个字符串完全一致,打印“完全一致”;如果存在不同,打印第一处不同的位置(索引下标)。?^<uDTv*e-
程序实现如下:Powered b
O

答:(参考了答案思路)

#include <stdio.h>

int main()
{
	char str1[100];
	char str2[100]; 
	char *target1 = str1;
	char *target2 = str2;
	int i = 1;
	
	printf("请输入第一个字符串:");
	fgets(str1,100,stdin);
	
	printf("请输入第二个字符串:");
	fgets(str2,100,stdin); 
	
	while(*target1++ !='\0' && *target2++ != '\0')
	{
			i++;
			if(*target1 != *target2)
			{
				break;	
			}					
	} 
	if (*target1 == '\0' && *target2 == '\0')
    {
            printf("两个字符串完全一致!\n");
    }
    else{
    	
    	printf("两个字符串不完全相同,第 %d 个字符出现不同!\n", i);
	}
	return 0;
}

答案:

#include <stdio.h>

#define MAX 1024

int main()
{
        char str1[MAX];
        char str2[MAX];

        char *target1 = str1;
        char *target2 = str2;

        int index = 1;

        printf("请输入第一个字符串:");
        fgets(str1, MAX, stdin);

        printf("请输入第二个字符串:");
        fgets(str2, MAX, stdin);

        while (*target1 != '\0' && *target2 != '\0')
        {
                if (*target1++ != *target2++)
                {
                       break;
                }
                index++;
        }

        if (*target1 == '\0' && *target2 == '\0')
        {
                printf("两个字符串完全一致!\n");
        }
        else
        {
                printf("两个字符串不完全相同,第 %d 个字符出现不同!\n", index);
        }

        return 0;
}


进阶要求:版权属于
实现 strncmp 函数,允许用户指定前 n 个字符进行对比,这一次要求支持中英文混合的字符串比较噢!vt(#ERkrbc
程序实现如下:版权属于
.

答:(参考答案)

#include <stdio.h>

int main()
{
	char str1[100];
	char str2[100]; 
	char *target1 = str1;
	char *target2 = str2;
	int index = 1,num;
	char ch;
	
	printf("请输入第一个字符串:");
	fgets(str1,100,stdin);
	
	printf("请输入第二个字符串:");
	fgets(str2,100,stdin); 
	
	printf("请输入需要对比的字符个数:");
	scanf("%d",&num);
	
	while(*target1++ !='\0' && *target2++ != '\0' && num--)
	{
		ch = *target1;
		index++;
		if(ch < 0)
		{
			if(*target1 != *target2)
			{
				break;
			}
		}	
		
		if(*target1 != *target2)
		{
			break;	
		}			
	}
	
	if ((num == 0) || (*target1 == '\0' && *target2 == '\0'))
    {
            printf("两个字符串的前 %d 个字符完全相同!\n", index);
    }
	else
    {
            printf("两个字符串不完全相同,第 %d 个字符出现不同!\n", index);
    }
    	
     return 0;
	
}

答案:

#include <stdio.h>

#define MAX 1024

int main()
{
        char str1[MAX];
        char str2[MAX];

        char *target1 = str1;
        char *target2 = str2;

        char ch;
        int index = 1, n;

        printf("请输入第一个字符串:");
        fgets(str1, MAX, stdin);

        printf("请输入第二个字符串:");
        fgets(str2, MAX, stdin);

        printf("请输入需要对比的字符个数:");
        scanf("%d", &n);

        while (n && *target1 != '\0' && *target2 != '\0')
        {
                ch = *target1;
                if (ch < 0)
                {
                        if (*target1++ != *target2++ || *target1++ != *target2++)
                        {
                                break;
                        }
                }
                if (*target1++ != *target2++)
                {
                       break;
                }
                index++;
                n--;
        }

        if ((n == 0) || (*target1 == '\0' && *target2 == '\0'))
        {
                printf("两个字符串的前 %d 个字符完全相同!\n", index);
        }
        else
        {
                printf("两个字符串不完全相同,第 %d 个字符出现不同!\n", index);
        }

        return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值