【总结】C语言总结!!!

本文详细介绍了C语言的基础知识,包括关键字、循环结构、数组、函数等,并深入探讨了预处理、内存分配、函数递归等内容。

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

基础:
1、在c语言里面C99标准里面有32个关键字
2、for循环的执行流程:for(int i=0;i<size;i++)
                                        {}
          流程:     int i --->i<size---->{}---->i++
3、goto语句仅能够在函数体的内部进行跳转。
4、什么是数组
 概念:相同元素在内存里面 的集合
分类:一维数组和多维数组
特性:底层是连续的空间、支持随机访问(sizeof(数组名) =  整个数组的大小)
用法:1、存储数据元素
          2、最为函数的参数进行传参
            3、作为函数的返回值

5、函数:概念:在程序里面由一个或者多个语句块组成的子程序。
                分类:库函数-->完成有限的功能、在使用的时候必须包含#include和对应的头文件
                           自定义函数--->可以自己定义想要的逻辑功能
        函数的参数:实参-->正真传给函数的参数(可以是常量、变量、表达式、函数等)
                             形参-->形式参数是指函数部分的参数,因为函数参数部分的参数只有在函数被调用的过程中才会被实例化,所以叫形式参数,            
                                           形式参数在函数调用完成之后会自动销毁,因此,形式参数只有在函数类里面才有效
        函数设计注意事项:1、函数的参数不要过多
                                      2、函数设计要注意代码的复用性
                                      3、函数参数和返回值要满足功能的需要
        函数传参:1、传值---->形参是实参的一份拷贝
                         2、传址---->形参是实参地址的一份拷贝
                         3、传引用---->形参是实参地址的一份拷贝(C++)
        函数返回值方式:1、通过寄存器返回
                                   2、栈返回--->当返回的数据过多的时候,不能通过寄存器返回,返回栈时-->先Push一个地址--->将返回数据存储到这个地址的内存里面---->返回这个指针
进阶:
1、生成可执行程序的过程
            预处理------------->编译------------------>汇编----------------------->exe
      预处理:1、预定义符号__FILE__       //进行编译的源文件
                                          __LINE__       //文件当前行号
                                          __DATE__     //文件被编译的日期
                                          __TIME__     //文件被编译的时间
                    2、#define定义宏:在定义宏的时候尽量将想要表达的顺序的变量之间加上()
                                                   宏是和类型无关的--->在预处理阶段直接替换---速度快
                                                                                     没有类型检查----不安全
宏和函数的对比

属性
#define
函数
代码长度
多次使用会使代码大幅度增长
函数代码只出现依次,每次调用的时候调用同一份代码
执行速度
很快
存在函数调用和返回的额外开销
操作符优先级
宏参数的求值是在上下文的环境里,在设计宏的时候要对需要的参数加上()确保不会出现优先级的错误。
函数参数只在函数调用的时候求值一次,结果值传给函数,表达式的结果更加容易预测。
参数求值
在每次用宏定义的时候,都将重新求值,由于多次求值,具有副作用的参数可能会产生不可预测的而结果。
参数在函数被调用前只求值一次,在函数里面多次使用参数并不会导致多种求值过程,参数的副作用并不会造成特殊影响。
参数类型
宏和类型无关,只要参数合法,便可以使用任何参数类型。
函数的参数和类型有关,如果函数的参数不同就需要使用不同的函数,及时执行的功能相同的。
条件编译:解决头文件重复包含的问题
                常见的预处理条件编译指令:#if   常量表达式
                                                                       ........
                                                            #endif

                                                            #ifndef   表达式
                                                            #define  表达式
                                                                              .......
                                                            #endif
 
2、C/C++里面的内存分配
     栈区(系统自己分配释放):局部变量、函数参数、返回值、返回地址等。
    堆区(程序员分配释放):mallo、new分配的内存
    全局区(静态区):全局变量、静态数据、常量。程序结束后系统释放
    文字常量区:常量字符串。程序结束后系统释放。
    程序代码区:存放函数体(类的成员函数和全局函数)的二进制代码。
内存分配的方式:1、从静态存储区分配---->全局变量、static变量
                           2、在栈上开辟空间--->执行函数,函数体内的局部变量
                           3、从堆上开辟空间---->malloc,new
volatile关键字:编译时候不优化、执行的时候不缓存,每次都在内存里面读取(保证内存的可见性)
3、函数进阶理解
函数栈帧
函数的递归:递归的条件:1、存在限制条件,当这个限制条件满足的时候,递归继续,如果不满足的话就结束递归。
                                        2、每次递归都应该向限制条件靠近。
                    递归示例:菲波那切数列
main函数的参数解析:main函数的原型 int main(int argc,char *argv[],char *envp[]){}
                                  第一个参数:argc是整形变量,表示命令行参数的个数。
                                  第二个参数:argv是一个字符指针数组,每个元素都是字符指针。
                                  地三个参数:envp是字符指针数组,每一个元素指向一个环境变量字符串的指针。
可变参数列表:(函数参数不确定的函数)
示例:#include<stdio.h>
#include<stdarg.h>
int  Add(int n,...)
{
    va_list arg;
    int i = 0;
    int sum = 0;
    va_start(arg,n);
    for (;i<n;i++)
    {
         sum += va_arg(arg,int);
    }
    return sum;
    va_end(arg);
}
int main()
{
    int a = 10;
    int b = 20;
    int c = 15;
    int sum1 = Add(2,a,b);
    int sum2 = Add(3,a,b,c);
    printf("%d\n",sum1);
    printf("%d\n",sum2);
    return 0;
}
  • 声明一个va_list类型的变量arg,这个变量用来访问参数列表里面未确定的部分
  • va_list声明的变量用va_start来初始化,他的第一个参数是va_list的变量va_list的变量名,第二个参数是省略号前最后一个有名字的参数。初始化过程吧arg变量设置成可变参数列表部分的第一个参数。
  • va_arg这个宏接受两个参数,va_list变量的变量和参数列表中的下一个参数类型
  • 最后需要在访问完毕之后调用va_end。
注意:
  • 可变参数列表里面必须从头到尾逐个访问,可以中途停止但是不可以开始就访问参数列表里面的中间元素。
  • 参数列表里面必须至少有一个明名参数,否则无法使用va_start
  • 这些宏是不对参数类型进行类型检测的
  • 如果在va_arg里面出现错误,那么在程序里面后果是不可以预测的。
3、指针
    概念:用来存储地址的变量单元
    注:指针的类型决定指针向前或者向后走一步有多大的距离
       模拟实现:strlen、strcat、strstr、strcpy、strcmp...
    重点------>C语言课件指针下
    //1
(*(void (*)())0)();              //调用一个将0强转成void (*)()类型的函数
//2

void (*signal(int , void(*)(int)))(int);    //声明一个返回值类型为void (int )类型,参数为int和void (*)(int)型指针的函数指针。
示例:函数指针实现一个通用的计算器
4、结构体
概念:将一些具有共同特征(属性)的变量封装在一起,组成的自定义数据类型。
结构体对齐规则:1、成员对齐:min(默认对齐数,成员类型)
                           2、整体对齐:min(默认对齐数,max成员类型)*n
结构体里面如何求一个成员变量相对于结构体其实位置的偏移量?
            offsetof(结构体类型,成员名)
            offsetof(s,m)    *(size_t)&((s*)0->m);
5、文件操作
fopen(文件路径,打开模式);
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
fseek(文件指针,偏移量,起始点);
fgetc(文件指针)从文件指针里面读入一个字符
fputc(str,fp)将str里面的字符写到fp里面去。
fgets(str,n,fp)从fp里面读入长度为n的字符串到str里面去。
fputs(str,fp)将str里面的字符串写到fp里面去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值