c - 指针的原因是在第二种情况下指向字符串文字的最后一个字符
问题描述
情况1:
# include<stdio.h>
int main() {
int l=0;
char *names[4] = {
"Arijit",
"Rohit",
"Debojyoti",
"Abhisek"
};
while(l<4)
{
printf("Address %u contains %s\n",names[l],names[l]);/*here instead of of names[l] for strings when I used names[l++] the memory order changed look at the output*/
l++;
}
return 0;
}
输出 1:
Address 4210688 contains Arijit
Address 4210695 contains Rohit
Address 4210701 contains Debojyoti
Address 4210711 contains Abhisek
输出 2:
Address 4210695 contains Arijit
Address 4210701 contains Rohit
Address 4210711 contains Debojyoti
Address 45 contains Abhisek
查看第二个 o/p Debojyoti 包含 10 个字符,包括 '\0' 所以 Rohit 被分配地址 4217011。为什么?再看看 Abhisek 被分配到一个与其他三个名字不连续的内存位置。为什么?
解决方案
问题是 C没有定义函数参数的评估顺序。时期。在大多数情况下,C 没有定义二元运算符的操作数求值顺序。
因此,在同一个表达式中同时使用和修改变量通常是错误的。(对于语言律师:不,我不是指编译器会检测到的错误!未定义的行为情况是合法的 C,但代码仍然是错误的。)
您的第二版声明,缩短,看起来像:
printf("%p, %s, %s\n", names[l], names[l], names[l++]);
C 可以自由地以printf()
任何顺序评估这些参数。这意味着l==0
在语句开始时,第一次迭代的以下任何解释都是可能的:
printf("%p, %s, %s\n", names[0], names[0], names[0]); l+=1;
printf("%p, %s, %s\n", names[0], names[1], names[0]); l+=1;
printf("%p, %s, %s\n", names[1], names[0], names[0]); l+=1;
printf("%p, %s, %s\n", names[1], names[1], names[0]); l+=1;
在同一个编译器上,您可以看到调试和优化编译之间出现不同的顺序。中间两种解释不太可能,但在符合标准的编译器中仍然允许。只有第 4 个参数保证评估为names[0]', due to the definition of postfix
++`。
正如我上面所说,避免在同一个表达式中使用和修改同一个变量。在不能保证操作顺序的情况下严格避免它,即使在只有一种解释可能的极少数情况下也要三思而后行。Guido Van Rossum(Python 语言的发明者)指出,程序的阅读频率高于编写频率。让团队中的其他程序员感到困惑——甚至是你自己在一两年内回来编辑代码时,都会产生一定的成本。
当“经过测试的”生产代码在编译器升级后开始失败时,成本会更高。
推荐阅读
- python - Virtualhost(linux mint)netstat端口与我在win10上看到的不同
- windows - 行尾行为和 Git
- python - 如何将字典中的列表变成字典中的字典?
- spring-integration - 如何使用 IntegrationFlowContext 作为流程配置的一部分?
- bash - Bash:给管道空字符串一个默认值
- python - 如何编写一个返回总位数和单个空格的函数
- pandas - 如何在使用熊猫读取csv文件时根据某些标准在数字前面添加零
- hashtable - 搜索线性寻址 - 哈希表
- entity-framework - 实体框架错误字符串或二进制数据将在表中被截断
- python - 如何解决 Django 3 在从外部页面获取 POST 数据时重置用户会话的问题