提问人:Dylan Girrens 提问时间:10/19/2023 更新时间:10/19/2023 访问量:69
为什么在这种情况下,p+1 不会产生与 p++ 相同的结果?
Why does p+1 not produce the same result as p++ in this scenario?
问:
提示:编写以下函数: void get_extension(char *file_name, char *extension); file_name指向包含文件名的字符串。该函数应存储扩展 在字符串 poinLed to 中的文件名上,通过扩展名。例如,如果文件名 是 memo.txt,该函数会将“txt”存储在扩展指向的字符串中。如果 文件名没有扩展名,函数应存储一个空字符串(单个 null 字符)。
//Version 1
#include <stdio.h>
#include <stdlib.h>
void get_extension(char *file_name, char* extension);
int main(){
char file_name[1000], extension[10];
printf("Enter file name: ");
scanf("%s", file_name);
get_extension(file_name, extension);
printf("%s", extension);
return 0;
}
void get_extension(char *file_name, char *extension){
char *p;
for(p = file_name; *p != '.'; p++);
for(p++; *p != '\0'; p++, extension++){ //only difference between V1 and V2
*extension = *p;
}
*extension = '\0';
}
//Version 2
#include <stdio.h>
#include <stdlib.h>
void get_extension(char *file_name, char* extension);
int main(){
char file_name[1000], extension[10];
printf("Enter file name: ");
scanf("%s", file_name);
get_extension(file_name, extension);
printf("%s", extension);
return 0;
}
void get_extension(char *file_name, char *extension){
char *p;
for(p = file_name; *p != '.'; p++);
for(p+1; *p != '\0'; p++, extension++){ // only difference between V1 and V2
*extension = *p;
}
*extension = '\0';
}
为什么版本 1 有效而版本 2 不起作用?我知道这与 p+1 和 p++ 有关。
答:
0赞
NoDakker
10/19/2023
#1
“for”循环 (p+1) 中的初始化步骤实际上没有执行内存位置的任何增量。它只是计算到某个数值。第一个线索可能是编译器警告,例如我在编译程序时收到的警告。
/home/craig/C_Programs/Console/FileExtension/main.c|44|warning: statement with no effect [-Wunused-value]|
我的猜测是,您在编译程序的“版本 2”时也收到了该警告。
考虑到这一点,我构建了一个混合版本的程序来调用两个版本的“get_extension”函数,以便比较输出数据,并希望为您澄清正在发生的事情。下面是程序的重构版本,允许调用函数的两个版本。
#include <stdio.h>
#include <stdlib.h>
void get_extension(char *file_name, char* extension);
void get_extension2(char *file_name, char* extension);
int main()
{
char file_name[1000], extension[10];
printf("Enter file name: ");
scanf("%s", file_name);
get_extension(file_name, extension);
printf("Extension is %s\n", extension);
get_extension2(file_name, extension);
printf("Extension is %s\n", extension);
return 0;
}
void get_extension(char *file_name, char *extension)
{
char *p;
for(p = file_name; *p != '.'; p++); /* Starting at the beginning character array memory location, increment until the "." character is reached */
for(p++; *p != '\0'; p++, extension++) /* The file character array pointer is in effect incremented, and then incremented in synch with the extension pointer */
{
printf("p in first function is.: %p\n", p);
*extension = *p;
}
*extension = '\0';
}
void get_extension2(char *file_name, char *extension)
{
char *p;
for(p = file_name; *p != '.'; p++); /* Starting at the beginning character array memory location, increment until the "." character is reached */
for(p+1; *p != '\0'; p++, extension++) /* A value is calculated but not used and then the two pointers are incremented in synch which then includes "." */
{
printf("p in second function is: %p\n", p);
*extension = *p;
}
*extension = '\0';
}
需要注意的关键点如下:
- 在函数的第一个版本中,一旦找到“.”字符的位置,第二个“for”循环中的初始化步骤就会将内存位置递增到前面一个位置,从而有效地越过“.”字符,并将文件名的剩余字符复制到扩展字符数组中。
- 在函数的第二个版本中,一旦找到“.”字符的位置,第二个“for”循环的初始化步骤只是计算一个实际未使用的值(并且收到了编译器警告),因此“.”字符以及剩余的文件名字符被复制到扩展字符数组中。
- 为了突出两个版本的函数之间的对比,添加了一个“printf”语句,其中列出了内存位置。
以下是表示功能差异的程序执行示例。
craig@Vera:~/C_Programs/Console/FileExtension/bin/Release$ ./FileExtension
Enter file name: sample.txt
p in first function is.: 0x7ffeda0b2e57
p in first function is.: 0x7ffeda0b2e58
p in first function is.: 0x7ffeda0b2e59
Extension is txt
p in second function is: 0x7ffeda0b2e56
p in second function is: 0x7ffeda0b2e57
p in second function is: 0x7ffeda0b2e58
p in second function is: 0x7ffeda0b2e59
Extension is .txt
因此,要点在于了解内存位置如何以及何时递增、递减和引用,并检查编译器文本中的线索和可能的警告。与往常一样,您可能希望参考一些侧重于数组、其指针和指针递增/递减的教程文献。
评论
p++
p
p+1
p+=1