部分知识点解决来与于[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语句判断当中
-
适用条件:当需要同时满足多个条件时,可使用逻辑与(&&);当需要满足其中一个条件时,可使用逻辑或(||)。
-
详细讲解:
-
通俗来讲就是 表达式一 && 表达式二:&&意思是<并且>,只用当表达式一和表达式二同时成立才为真
-
表达式一 && 表达式二:||意思是<或者>,只用当表达式一和表达式二有一个成立就为真。
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