目录

前言:

一. 数据类型:

      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语言入门可能遇到的若干问题总结