C语言基础知识
1. 正常格式书写
c语言代码的正常格式:
#include <stdio.h> //include的后面有空格
//此处可以空一格
int main()
{
return 0;
}
2. 利用scanf函数来实现多行输入
此处需要多行输入,我们可以利用
scanf
函数的性质来实现多行输入
scanf
函数是用来读取数据的如果能正常读取数据,返回的是读取数据的个数
例如:
int main() { int a = 0; int b = 0; int ret = scanf("%d %d", &a, &b); printf("a=%d\n", a); printf("b=%d\n", b); printf("ret=%d\n", ret); return 0; }
当输入1 2时(或者1回车然后2)
此时可以看出
scanf
读取数据的个数为2当输入1
ctrl+z
时(其实只要输入一个ctrl+z
,scanf
就会结束,此时应该是vs的bug)此时可以看出
scanf
读取数据的个数为1当输入只
ctrl+z
时此时可以看出
scanf
读取的数据的个数为0,值是-1,为什么是-1?,因为end of file,还没开始读就结束了
如果读取遇到错误,或者遇到读取文件结束返回
EOF
#include <stdio.h>
int main()
{
int num = 0; //初始化,否则如果忘记赋值直接输入会出现乱码,初始化后,我们就知道问题所在
scanf("%d",&num);
while(scanf("%d",num)==1)//表示读取项为1,也可以是!=EOF,EOF:end of file 文件结束标志,此处表示到达输入流末尾
{
if(num>=140)
{
printf("genius\n");
}
}
return 0;
}
注意:在C语言中,
scanf
函数的返回值是成功读取并匹配的输入项的个数。当scanf
函数成功读取并匹配了一个输入项时,返回值为1;当出现错误或者到达输入流的末尾时,返回值为EOF
(-1)。因此,当scanf
函数成功读取并匹配了一个输入项时,返回值为1,所以可以使用"==1"来判断是否成功读取了一个输入项。
局部变量的作用域:局部变量所在的局部范围。
数字0,数值就是0
字符‘0’,ASCII值是48
\0一般作为字符串的结束标志
3. 字符数组输入乱码问题
#include <stdio.h> int main() { char ch[] = {'b','i','t'}; printf("%s", ch); return 0; }
在上述代码中直接打印结果,会出现乱码的问题,为了解决这个问题,我们可以在后面添加‘\0’。
为什么会出现乱码?
因为字符数组的初始化有两种方式:显式初始化和隐式初始化。
在上面的代码中,字符数组
ch
是通过显式初始化的方式进行初始化的,即通过逐个指定每个字符的方式进行初始化。在这种情况下,编译器不会自动在末尾添加空字符。因此,输出结果会乱码。如果你想要让编译器自动在末尾添加空字符,可以使用隐式初始化的方式,即使用双引号将字符序列括起来,如
char ch[] = "bit";
。这样编译器会自动在末尾添加空字符。
#include <stdio.h> #include <string.h> int main() { char ch[] = {'b','i','t'}; printf("%s", strlen(ch)); return 0; }
上述打印结果数字会是随机值,因为没有\0,停止位置随机。
%s
是C语言中的格式控制符,用于格式化输出字符串。在
printf
函数中,%s
用于输出一个以空字符('\0'
)结尾的字符串。当printf
函数遇到%s
时,它会从对应的参数列表中读取一个指向字符串的指针,并将该指针所指向的字符串输出到标准输出。
4. 函数声明问题
#include<stdio.h>
int main() {
int a,b,c;
int max(int x, int y);
scanf("%d %d",&a,&b);
c = max(a,b);
printf("max=%d\n",c);
}
int max(int x, int y) {
int temp;
if (x > y)
temp = x;
else
temp = y;
return (temp);
}
在C语言中,函数的声明通常需要在使用该函数之前进行。这是因为C语言是一种顺序执行的语言,编译器需要在使用函数之前知道函数的返回类型、参数类型和函数名等信息。
#include<stdio.h>
int max(int x, int y); //函数声明
int main()
{
int a,b,c;
scanf("%d %d",&a,&b);
c = max(a,b);
printf("max=%d\n",c);
}
int max(int x, int y) {
int temp;
if (x > y)
temp = x;
else
temp = y;
return (temp);
}
5. 数组
5.1 数组在C语言中的定义
一组相同类型元素的集合
5.2 数组的优点
- 存储多个相同类型的元素:数组允许我们在一个变量中存储多个相同类型的元素。这样,我们可以通过一个变量名来访问数组中的不同元素,而不需要为每个元素定义一个独立的变量。
- 方便的访问和处理数据:通过使用数组,我们可以使用索引来访问数组中的元素。数组的索引从0开始,可以通过索引值来快速访问数组中的任意元素。这样,我们可以方便地对数组中的元素进行读取、修改和处理。
- 节省内存空间:使用数组可以节省内存空间。相比于定义多个单独的变量来存储多个元素,使用数组可以在一个连续的内存块中存储所有元素,从而减少了内存的使用。
5.3 数组的下标
下标:距离第一个元素的位置远近
数组的每个元素都有一个下标,下标是从0开始的,数组可以通过下标来访问的。
5.4数组的使用
#include <stdio.h>
int main()
{
int i = 0;
int arr[10];
for(i=0; i<10; i++)
{
scanf("%d",arr[i]);
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
或者
#include <stdio.h>
int main()
{
int arr[10];
int i = 0;
while(i<10)
{
scanf("%d",&arr[i]);
i++;
}
i = 0; //此处的i=0不可以省略
while(i<10)
{
printf("%d",arr[i]);
i++;
}
printf("\n");
return 0;
}
数组进不进行初始化是无所谓的,但是变量最好进行初始化,但为了避免潜在的错误和不确定性,建议在声明变量时进行初始化或在使用变量之前对其进行赋值。
数组的初始化是指在声明数组的同时为数组元素赋初值。如果不进行初始化,数组的元素将具有未定义的值。
6. 操作符
6.1 算数运算符 除号
对于除法来说,除号的两端都是整数的话,执行的是整数除法
除号的两端只要有一个数是小数,就执行小数的除法
6.2 double与float的说明
在C语言中,
double
和float
是两种不同的浮点数类型,用于表示带有小数部分的数值。它们的主要区别在于精度和存储空间。
- 精度:
double
类型的变量具有更高的精度,可以表示更大范围和更精确的数值。它通常使用64位来存储,可以表示的有效数字位数约为15-17位。而float
类型的变量精度较低,通常使用32位来存储,可以表示的有效数字位数约为6-9位。因此,double
类型适用于对精度要求较高的计算,而float
类型适用于对精度要求不那么高的计算。 - 存储空间:
double
类型的变量占用的存储空间比float
类型大。double
类型通常占用8个字节(64位),而float
类型通常占用4个字节(32位)。因此,如果存储空间有限或需要节省内存,可以使用float
类型来表示浮点数。
例如:
7.0
编译器默认是double
类型,如果想让它是float
类型,则可以7.0f
。
6.3 取模运算符
6.3.1 取模运算符为什么两边一定是整数?
- 定义限制: 取模运算符的定义是用于整数之间的运算,而不是用于浮点数之间的运算。因此,C语言规定了取模运算符的操作数必须是整数类型,否则会导致编译错误。
- 数学特性: 取模运算的数学特性决定了它只能用于整数之间的运算。取模运算的结果是两个整数相除后的余数,而浮点数相除的结果是一个浮点数,没有余数的概念。
需要注意的是,C语言中的取模运算符对于负数的处理方式可能与数学上的取模定义稍有不同。具体来说,对于负数的取模运算,C语言的结果可能是正数或负数,取决于具体的实现。因此,在进行负数的取模运算时,应该根据具体需求来处理结果。
总结起来,C语言中的取模运算符(%)要求运算符两边的数必须是整数,因为取模运算的定义限制了它只能用于整数之间的运算,并且C语言规定了取模运算符的操作数必须是整数类型。
6.4 移位操作符(了解)
移位操作符是一种在计算机编程中常用的位操作符,用于对二进制数进行位移操作。在C语言中,移位操作符包括左移(<<)和右移(>>)两种。
- 左移(<<): 左移操作符将一个二进制数的所有位向左移动指定的位数。左移操作符的语法是
a << b
,其中a是要进行位移的二进制数,b是要左移的位数。左移操作将a的二进制表示向左移动b位,并在右侧填充0。左移操作相当于将a乘以2的b次方。 - 右移(>>): 右移操作符将一个二进制数的所有位向右移动指定的位数。右移操作符的语法是
a >> b
,其中a是要进行位移的二进制数,b是要右移的位数。右移操作将a的二进制表示向右移动b位,并根据符号位进行填充。对于无符号数,右移操作在左侧填充0;对于有符号数,右移操作在左侧填充符号位的值。
移位操作符常用于对二进制数进行位运算,例如进行位掩码操作、提取或设置特定位等。需要注意的是,移位操作符只能用于整数类型的操作数。
总结起来,移位操作符是一种位操作符,用于对二进制数进行位移操作。C语言中的移位操作符包括左移(<<)和右移(>>)两种。左移操作将二进制数的所有位向左移动指定位数,右移操作将二进制数的所有位向右移动指定位数,并根据符号位进行填充。移位操作常用于对二进制数进行位运算。
6.5 赋值操作符
=
赋值操作符
+=``-=``*=``/=``&=``^=``|=``>>=``<<=
复合操作符
例如:
a=a+3 <—> a+=3
a=a*10 <->a*=10
6.6 双目运算符与单目运算符
单目运算符:只有一个操作数的运算符
双目运算符:有两个操作数的运算符(例如:4/2)
注意:sizeof是单目运算符
在C语言中,真与假
0
表示假非
0
表示真(只要不是0,就是真,-1
也是真)
int main()
{
int n = -1;
if (!n) //只有是假才执行
printf("真\n");
return 0;
}
sizeof:返回指定类型或变量所占用的字节数
strlen:strlen
函数只能用于字符串,即以null字符(‘\0’)结尾的字符数组,它返回字符串中字符的个数,不包括null字符
自增运算符
-
++a形式,先加一,后使用
#include <stdio.h> int main() { int a = 0; int b = 0; b = ++a; printf("%d,%d", a, b); return 0;
-
a++形式,先使用,后加一
#include <stdio.h> int main() { int a = 0; int b = 0; b = a++; printf("%d,%d", a, b); return 0; }
自减运算符一样
少用强制类型转换