天天看点

C语言学习 阶段小结前言一、语法规范二、scanf返回值三、判断语句的使用四、数组传参To be continued

文章目录

  • 前言
  • 一、语法规范
    • 1.分号的使用与常见错误
      • 1.1 if语句中的分号错误
      • 1.2 循环语句中的分号错误
  • 二、scanf返回值
    • 1.scanf返回值
  • 三、判断语句的使用
  • 四、数组传参
  • To be continued

前言

C语言学习已经有一段时间,相比语言要求更不严格的Python等语言,C语言需要注意的细节更多,这要求我们在编写代码和程序时要十分小心,否则很有可能在程序出错时也无法发现自己的错误。本文就本人一段时间的学习以来遇到的一些易错易漏易混淆知识点进行一些总结。

一、语法规范

1.分号的使用与常见错误

C语言中的分号就像汉语中的句号,代表一句话的结束。如果一个完整的语句最后缺少分号,计算机将无法判断语句在何处结束,也就不易获得正确完整的代码语句。好在编译器都会在编译时报错,并提示这一通常因粗心产生的错误。但分号的错误使用却不易被察觉最终导致程序运行出现BUG。

1.1 if语句中的分号错误

#include<stdio.h>
int main()
{
int a,b,c=1;
if(a==0);
printf("Im a good boy.");//即使不是1也仍然可以输出这句话
else;
return 0;
}
           

此处if后多了一个分号直接导致if失效,因为if不加()只能够控制后面的一条语句,再往后if将不再有作用效果。

#include<stdio.h>
int main()
{
int a,b,c=0;
if(a==0)
;
printf("Im a good boy.");
else//会自动报错提示else无对应的if
return 0;
}
           

自动报错表明if受分号影响对后续语句不再拥有作用效果

1.2 循环语句中的分号错误

#include<stdio.h>
int main()
{
int arr[10]={0};
for(int i=0;i<=9;i++);
scanf("%d",arr[i]);//此处将报错
return 0;
}
           

这段代码在编译时会报错"name lookup of ‘i’ changed for ISO ‘for’ scoping [-fpermissive]"实际上就是指i这一变量的使用范围仅限于for循环内,也就是表明这一语句不在循环结构内,实际上是因为在没有()的情况下,for语句只可控制下一条语句,而这里的分号(空语句)占用了这一控制名额,导致后续的报错。

二、scanf返回值

1.scanf返回值

#include<stdio.h>
int main()
{
int a,b,c=0;//初始化变量
int num=scanf("%d %d %d",&a,&b,&c);//获得scanf的返回值
printf("%d",num);//结果为3
return 0;
}
           

此处输出的num值为3

scanf的返回值为成功输入的字符数。

#include<stdio.h>
int main()
{
int a,b,c=0;   //初始化变量
int num=scanf("%d %d %d",&a,&b); //获取scanf的返回值
printf("%d",num);//结果仍然为3
return 0;
}
           

此处只给a、b两个变量进行赋值,但最后输出的num仍然为3,由此可知scanf返回值为成功输入值的个数,与输入是否赋值给变量无关。

三、判断语句的使用

所有学习C语言的人可能都会有一个习惯,下意识地把等于符号打为“==”。这也反映出判断符号在C语言中的特殊性。

#include<stdio.h>
int main()
{
int arr[10]={0};
if(arr[1]=-1)
printf("wrong");
return 0;
}
           

这段代码咋一看没有问题,而且最终也不应该输出内容,但事实确是在运行时屏幕将显示“wrong”。问题就是在于if中的条件并不是一个正确的判断条件,而是错输入了一个赋值语句。这样的错误隐蔽但很致命。

四、数组传参

数组传参在C语言中是较为特别的一个情况

#include<stdio.h>
int main()
{
int arr[10]={0};
for(int i=0;i<=9;i++)
scanf("%d",arr+i);
return 0;
}
           

对于通常的int、char、float等等类型的变量,scanf输入都需要加上“&”取地址的符号,但数组传参则是直接传入首个元素的地址,所以可以在不用“&”的情况下直接用数组名进行传参。但需要注意的是此处也可以用&arr[i]的方式实现这一循环输入。对于字符数组同理也可以通过数组名进行传参。

既然知道数组在传参时传入的是首元素地址,那么我们自然就不应该犯下面的错误

#include<stdio.h>
#include<string.h>
int size(char *arr)
{
	int size1=-1;
	size1=sizeof(arr)/sizeof(arr[0]);
	return size1;
}
int main()
{
char arr[20]={0};
scanf("%s",arr);
char arr1[30]=", hello world\n";
strcat(arr,arr1);
printf("%s",arr);
int size1=-1;
size1=size(arr);
printf("%d",size1);
return 0;
}
           

这样是无法求出数组的真实长度的,因为传入的并非整个数组而是数组指针,而相应的size函数中求出的大小也只是指针所占用的内存空间(8字节)

*注:指针的大小取决于系统位数,在32位系统中指针的大小是4个字节而64位系统中指针的大小为8个字节。

To be continued

以上是对目前遇到的一些C语言细节点的小结,如有新的更多发现将继续添加。

继续阅读