c语言入门易错知识点(补充中)

本文介绍了C语言中的break和continue在循环中的作用,自动类型转换的规则,a++与++a的区别,逻辑运算符的使用,以及传参的按值与按地址传递,还对比了int和void函数的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

部分知识点解决来与于[C语言基础知识入门(大全)-优快云博客]

一、break与continue问题

1.在for循环中,break是直接中断for循环,(多层)for循环直接结束,continue是直接跳出循环。

下面用代码来直观的表现出

break:

for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;
    }
    printf("%d ", i);
}
 
continue:
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        continue;
    }
    printf("%d ", i);
}
 
具体实操代码如下:
#include <stdio.h>
int main() {
	printf("break效果如下:"); 
	for (int i = 0; i < 10; i++) {
	    if (i == 5) {
	        break;
	    }
	    printf("%d ", i);
	}
	printf("\ncontinue效果如下:"); //注意前面的\n的意思是进行换行,控制台实际输出效果是 continue效果如下:
    for (int j = 0; j < 10; j++) {
	    if (j == 5) {
	        continue;
	    }
    	printf("%d ", j);
	}
    return 0;
}
 


 
 代码结果如下:

 break效果如下:0 1 2 3 4
continue效果如下:0 1 2 3 4 6 7 8 9

 通过上述代码可知,break直接中断循环,而continue是跳过当前循环,进行下一趟循环。那么在多层for循环中,break产生啥效果呢,请看下面代码:

#include <stdio.h>
int main() {
	printf("在多层for循环下break果如下:\n"); 
    for (int j = 0; j < 10; j++) {
		
		for (int i = 0; i < 10; i++) {
		    if (i == 5) {
		        break;
		    }
		    printf("%d ", i);
		}
		printf("\n");
	}
    return 0;
}
 
结果如下:

在多层for循环下break果如下:
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4 

由此我们可以得出,每次执行break都会直接跳过当前的for循环,从上一层for循环从头开始。

二、自动类型转化:

1. 图片形式:

注意只能有字节小的转向大的,反之则不行。

2.代码形式【字节数判断】
#include <stdio.h>

int main() {
    printf("Size of int: %lu byte(s)\n", sizeof(int));
    printf("Size of float: %lu byte(s)\n", sizeof(float));
    printf("Size of double: %lu byte(s)\n", sizeof(double));
    printf("Size of long: %lu byte(s)\n", sizeof(long));
    printf("Size of char: %lu byte(s)\n", sizeof(char));
    printf("Size of short: %lu byte(s)\n", sizeof(short));

    return 0;
}
 

得出结果如下: 

Size of int: 4 byte(s)
Size of float: 4 byte(s)
Size of double: 8 byte(s)
Size of long: 4 byte(s)
Size of char: 1 byte(s)
Size of short: 2 byte(s)

         值得一提的是int和float的字节数一样,但是他们区别主要在于范围和精度不同(int是整型而float是浮点型) 

三、a++与++a问题:

1.图片形式

2.代码展示【a++与++a】 
#include <stdio.h>

int main() {
    int a = 5;
    
    // a++示例
    printf("a = %d\n", a); // 输出 a = 5
    printf("a++ = %d\n", a++); // 输出 a++ = 5
    printf("a = %d\n", a); // 输出 a = 6
    
    // ++a示例
    a=5; //让a再次等于5,查看区别 
    printf("a = %d\n", a); // 输出 a = 5
    printf("++a = %d\n", ++a); // 输出 ++a = 6
    printf("a = %d\n", a); // 输出 a = 6
    
    return 0;
}

 

通过上述代码我们可以得出,a++=5,而++a=6。进而得出a++是先取值,再运算(自增)。++a是自己先运算(自增),在取值。

 3.总结如下:

a++和++a是两种不同的自增运算符。它们的主要区别在于它们所产生的结果值。

  • a++:这是后置自增运算符,它首先返回变量a的当前值,然后将a的值增加1。也就是说,a++会先返回变量a的值,然后再执行自增操作。例如,如果a的初始值是5,则表达式int b = a++;会使b的值为5,然后a的值变为6。
  • ++a:这是前置自增运算符,它首先将变量a的值增加1,然后返回a的新值。也就是说,++a会先执行自增操作,然后再返回变量a的值。例如,如果a的初始值是5,则表达式int b = ++a;会使a的值变为6,并且b的值也是6。

因此,在运用上的主要区别在于对表达式的求值顺序的影响。使用a++时,先返回变量的原值,然后再自增;而使用++a时,先自增变量的值,然后再返回。具体使用哪种自增运算符取决于需要的结果值。

四、逻辑运算符问题:

1. && 与 || 问题:
  • 适用范围:通常用在if语句判断当中
  • 适用条件:当需要同时满足多个条件时,可使用逻辑与(&&);当需要满足其中一个条件时,可使用逻辑或(||)。
  • 详细讲解:
  1. 通俗来讲就是  表达式一 && 表达式二:&&意思是<并且>,只用当表达式一和表达式二同时成立才为真

  2. 表达式一 && 表达式二:||意思是<或者>,只用当表达式一和表达式二有一个成立就为真。

2. 三目运算符

表达式一 ?表达式二:表达式三           

快速理解:首先<?>的意思是前面表达式一是真的还是假的,真的就执行表达式er,假就执行表达式三。

#include <stdio.h>

int main() {
    int num1 = 10;
    int num2 = 20;

    int max = (num1 > num2) ? num1 : num2;

    printf("The maximum number is: %d\n", max);

    return 0;
}
 

上述结果是max=20。在max=AA ?BB :CC 这个式子中,当AA为真的时候,执行BB。如果AA为假的时候执行CC。

3. 符号优先级问题

 下述展现一个例子:

#include <stdio.h>

int main() {
    int a = 2, b = 3, c = 4, d = 5, e = 6, f = 7;
    int result1 = a * b + c / d - e % f;   // 乘法、除法和取模优先级高于加法和减法
    int result2 = a << 2 + b >> 3;         // 位移运算符优先级高于加法和减法
    int result3 = (a & b) ^ (c | d);       // 按位与、按位或和按位异或优先级高于逻辑与和逻辑或
    int result4 = !a && b || c;            // 逻辑非、逻辑与和逻辑或优先级从高到低依次降低

    printf("Result 1: %d\n", result1);
    printf("Result 2: %d\n", result2);
    printf("Result 3: %d\n", result3);
    printf("Result 4: %d\n", result4);

    return 0;
}
 

得出结果如下:

Result 1: 0
Result 2: 8
Result 3: 7
Result 4: 1

五、多维数组问题:

1.分不清二维数组遍历中对应的关系>>先行后列

对于初学者来讲,有时可能会在数组的遍历中,分不清对二维数组的哪个代表着“行”,哪个代表着“列”而导致,在for循环中可能会导致遍历超过数组下标上限或者没有完全遍历完数组(即让下面的代码i<3,j<2。那么这就会导致代码报错)

#include <stdio.h>

int main() {
	int num[2][3] = {{1,2,3},{3,4,5} } ;
	for(int i = 0;i<2;i++){
		for(int j = 0;j<3;j++){
			printf("%d",num[i][j]);
		}
		printf("\n");
	}
	return 0;
}
 2.得出结果如下:

123
345

由此我们可以得出对于num[2][3],可以理解为两行三列。 这里只写了最简单的运用。

六、关于传参问题:

1.按值传参与按地址传参

对于传参有两种形式:一种是按值传参,一种按地址传参。他们区别在于按值传参相当于再起一个别名,然后将这个参数值赋给它。地址传参相当于直接将参数地址给它,直接修改这个参数的值 。直接体现为按值传参不会修改这个参数的值,按地址传参则会修改。

#include <stdio.h>

void fun_value(int num) {
    num = 20; // 修改局部副本的值
}
void fun_point(int* ptr) {
    *ptr = 10; // 通过指针修改原始变量的值
}

int main() {
    int a = 5;
    printf("原始a的值: %d\n", a); // 输出原始变量的值
    fun_value(a); // 按值传递
    printf("按值传参: %d\n", a); // 输出原始变量的值,不会改变
    fun_point(&a);
	printf("按地址传参: %d\n", a); // 输出原始变量的值,会改变 
    return 0;
}

结果如下:

原始a的值: 5
按值传参: 5
按地址传参: 10

2.进行理解:

按值传参和按地址传参是函数参数传递的两种方式。在按值传参中,函数的形参是实参的拷贝,对形参的修改不会影响实参;而在按地址传参中,函数的形参是实参的地址,对形参的修改会影响实参。

补充一下对传参和实参的讲解:

形参和实参是关于函数参数的概念,它们的定义如下:
  • 形参:在函数定义中声明的参数,用于接收函数调用时传递给函数的实际值。形参在函数定义时作为变量来使用,有助于定义函数的结构和行为。

  • 实参:在函数调用时传递给函数的实际值。实参可以是常量、变量、表达式或其他函数的返回值。实参的值被传递给函数的形参,用于在函数内部进行计算和处理。

  • 简单来说,形参是函数定义中的参数名,用于标识函数内部使用的变量;而实参是在函数调用时传递给函数的值,可以是任何合法的表达式或变量。

    在函数调用时,实参的值可以通过按值传递或按引用传递的方式传递给函数的形参。按值传递是将实参的值复制给形参,形参的修改不会影响实参。而按引用传递是将实参的引用(地址)传递给形参,形参可以通过引用修改实参的值。

  • 下面是一个示例代码,用于演示形参和实参的概念:
#include <stdio.h>

// 按值传递
void changeValueByValue(int num) {
    num = 10; // 修改形参的值
    printf("按值传递,形参的值为:%d\n", num);
}

// 按引用传递
void changeValueByReference(int* ptr) {
    *ptr = 20; // 通过指针修改实参的值
    printf("按引用传递,实参的值为:%d\n", *ptr);
}

int main() {
    int num = 5;
    printf("实参的值为:%d\n", num);
    printf("\n");
    changeValueByValue(num); // 按值传递,num的值被复制给形参
    printf("函数调用后,实参的值为:%d\n", num);
    printf("\n");
    changeValueByReference(&num); // 按引用传递,传递num的地址
    printf("函数调用后,实参的值为:%d\n", num);

    return 0;
}
 
输出结果为:
实参的值为:5

按值传递,形参的值为:10
函数调用后,实参的值为:5

按引用传递,实参的值为:20
函数调用后,实参的值为:20

七、定义函数int 与void区别:

int :需要用到return,即需要有返回值

void : 没有返回值,可以直接输出。

 1. 首先 int型函数也一般传递回来的是一个值,不能够直接传递回来一个式子,但能传递回来一个式子的值。
#include <stdio.h>

int fun_equation(int num) {
    int result = num + 10; // 进行某个式子的计算
    return result; // 返回式子计算的结果
}

int fun_value(int num) {
    num = 20; // 修改局部副本的值
    return 20; 
}
void func(int num){
	printf("void型函数,不返回:%d",num);
}

int main() {
    int a = 5;
    printf("原始a的值: %d\n", a); // 输出原始变量的值

    int equationResult = fun_equation(a); // 调用函数并将结果存储在变量中
    printf("int型函数,返回一个式子: %d\n", equationResult); // 输出存储的式子结果

    int num =  fun_value(a);
    printf("int型函数,返回一个值: %d\n", num); 
    
    func(a);
    return 0;
}
2. 结果如下:

原始a的值: 5
int型函数,返回一个式子: 15
int型函数,返回一个值: 20
void型函数,不返回:5

八、在下一篇中将会写到数组,指针,结构体,以及数组的更深层的内容。对于不完善或者理解错误的地方,望指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhou Xuan_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值