C语言错题及注意点
Posted 两片空白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言错题及注意点相关的知识,希望对你有一定的参考价值。
作业
答案选择C,当时选择A
错误原因:对strlen的理解不够,以为仅仅是显示字符个数。
正确理解:strlen是用来获取字符串的有效长度,结尾标记’\\0’不包含在内。获取规则是从前往后依次检测,直到遇到’\\0’终止检测。
题目中有线字符检测完后,由于未放置’\\0’,还会继续往下检测,直到遇到’\\0’,因此答案不确定。
- define不是关键字,是编译器实现的,用来定义常量和宏的预处理指令
#include<stdio.h>
#include<Windows.h>
#pragma warning(disable:4996)
void reverse_string(char *string){//递归
int len = strlen(string);
char temp = *string;
*string = *(string + len - 1);//先将第一个替换
*(string + len - 1) = '\\0';//最后一个'\\0'代替
if (strlen(string + 1) >= 2){//一个字符不需要交换了
reverse_string(string + 1);//往中间变小,
}
*(string + len - 1) = temp;//最后一个用第一个替换
}
void Reverse_string(char *string){//非递归
int len = strlen(string);
char *left = string;
char *right = string + len - 1;
while (left < right){
char temp = *left;
*left = *right;
*right = temp;
left++, *right--;
}
}
int main(){
char a[1000];
gets(a);
Reverse_string(a);
printf("%s\\n", a);
system("pause");
return 0;
}
分析:
两种方法:
非递归:用两指针分别指向头尾,交换后向中间走。
递归:思路一样,都是前后交换,往中间变小。递归是,地址加1作为参数,递归前要将最后一个用‘\\0’代替。因为最后一个会用’\\0’代替,所以必须先交换第一个,最后再来交换最后一个。
#include<stdio.h>
char *print()
{
//char a[] = "abcd";//第一种情况
//char a[] = { 'b', 'c', 'd' };//第二种情况
const char *a = "abcd";//第三种情况
return a;//返回的是地址
}
int main()
{
const char *res = print();
printf("%s\\n", res);
return 0;
}
第一,二种情况返回的是乱码,第三中情况返回字符串“abcd”;
因为函数调用时形成栈帧,将字符或字符串存入数组中,函数调用完毕后地址被释放,由于返回的地址,释放后里面的值发生变化,所以显示乱码(随机值)。但是第三种情况,指针指向的是字符常量地址区,函数释放后地址里的值不会发生变化,所以返回“abcd”。
而当调用一个加减乘除的函数时,为什么不会发生变化,因为返回的是值,不是地址。
指针
做多级指针的题。画图来解。
1.
int a[]={1,2,3,4};
printf("%d\\n",sizeof(*&a));
输出:
16
&符号在a单独使用时,即&a代表整个数组的地址,a代表整个数组的大小。*&a相当于a。
sizeof在a单独使用时代表取整个数组的大小。
2.
int a[3][4]={0};
printf("%d\\n",sizeof(a[0]+1));
printf("%d\\n",sizeof(*(a[0]+1)));
printf("%d\\n",sizeof(&a[0]+1));
printf("%d\\n",sizeof(*(&a[0]+1)));
输出:
4
4
4
16
第一个和第三个因为是地址所以在32位平台下所以为4
第二和四个a[0]可以看作是*(a+0),解了一层引用
第二个整体可以看作*(*(a+0)+1)。解两层引用就是该值。
第四个整体可以看作*(&(*(a+0))+1)。只解了一层引用。
以上是关于C语言错题及注意点的主要内容,如果未能解决你的问题,请参考以下文章