C高级(5)

目录

1.指针函数

2.函数指针

3.函数指针数组

4.共用体

5.枚举

6.存储类型

7.条件编译

7.1根据宏是否定义

7.2根据宏值

7.3防止头文件重复包含


1.指针函数

1.概念:

本质是函数,返回值是指针

2.格式:

数据数据 * 函数名(形参)

{

函数体

return 地址;//失败一般会返回NULL

}

2.函数指针

  1. 概念:本质是指针,指向的是函数
  2. 格式:

数据类型 (*指针名)(参数列表);

数据类型: 与指向函数的返回值类型保持一致

参数列表:与指向函数的参数列表保持一致

3.基本用法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int add(int a, int b)
{
    return a + b;
}

int sub(int a, int b)
{
    return a - b;
}
//2.函数指针作为另一个函数的参数,实现接口重用-->多态
int test(int (*p)(int ,int))
{
    printf("test:%d\n",p(3,4));
    return 0;
}

int main(int argc, char const *argv[])
{
    //1.函数指针
    int (*p)(int, int);
    p = add;
    printf("%d\n", p(2, 3));//5
    p = sub;
    printf("%d\n", p(2, 3));//-1
    test(add);//7
    test(sub);//-1
    return 0;
}

3.函数指针数组

1.概念:

本质是数组,数组中存放的是函数指针

2.格式:

数据类型 (*数组名[元素个数])(参数列表);

数据类型:和指向函数的返回值类型一致

参数列表:和指向的函数的参数列表一致

例子:

int (*arr[2])(int,int)={函数名,函数名}

4.共用体

所有成员变量共用一块地址空间

1.格式:

union 共用体名

{

成员列表;

};

2.定义共用体变量

union 共用体名字 变量名;

union value

{

int a;

char b;

};

union value val;

val.a=10;

val.b='a';

3.特性:

1)所有成员共用同一块地址空间

2)以最后一次赋值为内存中的实际数据

3)共用体的大小为成员中类型最大的数据的大小

用共用体测大小端

#include <stdio.h>
union value
{
    int a;
    char b;
};

int main(int argc, char const *argv[])
{
    // 1.强转测大小端
    //  int a = 0x12345678;
    //  char b = (char)a;

    // 2.共用体测大小端
    union value val;
    val.a = 0x12345678;
    if(val.b == 0x78)
        printf("小端\n");
    else if(val.b == 0x12)
        printf("大端\n");

    return 0;
}

typedef struct node

{

int a;

char b;

}NT,*NP;

NT == struct node

NP == struct node * == NT *

5.枚举

  1. 定义:一种构造数据类型,用于声明一组常数
  2. 格式:

enum 枚举类型名

{

常数1,

常数2,

};

#include <stdio.h>
enum week
{
    MON = 1,
    TUE = 4,
    WED,
};
int main(int argc, char const *argv[])
{
    int n;
    scanf("%d", &n);
    switch (n)
    {
    case MON:
        printf("1\n");
        break;

    default:
        printf("other\n");
        break;
    }
    return 0;
}

注意:没有赋初值时默认从0开始,向后依次递增

6.存储类型

1)auto

自动型,修饰局部变量,存放在栈区(一般省略)

2)static

静态型,可以修饰局部变量和全局变量,也可以修饰函数

1.存放在静态区/全局区,.bss(未初始化的全局变量和静态变量) .data(初始化的全局变量和静态变量)

2.初始值默认为0,只初始化一次

#include<stdio.h>
void fun()
{
    static int a;//只初始化一次
    a++;
    printf("%d\n",a);
}
int main(int argc, char const *argv[])
{
    fun();//1
    fun();//2
    return 0;
}

3.限制作用域 ,修饰全局变量被限制仅能在本文件中使用,修饰局部变量,作用域被限制在本函数中,但会延长其生命周期

4.修饰函数,被限制仅能在本文件中使用

3)extern

外部引用:可以引用其他文件中的全局变量和函数,在本文件中使用

num.c
#include<stdio.h>
//int n=10;
static int n=10;//加上static只能在本文件中使用,不能被外部引用
void fun()
{
    printf("hello\n");
}
main.c
#include<stdio.h>
extern int n; //外部引用num.c中的全局变量n
extern void fun();//外部引用num.c中的函数fun
int main(int argc, char const *argv[])
{
    fun();
    printf("n=%d\n",n);
    return 0;
}

3)register

寄存器类型,由于寄存器数量较少,申请不到空间时和auto一样

7.条件编译

7.1根据宏是否定义

#define 宏名

#ifdef 宏名

/*code1*/

#else

/*code2*/

#endif

执行顺序:判断宏是否定义,如果定义了就编译code1,否则编译code2

7.2根据宏值

#define 宏名 值

#if 宏名

/*code1*/

#else

/*code2*/

#endif

执行顺序:判断宏的值是否为0,如果不为0编译code1,否则编译code2

例:

7.3防止头文件重复包含

放在头文件中:

#ifndef 宏名

#define 宏名

/*code*/

#endif

例如:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值