• C语言基本知识


    基础

    第一个函数

    image-20230813101519988

    argc代表参数个数argument count。argv代表参数value,第一个为放的是文件名,后面是传入的参数。

    编译过程

    • 预处gcc -E hello.c -o hello.i
    • 编译gcc -S hello.c(.i) -o hello.s
    • 汇编gcc -c hello.c -o hello.o
    • 连接gcc hello.o -o hello
    • 一步到位:gcc hello.c -o hello

    image-20230812213433992

    生成文件

    image-20230904191402421

    存储类

    auto:用完即丢。

    static:本文件的全局变量

    extern:只声明,不定义,引用外部变量。

    register:放在寄存器而不是内存。

    //auto
    {
       auto int month;	//   等于int mount;
    }
    
    //register
    {
       register int  miles;
    }
    
    //static
    static int count=10;        /* 全局变量 - static 是默认的 */
    int main(){
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    extern实例

    //文件add.cpp
    extern int x;
    extern int y;
    int add(){
    	return x+y;
    }
    
    //文件test.cpp
    #include 
    int x = 2;
    int y = 5;
    extern int add();	//不用extern也可以
    int main(){
        int z = add();
        printf("%d\n",z);
    }
    
    //cmd下
    $ gcc add.cpp test.cpp -o sum
    //返回结果
    $ sum		
        
        
    //区别extern
    extern int a;     // 声明一个全局变量 a
    extern int a =0;  // 定义一个全局变量 a 并给初值。一旦给予赋值,一定是定义,定义才会分配存储空间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    全局变量static保存在内存的全局存储区中,占用静态的存储单元;

    局部变量auto保存在中,只有在所在函数被调用时才动态地为变量分配存储单元。

    常量

    整数、浮点数、字符、字符串(字符串常量以‘\0’或者null结尾)。

    定义常量define或者const修饰:define只是进行文本替换,const用于只读变量,会为其分配内存(不会为常量分配内存),还可以捕获一些潜在的错误。所以建议使用const

    3.14159       /* 合法的 */
    314159E-5L    /* 合法的 */
        
    //浮点数==整数+小数。科学计数法==小数+指数
    510E          /* 非法的:不完整的指数 */
    210f          /* 非法的:没有小数或指数 */
    .e55          /* 非法的:缺少整数或分数 */
     
    //s1和s2相同
    char *s1 = "hello, dear";
    char *s2 = "hello, " "d" "ear";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    数据类型

    基本,指针,构造(数组、结构、枚举、共用),空。

    整形数据根据编译环境的不同,所取范围不同。

    浮点数

    24位:符号+底数。8位:指数(偏移值为+127)。

    ##include<cfloat>头文件,知道原理
    printf("%e\n",FLT_MIN) ;	//1.175494e-038
    printf("%e\n",FLT_MAX) ;	//3.402823e+038  
    
    //二者均为常量9
    int a = '\11';	
    int b = 011;	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运算符

    算数、逻辑、位、关系、赋值。杂运算符:sizeof()、&(取地址)、*(指向一个变量)、?:。

    优先级:后缀((),->,++/–),单目(!/sizeof/++/–),算数,移位,大小关系,相等关系。位运算,逻辑运算。三元,赋值,逗号。

    格式化输出

    格式字符,转义字符,普通字符。格式修饰符。g和G?l和L?h?%.ns表示?%-m.nf表示什么意思?

    枚举

    枚举类型是被当做 int 类型来处理的,所以按照 C 语言规范是没有办法遍历枚举类型的。不过在一些特殊的情况下,枚举类型必须连续是可以实现有条件的遍历。

    //不可以遍历
    enum
    {
        ENUM_0, ENUM_10 = 10, ENUM_11
    };
    
    //可以遍历。默认MON是0,但是这里赋值为1
    enum DAY
    {
          MON=1, TUE, WED, THU, FRI, SAT, SUN
    }day;
    int main()
    {
        // 遍历枚举元素
        for (day = MON; day <= SUN; day++) {
            printf("枚举元素:%d \n", day);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    指针

    指针的含义。&*

    函数指针

    函数指针:一个指向函数的指针int (*p)(int,int) = fun

    //函数指针
    int max(int a,int b){ return a>b?a:b; }
    int main(){
    	int (*p)(int,int) = &max;//&可以不写 
    	p(1,2);		//等价max(1,2) 
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    回调函数

    populate_array() 将调用 10 次回调函数,并将回调函数的返回值赋值给数组。

    void populate_array(int *array,size_t length,int (*getValue)()){
    	for(int i=0 ; i<length ; i++){
    		*(array+i) = getValue();	//这里
    	}
    }
    
    int getRandom(){ return rand(); }	//回调函数
    
    int main(){
    	int array[10];
         //getRandom不能加括号否则无法编译,因为加上括号之后相当于传入此参数时传入了 int,而不是函数指针
    	populate_array(array,10,getRandom);
    	//此时for输出array
    	return 0;
    }
    
    //size_t 是一种数据类型,近似于无符号整型,但容量范围一般大于 int 和 unsigned。这里使用 size_t 是为了保证 arraysize 变量能够有足够大的容量来储存可能大的数组。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    字符串

    \0 是用于标记字符串的结束

    #include 
    char site[7] = {'R', 'U', 'N', 'O', 'O', 'B', '\0'};
    char site[] = "RUNOOB";
    char site[6] = {'R', 'U', 'N', 'O', 'O', 'B'};//如果当作字符串输出会乱
    
    
    strcpy(s1, s2);	//复制字符串 s2 到字符串 s1。
    strcat(s1, s2); //连接字符串 s2 到字符串 s1 的末尾。catenate 
    strlen(s1);		//返回字符串 s1 的长度。
    strcmp(s1, s2);	//如果 s1 和 s2 是相同的则返回0如果 s1s2 则返回大于 0。
    strchr(s1, ch);	//返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
    strstr(s1, s2);	//返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。
    strupr(s1);
    strlwr(s1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    结构体

    定义结构体:

    #1
    //声明了结构体变量s1
    struct{
        int a;
        char b;
        double c;
    } s1;
    
    
    #2
    struct SIMPLE{
        int a;
        char b;
        double c;
    };
    //用SIMPLE标签的结构体,另外声明了变量t1、t2、t3
    struct SIMPLE t1, t2[20], *t3;
    
    
    #3
    //也可以用typedef创建新类型
    typedef struct Simple2{
        int a;
        char b;
        double c;
    };
    //现在可以用Simple2作为类型声明新的结构体变量
    Simple2 u1, u2[20], *u3;
    
    struct Books{
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    } book = {"C 语言", "RUNOOB", "编程语言", 123456};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    实例:

    struct Person {
        char name[20];
        int age;
        float height;
    };
    
    int main() {
        struct Person person;
        printf("结构体 Person 大小为: %zu 字节\n", sizeof(person));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    使用 sizeof 运算符来获取 person 结构体的大小,结构体的大小可能会受到编译器的优化和对齐规则的影响。了解结构体的内存布局和对齐方式,可以使用 offsetof 宏和 _attribute_((packed)) 属性等进一步控制和查询结构体的大小和对齐方式。

    共用体

    定义

    
    union Data
    {
       int i;
       float f;
       char  str[20];
    } data1;
    
    union Data data2; 	//sizeof(data2) = 20,会采用共用体中最大的元素作为对象的大小 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果其中对象的一个元素被赋值,其他的元素都会受到损害。共用体用于多个元素只会用其中的一种情况,比如传递信息的包(只会传递一种包)。

    位域

    位域bit-field是结构体中特殊的成员,指定成员占用多少bit,位域的宽度不能超过其数据类型的大小。

    /* 定义简单的结构 */
    struct
    {
      unsigned int a;
      unsigned int b;
    } status1;		//sizeof(status1)=8
     
    /* 定义位域结构 */
    struct
    {
      unsigned int a : 1;	//指定a占用1bit,也就是a只能为0或者1
      unsigned int b : 1;	//指定b占用1bit
    } status2;		//sizeof(status2)=4
    
    
    //一个位域存储在同一个字节中,如一个字节所剩空间不够存放另一位域时,则会从下一单元起存放该位域。也可以有意使某位域从下一单元开始。
    struct
    {
      char a : 2;
      char b : 3;
      char c : 3;
    } status3;		//sizeof(status3)=1
     
    
    //位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的。
    struct k{
        int a:1;
        int  :2;    /* 该 2 位不能使用 */
        int b:3;
        int c:2;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    结构体内存分配原则

    原则一:元素根据自己的整数倍进行存储。

    原则二:struct的大小为元素(最占空间)的倍数。

    typedef

    自定义类型。

    //C语言中没有byte的数据类型
    typedef unsigned char byte;
    byte a = 1;
    
    
    
    typedef struct Books
    {
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    } Book;
    Book book;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    typedef区别#define:(typedef定义类型,define文本替换)

    • typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。
    • typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。
    //#define可以使用其他类型说明符对宏类型名进行扩展,但对 typedef 所定义的类型名却不能这样做。
    #define INTERGE int;
    unsigned INTERGE n;  //没问题
    typedef int INTERGE;
    unsigned INTERGE n;  //错误,不能在 INTERGE 前面添加 unsigned
    
    
    #define PTR_INT int *
    PTR_INT p1, p2;        //p1、p2 类型不相同,宏展开后变为int *p1, p2;
    typedef int * PTR_INT
    PTR_INT p1, p2;        //p1、p2 类型相同,它们都是指向 int 类型的指针。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输入 & 输出

    int scanf(const char *format, …)int printf(const char *format, …)

    int getchar(void)int putchar(int c)

    **char *gets(char s)int puts(const char s)

    C 语言把所有的设备都当作文件。所以设备(比如显示器)被处理的方式与文件相同。以下三个文件会在程序执行时自动打开,以便访问键盘和屏幕。

    标准文件文件指针设备
    标准输入stdin键盘
    标准输出stdout屏幕
    标准错误stderr您的屏幕
    #1:
    int getchar(void); //从屏幕读取下一个可用的字符,并把它返回为一个整数。这个函数在同一个时间内只会读取一个单一的字符。您可以在循环内使用这个方法,以便从屏幕上读取多个字符。
    int putchar(int c); // 函数把字符输出到屏幕上,并返回相同的字符。这个函数在同一个时间内只会输出一个单一的字符。您可以在循环内使用这个方法,以便在屏幕上输出多个字符。
    
    int c = getchar();
    putchar(c);
    
    
    
    #2:
    char *gets(char *s); //函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。读取的换行符被转换为null值,做为字符数组的最后一个字符,来结束字符串。gets函数由于没有指定输入字符大小,如果很大会越界。
    int puts(const char *s); //函数把字符串 s 和一个尾随的换行符写入到 stdout。
    
    char str[100];
    gets(str);
    puts(str);
    
    
    #3:
    scanf()printf() 函数
    
        
        
    #4:
    fgets函数原型:char *fgets(char *s, int n, FILE *stream);我们平时可以这么使用:fgets(str, sizeof(str), stdin);取代gets(),原因gets()易越界
    
    char str[5];
    fgets(str, sizeof(str), stdin);
    fputs(str,stdout);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    文件读写

    FILE *fopen( const char *filename, const char *mode );

    r打开一个已有的文本文件,允许读取文件。
    w打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。
    a打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。
    r+打开一个文本文件,允许读写文件。
    w+打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。
    a+打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。

    如果是二进制"rb", “wb”, “ab”, “rb+”, “r+b”, “wb+”, “w+b”, “ab+”, “a+b”。

    函数介绍:(错误返回EOF)

    int fputc( int c, FILE *fp );
    int fputs( const char *s, FILE *fp );
    int fprintf(FILE *fp,const char *format, ...) 
    int fgetc( FILE * fp );
    char *fgets( char *buf, int n, FILE *fp );	//读取n-1,因为最后要有'\0'。遇到换行即停
    int fscanf(FILE *fp, const char *format, ...) 	//遇到空格换行即停。
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实验

    #include 
     
    int main()
    {
       FILE *fp = NULL;
     
       fp = fopen("C:\\tmp\\test.txt", "w+");
       fprintf(fp, "This is testing for fprintf...\n");
       fputs("This is testing for fputs...\n", fp);
       fclose(fp);
    }
    
    
    #include 
     
    int main()
    {
       FILE *fp = NULL;
       char buff[255];
     
       fp = fopen("C:\\tmp\\test.txt", "r");
       fscanf(fp, "%s", buff);
       printf("1: %s\n", buff );
     
       fgets(buff, 255, (FILE*)fp);
       printf("2: %s\n", buff );
       
       fgets(buff, 255, (FILE*)fp);
       printf("3: %s\n", buff );
       fclose(fp);
     
    }
    //输出
    1: This
    2: is testing for fprintf...
    
    3: This is testing for fputs...
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    实验

    int fseek(FILE *stream, long offset, int whence);文件中光标偏移

    whence有

    #include 
    int main(){   
        FILE *fp = NULL;
        fp = fopen("test.txt", "r+");  // 确保 test.txt 文件已创建
        fprintf(fp, "This is testing for fprintf...\n");   
        fseek(fp, 10, SEEK_SET);
        if (fputc(65,fp) == EOF) {
            printf("fputc fail");   
        }   
        fclose(fp);
    }
    
    #打开test.txt
    This is teAting for fprintf...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    预处理器

    C Preprocessor简写为CPP

    指令描述
    #define定义宏
    #include包含一个源代码文件
    #undef取消已定义的宏
    #ifdef如果宏已经定义,则返回真
    #ifndef如果宏没有定义,则返回真
    #if如果给定条件为真,则编译下面代码
    #else#if 的替代方案
    #elif如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
    #endif结束一个 #if……#else 条件编译块
    #error当遇到标准错误时,输出错误消息
    #pragma使用标准化方法,向编译器发布特殊的命令到编译器中。pragma“注释”

    实例

    //取消定义,并重新定义
    #undef  FILE_SIZE
    #define FILE_SIZE 42
    
    //ifdef---endif
    #ifndef MESSAGE
       #define MESSAGE "You wish!"
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    内置的宏定义

    #include 
     
    main()
    {
       printf("File :%s\n", __FILE__ );		
       printf("Date :%s\n", __DATE__ );
       printf("Time :%s\n", __TIME__ );
       printf("Line :%d\n", __LINE__ );		//__LINE__当前行号
       printf("ANSI :%d\n", __STDC__ );		//__STDC__,当编译器以ANSI编译器时,为1
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    实例

    //'\'表示宏延续运算符,'#'字符串常量化运算符。宏定义中printf如果被大括号括,则需要在末尾有分号
    #define  message_for(a, b)  \
        printf(#a " and " #b ": We love you!\n")
    int main(void){
       message_for(Carole, Debra);
       return 0;
    }
    //输出
    Carole and Debra: We love you!
        
    
    //'##'标记粘贴运算符
    #define tokenpaster(n) printf ("token" #n " = %d", token##n) 
    int main(void){
       int token34 = 40;
       tokenpaster(34);
       return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    头文件

    include <> 和 include ""区别。

    有条件引用

    #if SYSTEM_1
       # include "system_1.h"
    #elif SYSTEM_2
       # include "system_2.h"
    #elif SYSTEM_3
       ...
    #endif
      
    //需要指定在不同的操作系统上使用的配置参数。
    #if SYSTEM_1
       # include "system_1.h"
    #elif SYSTEM_2
       # include "system_2.h"
    #elif SYSTEM_3
       ...
    #endif
    
    //有条件引用
    #define SYSTEM_H "system_1.h"
    ...
    #include SYSTEM_H
    
    //global.h包含所有头文件,以后直接引用global.h即可
    #ifndef _GLOBAL_H
    	#define _GLOBAL_H
    #endif 
    #include 
    #include 
    #include 
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    强制类型转换

    char/short → int → unsigned → long → double ← float

    错误处理

    errno、perror()、strerror()、可以直接使用 stderr 文件流

    #include 
    #include 
    #include 
    
    extern int errno;
    
    int main(){
    	FILE *fp = fopen("unexist.ext","rb");
    	if(fp == NULL){
    		perror("打开错误\n");
    		fprintf(stderr,"---%s",strerror(errno));
    	}else{
    		fclose(fp);
    	}
    	
    	return 0;
    } 
    //输出
    打开错误
    : No such file or directory
    ---No such file or directory
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    实例

    //退出程序时返回状态。EXIT_FAILURE和EXIT_SUCCESS是宏定义,分别是-1和0
    #include 
    #include 
     
    main()
    {
       int dividend = 20;
       int divisor = 5;
       int quotient;
     
       if( divisor == 0){
          fprintf(stderr, "除数为 0 退出运行...\n");
          exit(EXIT_FAILURE);
       }
       quotient = dividend / divisor;
       fprintf(stderr, "quotient 变量的值为: %d\n", quotient );
     
       exit(EXIT_SUCCESS);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可变参数

    实例

    va_list ;	//stdarg.h中的类型
    va_start(ap, last_arg)	//ap为va_list,last_arg表示最后一个可变参数。ap指向可变参数的第一个元素
    va_arg(ap, type)	//可变参数的下一个参数
    va_end(ap)			//结束,ap置空
        
    #include 
    #include 
    float fun_average(int num,...){
    	va_list valist;
    	va_start(valist,num);
    	float sum = 0;
    	for(int i=0; i<num ; i++){
    		sum += va_arg(valist,int);
    	}
    	va_end(valist);
    	return sum/num;
    } 
    int main(){	
    	printf("%f\n",fun_average(3,5,6,7));
    	printf("%f\n",fun_average(4,5,6,7,8));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    内存管理

    函数均在stdlib.h文件中

    1void *calloc(int num, int size); 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是 0。c表示clear
    2void free(void *address); 该函数释放 address 所指向的内存块,释放的是动态分配的内存空间。
    3void *malloc(int num); 在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。
    4void *realloc(void *address, int newsize); 该函数重新分配内存,把内存扩展到 newsize

    实例

    #include 
    #include 
    #include 
    
    int main(){
    	char *p;
    	p = (char*)malloc(5*sizeof(char));
    	if(p == NULL){
    		fprintf(stderr,"---1stderr");
    	}else{
    		strcpy(p,"1234");
    	}
    	printf("%s\n",p);
    	p = (char*)realloc(p,10*sizeof(char));
    	if(p==NULL){
    		fprintf(stderr,"---2stderr");
    	}else{
    		strcat(p,"12345");
    	}
    	printf("%s\n",p);
    	free(p);
    	return 0;	
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    命令行参数

    #include 
    
    int main( int argc, char *argv[] )  
    {
       if( argc == 2 )
       {
          printf("The argument supplied is %s\n", argv[1]);
       }
       else if( argc > 2 )
       {
          printf("Too many arguments supplied.\n");
       }
       else
       {
          printf("One argument expected.\n");
       }
    }
    
    //执行。argv[0]存储程序的名字,argv[1]存储第一个输入的参数
    $./a.out testing
    The argument supplied is testing
    
    $./a.out testing1 testing2
    Too many arguments supplied.
    
    $./a.out
    One argument expected
    
    $./a.out "testing1 testing2"
    
    Progranm name ./a.out
    The argument supplied is testing1 testing2
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    排序

    • 冒泡排序:略
    • 选择排序:略
    • 插入排序:略
    • 希尔排序:

    有待解决

    例子

    基础

    #两整数相除任然是整数。
    printf("%f",(float)(10/3));		//3.000000
    
    int *ptr;		//ptr:整型指针变量
    
    //后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
    0xFeeL      /* 合法的 */
    0x4b       /* 十六进制 */
    30u        /* 无符号整数 */
    30l        /* 长整数 */
    30ul       /* 无符号长整数 */
        
    #'\101'等价于0101
    '\101', '\x41', 'A'	//三者等价
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    变量修饰符

    //用循环函数检测使用时间
    time_t start,end;
    time(&start);
    		fori;
    time(&end);
    printf("%ld",start-end);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    函数

    #add.c
    #include 
    /*外部变量声明*/
    extern int x ;
    extern int y ;
    int add()
    {
        return x+y;
    }
    
    
    #test.c
    #include 
    /*定义两个全局变量*/
    int x=1;
    int y=2;
    int add();
    int main()
    {
        printf(" %d\n",add());
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    拓展

    编码

    1. ascii编码规则?常用字符?
    2. ANSI编码即扩展ascii编码。GB2312(94*94)三种编码方式、GBK用剩余的空间再进行编码、Big-5、JIS
    3. utf-8编码规则?

    格式化输出

    1. 整形输出:%ld %o %x %u %5d %05d %-5d
    2. 小数输出:%20.15f %-20.15f %e %g
    3. 字符输出:%5c
    4. 指针输出:%p
    5. 格式修饰符:l、 L、h、m.n、-

    visual stdio(vs)和vs code

    两者都是microsoft下

    vs:通俗的说是一个编译器。不可跨平台,是IDE,可以编译很多高级语言。

    vs code:通俗的说是一个编辑器。可跨平台,超级文本编辑器。

    vc(visual C++):编译器,只用于C/C++。

    问题

    1. 静态(static)和外部(extern)类型的数组元素初始化元素为0,自动(auto)类型的数组的元素初始化值不确定。


    /三者等价

    
    
    
    变量修饰符
    
    ```c
    //用循环函数检测使用时间
    time_t start,end;
    time(&start);
    		fori;
    time(&end);
    printf("%ld",start-end);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    函数

    #add.c
    #include 
    /*外部变量声明*/
    extern int x ;
    extern int y ;
    int add()
    {
        return x+y;
    }
    
    
    #test.c
    #include 
    /*定义两个全局变量*/
    int x=1;
    int y=2;
    int add();
    int main()
    {
        printf(" %d\n",add());
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    拓展

    编码

    1. ascii编码规则?常用字符?
    2. ANSI编码即扩展ascii编码。GB2312(94*94)三种编码方式、GBK用剩余的空间再进行编码、Big-5、JIS
    3. utf-8编码规则?

    格式化输出

    1. 整形输出:%ld %o %x %u %5d %05d %-5d
    2. 小数输出:%20.15f %-20.15f %e %g
    3. 字符输出:%5c
    4. 指针输出:%p
    5. 格式修饰符:l、 L、h、m.n、-

    visual stdio(vs)和vs code

    两者都是microsoft下

    vs:通俗的说是一个编译器。不可跨平台,是IDE,可以编译很多高级语言。

    vs code:通俗的说是一个编辑器。可跨平台,超级文本编辑器。

    vc(visual C++):编译器,只用于C/C++。

    问题

    1. 静态(static)和外部(extern)类型的数组元素初始化元素为0,自动(auto)类型的数组的元素初始化值不确定。

  • 相关阅读:
    ardupilot相机拍照控制
    Lyapunov稳定性分析3(离散时间系统)
    如何使用数据选择器配置日期筛选框?
    前端如何实现一个滚动的文本字幕
    电脑重装系统桌面图标变成白色文件怎么恢复?
    Vue 中 (moment)操作日期的加减与展示
    Python语法进阶(1)- 进程与线程编程
    【K8S】kubernetes集群架构与组件
    Yarn调度器
    uniapp开发ios上线(在win环境下使用三方)
  • 原文地址:https://blog.csdn.net/weixin_44042813/article/details/132723059