测试题:来自
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;
}