目录
前言:
一. 数据类型:
1.float使用时注意事项
2.整形范围
3.四种常量
4.其他技巧
二.分支和循环语句
1.if/else的配对问题
2.若要连续输入可以使用
3.其他技巧
三.函数
1.C语言程序是从上到下依次执行,还是由main函数进入依次执行?
2.scanf后记得跟&符号
3.一个值得思考的函数
4.其他技巧
四.数组
1.字符串/字符数组的区别?
2. 一维数组传参方法
3.二维数组传参方法
4.其他技巧
五.操作符
1.常见的转义字符
2.操作符优先级
3.其他技巧
六.指针/地址/内存
1.内存分区
七.结构体
1.结构体与类
2.结构体成员中有字符串且要给它赋值时,使用strcpy函数
3.结构体作为参数传给函数时
4.结构体的内存对齐问题
八.其他事项
1.define如何定义宏
2.打印日期时间
3.static修饰
1)修饰变量
2)修饰函数:
4.文件操作读取结束的判断
1)被错误使用的feof
2)正确用法
5.隐式类型转换
前言:
此篇文章是本人在c语言学习结束后,在学习过程中产生的部分疑惑的总结,希望能帮助其他人在入门C语言学习过程中解决一些问题,如果文章中有错误,也欢迎指正(不定期更新)。
一. 数据类型:
1.float使用时注意事项
float类型的字面常量,后面需要加上f或者F来表示是一个单精度浮点数。只所以要这样写,是 因为默认的浮点数常量都是double类型。
float a = 3.14f;
2.整形范围
int范围为-2^31到2^31之间,若超出记得使用long long等类型,使用long long时,对应使用%lld。
3.四种常量
字面常量,const修饰的常变量,#define修饰的常量,枚举常量
4.其他技巧
①打印浮点型时,若不想打印太多小数点,只想打印两位,可以printf("%.2f",f);
②输出时若想整齐一些,可以灵活使用\t以及如printf("%d * %d = %2d",a,b,c);
二.分支和循环语句
1.if/else的配对问题
else与离他最近的if配对
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
此处else与第二个if配对,结果为什么都不输出
2.若要连续输入可以使用
1)while((scanf("%d",&a) != EOF))
2)while((ch = getchar()) != EOF)等技巧
3.其他技巧
①若while()括号中有类似i++,a = c+1等,会执行括号中的指令
三.函数
1.C语言程序是从上到下依次执行,还是由main函数进入依次执行?
答:C语言中总是从main函数开始执行,执行好main函数后,是按照从上到下的顺序执行的。
2.scanf后记得跟&符号
int a = 0;
scanf("%d",&a);
3.一个值得思考的函数
#include <stdio.h>
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
//结果是啥?
//注:printf函数的返回值是打印在屏幕上字符的个数
return 0;
}
结果是什么?
4.其他技巧
①函数体外只能进行初始化,不能进行赋值运算
②若要输入5,9给a与b赋值时,通过scanf("%d,%d",&a,&b);
四.数组
1.字符串/字符数组的区别?
1)字符串
char arr[] = "hello";
//或
char arr[6] = "hello";
//长度为6,最后自动增加一个\0
2)字符数组
char arr[5] = {'h','e','l','l','o'};
//不会在最后自动添加\0
3)当我们使用%s时
①scanf中使用时,也会自动添加一个\0。
②printf中使用时,遇到\0会停止打印,如果没遇到,则会出现乱码
2. 一维数组传参方法
1)普通数组
void test(int arr[])
{}
void test(int arr[10])
{}
void test(int* arr)
{}
2) 指针数组
void test(int* arr[20])
{}
void test(int* arr[])
{}
void test(int **arr)
{}
3.二维数组传参方法
void test(int arr[5][5])
{}
void test(int arr[][5])
{}
void test(int(*arr)[5])
{}
4.其他技巧
①二维数组行可以省,列不能省
五.操作符
1.常见的转义字符
\? 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\' 用于表示字符常量 ' |
\“ 用于表示一个字符串内部的双引号 |
\\ 用于表示一个反斜杠,防止它被解释为一个转义序列符 |
\a 警告字符,蜂鸣 |
\b 退格符 |
\f 进纸符 |
\n 换行 |
\r 回车 |
\t 水平制表符 |
\v 垂直制表符 |
\ddd ddd 表示 1~3 个八进制的数字。 如: \130 X |
\xdd dd 表示 2 个十六进制数字。 如: \x30 0 |
2.操作符优先级
C语言小白必看——操作符详解(操作符优先级)_燕麦冲冲冲的博客-CSDN博客_操作符的优先级别
3.其他技巧
①对于/号,如果两个操作数都是整数,执行整数除法,只要有浮点数,则执行浮点数除法
六.指针/地址/内存
1.内存分区
答:代码在执行时,将内存大方向分为4个区域
①代码区:存放函数体的二进制代码,有操作系统进行管理
②全局区:存放全局变量和静态变量以及常量
③栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
④堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
注意:这里的栈和堆与数据机构的栈和堆是两个不同的概念
七.结构体
1.结构体与类
在学习c++后,我们会发现类与结构体有相似的地方,区别在于
1)可以理解为结构体默认为public,类默认为private
2)结构体无法实现构造函数等
2.结构体成员中有字符串且要给它赋值时,使用strcpy函数
struct Student s1;
strcpy(s1.name,"zhangsan");
s.age = 20;
3.结构体作为参数传给函数时
struct Student s1;
MyPrint(&s1);
//MyPrint(s1)若使用传值,则会由开辟一份新空间,若结构体很大,会造成空间浪费
作为参数时,推荐使用传址调用
4.结构体的内存对齐问题
//练习1
struct S1
{
char c1; int i; char c2;
};
printf("%d\n", sizeof(struct S1));
//练习2
struct S2
{
char c1; char c2; int i;
};
printf("%d\n", sizeof(struct S2));
为何成员一样,打印的结果却不同?因为结构体存在内存对齐现象
C语言-----结构体内存对齐_Li_xixi111的博客-CSDN博客_结构体内存对齐
八.其他事项
1.define如何定义宏
#define DOUBLE(x) ((x) + (x))
由于编译时会直接将DOUBLE替换为后面的((x)+(x)),所以记得加括号,否则可能出现优先级问题,从而获得预料之外的结果
2.打印日期时间
打印当前时间:__TIME__,用%s打印
打印当前日期:__DATE__,用%s打印
3.static修饰
1)修饰变量
①修饰全局变量:只能在本源文件中使用
②修饰局部变量:作用于变为全局
2)修饰函数:
只能在本源文件中使用
即static修饰后改变了作用域
4.文件操作读取结束的判断
1)被错误使用的feof
在文件读取过程中,不能用feof函数的返回值直接用来判断文件是否结束,而是用于当文件读取结束时,判断是读取失败造成的,还是遇到文件尾结束
2)正确用法
①文本文件:fgetc的返回值是否时EOF,或fgets的返回值是否是NULL
②二进制文件:fread的返回值是否小于实际要读的个数
5.隐式类型转换
隐式类型转换_绅士·永的博客-CSDN博客_隐式类型转换
更多推荐
C语言入门可能遇到的若干问题总结
发布评论