C语言的初步学习理解

(一)C的基本类型:包括两种类型:整数类型和浮点类型。

类型 存储大小 值范围
char 1 字节 -128 到 127或 0 到 255
unsigned char 1 字节 0 到 255
signed char 1 字节 -128 到 127
int 2 或 4 字节 -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
unsigned int 2 或 4 字节 0 到 65,535 或 0 到 4,294,967,295
short 2 字节 -32,768 到 32,767
unsigned short 2 字节 0 到 65,535
long 4 字节 -2,147,483,648 到 2,147,483,647
unsigned long 4 字节 0 到 4,294,967,295
float 4 字节 1.2E-38 到 3.4E+38 6 位小数
double 8 字节 2.3E-308 到 1.7E+308 15 位小数
long double 16 字节 3.4E-4932 到 1.1E+4932 19 位小数
注意,各种类型的存储大小与系统位数有关,但目前通用的以64位系统为主。您可以使用 sizeof 运算符。
表达式 sizeof(type) 得到对象或类型的存储字节大小。

计算各数据类型存储大小

#include <stdlib.h>

int main()
{
    char c = 'a';
    short i = 88;
    int k = 888;
    long m = 9999;
    float f = 1.28f;
    double d = 3.689;

    printf("char内存大小:%d\n",sizeof(c));
    printf("short内存大小:%d\n", sizeof(i));
    printf("int内存大小:%d\n", sizeof(k));
    printf("long内存大小:%d\n", sizeof(m));
    printf("float内存大小:%d\n", sizeof(f));
    printf("double内存大小:%d\n", sizeof(d));

    system("pause");
    return 0;
}

(二)枚举类型:它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。

enum{
    monday=10,//默认为0 赋值后为10
    saturday//默认为1 赋值后为11
};
int main(){
    printf("%d \n",monday);
    system("pause");
    return 0;
}

(三)void类型:类型说明符 void 表明没有可用的值。
通常用于以下三种情况下:
1.函数返回为空 例如 void exit (int status);
2.函数参数为空 例如 int rand(void);
3.指针指向 void 例如,内存分配函数 void *malloc( size_t size )
(四)派生类型:指针类型、数组类型、结构类型、共用体类型和函数类型。

printf()函数
printf() 用于格式化输出到屏幕。printf() 函数在 “stdio.h” 头文件中声明。
printf()函数的调用格式为:printf(“<格式化字符串>”, <参量表>);
输出格式如下:
d 以十进制形式输出带符号整数(正数不输出符号)
o 以八进制形式输出无符号整数(不输出前缀0)
x,X 以十六进制形式输出无符号整数(不输出前缀Ox)
u 以十进制形式输出无符号整数
f 以小数形式输出单、双精度实数
e,E 以指数形式输出单、双精度实数
g,G 以%f或%e中较短的输出宽度输出单、双精度实数
c 输出单个字符
s 输出字符串
p 输出指针地址
lu 32位无符号整数

数组的定义

// C 语言的数组,在申明的时候就必须确定大小和基本类型。
int[10] intArray; //java
int intArray[10]; //C
数组是存储在stack 栈 ,stack的大小是有限制的,超过限制则需要动态申请数组存放在堆里面
//申请40M数组空间 4byte *1024 *1024 *10 = 40M
int intArray=(int )malloc(sizeof(int) * 1024 * 1024 * 10);

指针

int main(){
    int a = 10;
    int * p=&a;//p代表int *指*p代表int型数据a的值
    *p = *p + 10;

    printf("*p:%d,a:%d\n",*p,a);
    int y = 1 + *p;
    printf("y:%d\n",y);
    *p += 1;
    printf("*p:%d,a:%d\n", *p, a);

    (*p)++;//*p所指向的内存地址的变量值 加1
    printf("*p:%d,a:%d ,p的地址:%#x\n", *p, a,p);
    *p++;//p的值 内存地址增加一个类型单位
    printf("*p:%d,a:%d ,p的地址:%#x\n", *p, a, p);

    system("pause");
    return 0;
}

输出值为:

*p:20,a:20
y:21
*p:21,a:21
*p:22,a:22p的地址:0xeffe84
*p:-858993460,a:22p的地址:0xeffe88

注意:& 取地址操作符。运用在内存中的对象上面,即变量与数组元素
* 间接寻址或者引用运算符
运算符的优先级

数组与指针

注意:数组变量名就是数组的首地址,通过数组下标所能完成的任何操作都可以通过指针来实现。

int main(){

    int a[5];
    int *p = a;//将指针p指向数组的首地址
    int i;

    //a+5表示a移动到数组的第五个位置 每移动一个地址的长度为变量类型所占的位数 并不是数字加1
    //通过指针给数组赋值
    for ( i = 0; p < a+5; p++)
    {
        *p = i;
        i++;
    }
    //打印数组元素
    for ( i = 0; i < 5; i++)
    {
        printf("a[%d]:%d \n",i,a[i]);
    }
    system("pause");
    return 0;
}

指针变量

int main(){

    int a = 10;
    int *p = &a;
    //p存储的是变量a的内存地址
    printf("p的值:%#x\n",p);
    p++;//这里p存储的内存地址增加了一个int型大小的值 int 4字节 p的值+4
    printf("p的值:%#x\n", p);

    char c = 'a';
    char *cp = &c;
    printf("cp的值:%#x\n", cp);
    cp++;//这里char 代表一个字节 cp的值+1
    printf("cp的值:%#x\n", cp);

    system("pause");
    return 0;
}

输出值如下:

p的值:0xcffb8c
p的值:0xcffb90
cp的值:0xcffb77
cp的值:0xcffb78

指针和函数参数

实现两个数的交换

//c语言中函数 参数为值传递 a,b为新的变量与调用函数时的a,b不相同 不能实现交换原值
void swap(int a,int b){
    int temp;
    temp = a;
    a = b;
    b = temp;
}
//将对指针变量a,b的地址进行了切换 指针指向内存地址的值没有改变
void swap2(int * a,int *b){
    int *temp;
    temp = a;
    a = b;
    b = temp;
}
//将指针a,b所指向内存地址上面的值进行了改变 可以实现交换
void swap3(int * a, int *b){
    int temp;
    temp = *a;
    *a = *b;//将指针a所指向的内存地址上的值 修改为指针b所指向的变量的值
    *b = temp;
}
int main(){
    int a, b;
    a = 10;
    b = 5;

    printf("a:%d,b:%d\n",a,b);
    swap(a,b);//c值传递 不能实现交换
    printf("交换后的值a:%d,b:%d \n", a, b);
    swap2(&a,&b);//不能实现交换
    printf("交换后的值a:%d,b:%d \n", a, b);
    swap3(&a, &b);//交换成功
    printf("交换后的值a:%d,b:%d \n", a, b);
    system("pause");
    return 0;
}

输出值为:

a:10,b:5
交换后的值a:10,b:5
交换后的值a:10,b:5
交换后的值a:5,b:10

注意:函数必须先声明再使用或者函数定义在使用的前面,才能正确调用

指针数组和数组指针

指针数组: 是一个数组 里面存储的是指针类型的数据
数组指针: 是一个指针 ,这个指针指向了数组的首地址
指针数组和数组指针

//函数先声明再使用
void sort(char*name[],int n);
int main(){
    //定义指针数组 存储的是char类型指针的一组数据
    char *name[] = {"sxx","dss","bww","wee"};
    sort(name,4);
    //打印排序后的数组
    for (int i = 0; i < 4; i++)
    {
        printf("%s\n",name[i]);
    }
    //数组指针 指针p2指向的数组的首地址
    char c[5] = {'a','b','c','d','e'};
    //char(*p2)[5] = c;//c数组第一个元素的首地址
    char(*p2)[5] = &c;//&c 是整个数组的首地址 
    system("pause");
    return 0;
}
//冒泡排序
void sort(char *name[], int n){
    char *temp;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n-1-i; j++)
        {
            //strcmp字符串首字母比较大小
            if (strcmp(name[j],name[j+1])>0){
                temp = name[j];
                name[j] = name[j + 1];
                name[j + 1] = temp;
            }
        }
    }
}

二级指针

二级指针,存储的值是一个一级指针的内存地址

int main(){

    int a = 100;
    int *p=&a;
    //二级指针存储的是一级指针地址 *p2得到的是p的值 **p2得到的是a的值
    //**p2==*(*p2)==*p==a
    int **p2 = &p;

    printf("a的值:%d\n",a);
    printf("*p的值:%d\n",*p);
    printf("**p2的值:%d\n",**p2);

    system("pause");
    return 0;
}

输出值为:

a的值:100
*p的值:100
**p2的值:100

函数指针

函数名是函数在内存中的首地址,可以将函数赋值给对应类型的指针
void 类型的指针:类似于java object
void* 包括 int * / char * /float*等

int plus(int a,int b){
    return a + b;
}
int minus(int a,int b){
    return a - b;
}
int plus2(int *a,int *b){
    return *a + *b;
}
int minus2(char *a,char *b){
    return 0;
}
int main(){
    int a = 8;
    int b = 10;
    int result;
    //函数指针
    int(*calc)(int a, int b);
    int(*calc2)(void *a,void*b);
    //calc = plus;
    calc = minus;
    result = calc(3, 5);
    //calc2 = (int(*)(void *,void *))plus2;//将void*强制类型转换int*
    calc2 = (int (*)(void *, void *))minus2;
    result = calc2(&a,&b);
    printf("minus:%#x\n", minus);
    printf("result:%d\n", result);
    system("pause");
    return 0;
}

注意:下面两个表达式完全不同 取决于运算符优先级
int (calc2) (void *a, void ); //函数指针
int* p(int a, int b); //一个返回值是int * 的函数 等同于(int*) p(int a, int b)

内存分配

分成三个区存储
程序区:存储程序代码二进制文件
静态存储区:存储全局变量和静态变量
动态存储区:
栈区:内存由编译器自动分配,自动释放
堆区:主要用于程序动态分配内存控件,需要手动释放内存

动态申请内存的方法
void* malloc(size_t size)//分配内存的单元是 字节, 大小 size,分配连续的内存如果申请失败,返回值是NULL
void* calloc(size_t _Count,size_t _Size)//申请 _Count 个 大小为_Size 的连续空间,这个连续空间的大小是_Size,整块空间可能不连续,如果申请失败,返回值是NULL
同时,它会初始化值为0
void * realloc(void * ptr, int len); //不常用
动态申请的内存一定要收到释放
free(*p)释放内存
注意:申请的内存必须手动释放,并置为NULL,不能重复释放 ,申请和释放要一一对应

C语言中的字符串

c语言中没有字符串类型,c语言中的字符串都用字符数组和字符指针表示

操作字符串方法

char *strcpy(char *destin, char *source);
拷贝一个字符串到另一个
char *strcat(char *destin, char *source);
字符串拼接函数
char *strchr(char *str, char c);
在一个串中查找给定字符的第一个匹配之处
int strcmp(char *str1, char *str2);
串比较 看Asic码,str1>str2,返回值 > 0;两串相等,返回0
int strncmpi(char *str1, char *str2, unsigned maxlen);
将一个串中的一部分与另一个串比较, 不管大小写
int stricmp(char *str1, char *str2);
以大小写不敏感方式比较两个串
int strcspn(char *str1, char *str2);
在串中查找第一个给定字符集内容的段
char *strdup(char *str);
将串拷贝到新建的位置处
char *strerror(int errnum);
返回指向错误信息字符串的指针
char *strnset(char *str, char ch, unsigned n);
将一个串中的所有字符都设为指定字符
char *strpbrk(char *str1, char *str2);
在串中查找给定字符集中的字符
char *strrchr(char *str, char c);
在串中查找指定字符的最后一个出现
char *strrev(char *str);
串倒转
double strtod(char *str, char **endptr);
将字符串转换为double型值
long strtol(char *str, char **endptr, int base);
将串转换为长整数
char *strupr(char *str);
将串中的小写字母转换为大写字母
void swab (char *from, char *to, int nbytes);
交换字节

int main(){
    //'\0'表示结束 不再读取后面的字符
    char ch[] = { 'c', 'h', 'i', 'n', 'a', '\0' };
    char ch1[10] = {'c','h','i','n','a','\0','r'};
    char ch2[20] = "china";//编译器默认会在末尾添加‘\0’
    ch2[0] = 's';//改变元素值

    /*char * ch3 = "china";
    //系统分配一个常量区 , char * ch3没有初始化, 将常量区 "china"的首地址赋值给ch3
    //这里不能对ch3的内容进行修改 因为ch3中存储的是常量,常量是不可修改的
    ch3[0] = 's';*/
    //初始化一个指针
    char * ch3 = (char *)malloc(sizeof(char));
    //使用strcpy方法给ch3赋值
    strcpy(ch3,"china");
    ch3[0] = '2';

    printf("ch:%s\n",ch);
    printf("ch1:%s\n", ch1);
    printf("ch2:%s\n", ch2);
    printf("ch3:%s\n", ch3);

    system("pause");
    return 0;
}

输出内容如下:

ch:china
ch1:china
ch2:shina
ch3:2hina

结构体

一系列不同类型的数据的结合
结构体名代表的只是结构体类型,没有内存空间, 结构体中的成员可以单独使用

struct Student
{
    char name[20];
    int age;
} Lucy = {"Lucy",20};//全局
//匿名结构体 锁定结构体的变量数量 只能在定义时声明变量
struct
{
    char name[20];
    int age;
    int classId;
} stu3,stu4;

int main(){
    //结构体初始化
    struct Student stu1 = {"Lucy",20};
    struct Student stu2;
    strcpy(stu2.name, "张三");
    stu2.age = 88;

    printf("%s,%d \n",stu1.name,stu1.age);
    printf("%s,%d \n", stu2.name, stu2.age);
    system("pause");
    return 0;
}

结构体数组

struct Student{
    char name[20];
    int age;
};
int main(){
    //以结构体数据为单位根据数据位置匹配
    struct Student stu[3] = { { "lucy", 30 }, { "lilei", 32 }, { "hann", 35 } };
    struct Student s[5];
    //结构体数组赋值
    for (int i = 0; i < 5; i++)
    {
        s[i].age = 100 + i;
        strcpy(s[i].name,"aa");
    }
    //输出结构体数组的值
    for (int i = 0; i < 5; i++)
    {
        printf("name:%s,age:%d\n",s[i].name,s[i].age);
    }
    system("pause");
    return 0;
}

结构体指针

struct Student{
    char name[20];
    int age;
};
int main(){
    struct Student stu[3] = { { "lucy", 30 }, { "lilei", 32 }, { "hann", 35 } };
    //结构体指针
    //struct Student *stud=stu;
    //初始化结构体指针
    struct Student *stud;
    stud = (struct Student *)malloc(sizeof(struct Student) * 4);
    printf("%#x",stud);
    memset(stud,0,sizeof(struct Student)*4);//赋值为0

    for (int i = 0; i < 4; i++)
    {
        //给结构体成员age赋值 ->
        (stud+i)->age = 100 + i;
        //给结构体成员name赋值 ->
        strcpy((stud+i)->name, "bb");
        /*stud[i].age = 100 + i;
        strcpy(stud[i].name,"cc");*/
    }
    for (int i = 0; i <4; i++)
    {
        printf("name:%s,age:%d\n", (stud+i)->name, (stud+i)->age);
    }

    system("pause");
    return 0;
}

在结构体中添加函数指针成员变量

struct Man{
    int age;
    char *name;
    int(*Msg)(char *,int);//函数指针
};
//打印信息
int message(char*str,int age){
    printf("str:%s,age:%d\n",str,age);
    return 0;
}
int main(){
    struct Man man;
    man.age = 40;
    man.name = "李健";
    man.Msg = message;//将函数首地址函数名message赋值给指针
    //调用函数
    man.Msg(man.name,man.age);

    system("pause");
    return 0;
}

在结构体中添加结构体指针变量
实现单链表

//定义一个结构体
struct Node{
    int data;
    Node * next;//结构体指针
};
//在单链表的末尾添加一个数据
int enqueNode(Node * head,int data){
    //创建新的节点
    struct Node * node = (struct Node *)malloc(sizeof(struct Node));
    //可能申请不到内存 判空
    if ( node == NULL){
        return 0;
    }
    //给新节点赋值next 为NULL代表是最后一个节点
    node->data = data;
    node->next = NULL;

    //找到最后一个节点
    Node *p = head;
    while (p->next!=NULL){
        p=p->next;//切换到下一个节点
    }
    //将找到的最后一个节点next指向新建的节点
    p->next = node;

    return 1;
}
int main(){

    Node * list;
    list = (Node*)malloc(sizeof(Node));
    list->data = 0;
    list->next = NULL;
    //从最后添加数据
    for (int i = 0; i < 10; i++)
    {
        enqueNode(list,i+1);
    }
    //遍历打印数据
    while (list->next != NULL){
        printf("%d\n",list->data);
        list = list->next;
    }
    system("pause");
    return 0;
}

typedef指令

取别名,并没有创建新的数据类型,只是给现有类型创建了别名

typedef int _in;
typedef char * string;//定义一个string字符串别名

typedef int(*PFI)(char *, char *);
typedef Tnode * Treeptr;
int fun(char *, char *){
    return 0;
};
typedef struct Tnode{
    char *word;
    int count;

    /*Tnode * left;
    Tnode * right;*/
    Treeptr left;
    Treeptr right;
} BinaryTreeNode;//结构体别名
int main(){

    _in a = 20;
    printf("a:%d\n",a);

    string str = "hello world";
    printf("str:%s\n", str);

    PFI pf= fun;

    BinaryTreeNode *node = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));;
    system("pause");

    return 0;
}

union共用体

将不同的数据类型数据放在同一块内存上 占用内存为成员中占用最大的那一个内存 大小

//占用的内存为f占用的内存大小
union MyUnion{
    int a;
    char c;
    float f;
};
int main(){
    MyUnion uni;

    uni.a = 10;
    uni.c = 'a';//覆盖之前a的值
    uni.f = 1.33f;//覆盖之前a,c值
    //成员之间存储内存地址相同
    printf("a:%#x,c:%#x,f:%#x \n",&uni.a,&uni.c,&uni.f);
    printf("a: %d, c: %c, f:%f \n", uni.a, uni.c, uni.f);
    system("pause");
    return 0;
}

文件操作

文件分两部分:1.控制信息 2.内容信息;文本文件图片文件等都是二进制文件
读取文件过程:从磁盘上读取 根据文件控制信息解码到文件缓冲区 再加载到内存空间
文本文件读取操作

int main(){
    //文件读取
    char * path = "C:\\Users\\lenovo\\Desktop\\test.txt";
    //如果存在文件则打开,不存在则新建文件 path文件路径 "r"表示读文件操作
    FILE *fp = fopen(path,"r");

    char buff[1024];
    //fgets获取内容 存储到buff数组中 每次获取1024个单位数据
    while (fgets(buff, 1024, fp))
    {
        printf("%s",buff);
    }
    //关闭文件流
    fclose(fp);

    //写文件
    char * path = "C:\\Users\\lenovo\\Desktop\\test.txt";
    //如果存在文件则打开,不存在则新建文件 path文件路径 "w"表示写文件操作
    FILE *fp = fopen(path, "w");
    if (fp==NULL){
        printf("file is null");
        return 0;
    }
    char *text = "今天下大雨,冷哦";
    //写入文本
    fputs(text,fp);
    //关闭文件流
    fclose(fp);

    system("pause");
    return 0;
}

二进制文件读写操作

int main(){

    char * read_path = "C:\\Users\\lenovo\\Desktop\\LogViewPro.exe";
    char * write_path = "C:\\Users\\lenovo\\Desktop\\LogViewPro_write.exe";
    //获取需要读取的文件 rb读二进制文件 wb写二进制文件 
    FILE *readFile = fopen(read_path,"rb");
    FILE *writeFile = fopen(write_path,"wb");

    char buff[50];
    int len = 0;
    //fread读取文件
    while ((len = fread(buff, sizeof(char), 50, readFile))!=0)
    {   //fwrite写入文件 每次写入的长度为读取的数据长度
        fwrite(buff,sizeof(char),len,writeFile);
    }
    //关闭文件流
    fclose(readFile);
    fclose(writeFile);
    system("pause");
    return 0;
}

获取文件大小

int main(){

    char * read_path = "C:\\Users\\lenovo\\Desktop\\a.jpg";
    FILE *fp = fopen(read_path,"r");
    if (fp==NULL){
        return 0;
    }
    //fseek移到文件末尾(SEEK_END)并偏移0 指向文件末尾
    fseek(fp,0,SEEK_END);
    //fseek移动到相对于SEEK_SET位置偏移100
    //fseek(fp,100,SEEK_SET);
    //通过ftell获取文件大小
    long fileSize = ftell(fp);
    printf("%ld\n",fileSize);

    system("pause");
    return 0;
}

对文件简单的加密解密实例

void encode(char normal_path[],char encode_path[]){

    FILE* normal_fp = fopen(normal_path,"r");
    FILE* encode_fp = fopen(encode_path,"w");

    int ch;
    //循环判断是否到文件末尾
    while ((ch=fgetc(normal_fp))!=EOF)
    {
        fputc(ch^7,encode_fp);
    }
    fclose(normal_fp);
    fclose(encode_fp);
}
void decode(char encode_path[], char decode_path[]){

    FILE* encode_fp = fopen(encode_path, "r");
    FILE* decode_fp = fopen(decode_path, "w");

    int ch;
    //循环判断是否到文件末尾
    while ((ch = fgetc(encode_fp)) != EOF)
    {
        fputc(ch ^ 7, decode_fp);
    }
    fclose(decode_fp);
    fclose(encode_fp);
}
int main(){
    char *normal_path = "C:\\Users\\lenovo\\Desktop\\test.txt";
    char *encode_path = "C:\\Users\\lenovo\\Desktop\\test_encode.txt";
    char *decode_path = "C:\\Users\\lenovo\\Desktop\\test_decode.txt";
    encode(normal_path,encode_path);
    decode(encode_path,decode_path);
    system("pause");
    return 0;
}

预处理

C 语言执行的流程:
一,组成程序的每个源文件通过编译过程分别转换成目标代码(object code)
二,各目标文件由连接器 捆绑在一起,形成一个单一而完整的可执行文件

而编译过程又由如下过程组成:
1.预处理器处理,在这个阶段,预处理器在源代码上执行一些文本操作。例如:用实际值代替由 #define指令定义的符号以及读入由#include指令包含的文件的内容。
2.源代码经过解析,判断它的语句的意思,这个阶段会产生绝大多数错误和警告信息的地方,随后便生成目标代码。

执行阶段:
1.程序必须载入到内存中。
2.程序执行
3.程序执行的最后一个阶段就是程序终止。

Define指令
定义:”#define 标识符 字符串”
“#define宏名(参数) 字符串”
意义:就是宏替换的作用,让 标识符替换 字符串,这只是一种简单的文本替换,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。
注意事项:
宏名一般用大写字母表示,以便于与变量区别。
宏定义末尾不必加分号,否则连分号一并替换。
宏定义可以嵌套。
宏定义不分配内存,变量定义分配内存。
预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。

“#include <> 或者 #include “” 区别”
< > 和 “ ” 区别在于: 使用<>表示在包含文件目录中去查找 (包含目录是由用户在设置环境时设置的include 目录“解决方案管理器 -> 属性-> 配置属性 -> VC++ 目录”),而不是在当前源文件目录去寻找; 使用双引号就是先从当前源文件目录中查找。

条件编译
“#ifdef #endif 成对出现”
第一种方式
“#ifdef 标识符 (或者#if defined)”
程序段1
“#else ”
程序段2
“#endif”
或者
“#ifdef 标识符 (或 #if defined 标识符)”
程序段
“#endif”

第二种方式
“#ifndef”
#else
“#endif”

第三种方式
“#if”
“#else”
“#endif”

在实践中的作用:
1.屏蔽跨平台差异
在大规模开发过程中,特别是跨平台和系统的软件里,可以在编译时通过条件编译设置编译环境。
“#ifdef WINDOWS”
#define MYTYPE long
“#else”
#define MYTYPE float
“#endif”

2.包含程序功能模块
“#ifdef FLV”
Include “fastleavec”
“#endif”
当不许向别的用户提供该功能,则在编译之前将首部的FLV 加一下横线即可

3.开关调试信息
4.避开硬件的限制
有时一些具体的应用环境的硬件不同,但限于条件本地缺乏这种设备,可绕过硬件直接写出预期结果
5.防止头文件重复包含
头文件可以被头文件或者C文件包含。由于头文件包含可以嵌套,C文件就有可能多次包含同一个文件; 或者不同的C文件都包含同一个头文件,编译时就可能出现重复包含的问题。

#include "A.txt"//自定义头文件
#define NUM 5//宏定义 等价替换 NUM=5
#define MAX(x,y) (x>y?x:y)//将MAX(x,y)替换成(x>y?x:y)
#define M 10
//条件编译
//#ifndef M
#ifdef M
    printf("%d\n",110);
#else
    printf("%d\n",120);
#endif
    printf("结束");

int main(){

    for (int i = 0; i < NUM; i++)
    {
        printf("%d\n",i);
    }
    int max = MAX(8,5);
    printf("max:%d\n", max);

    system("pause");
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值