【C语言】通识篇3

关键字

类型

C语言关键字是指在C语言的语法中具有特殊含义、被赋予特殊用途的标识符。这些关键字不能作为变量名、函数名或其他标识符的名称,因为它们已经被C语言用来表示特定的功能或含义

C语言有且只有32个关键字,这些关键字具有特定的含义和用法

auto  break  case  char  const  continue  default  do  double  else  enum  extern  float  for  goto   if  int  long  register  return  short  signed  sizeof  static  struct  switch  typedef  union  unsigned  void  volatile  while

除了这32个关键字外,还有一些被称为预处理指令的关键字,但它们并不是C语言中的真正的关键字

C语言被称为预处理指令的关键字列表:
#define:定义常量或宏
#include:包含头文件
#undef:取消已定义的宏
#ifdef:如果已定义了宏,则编译后面的代码
#ifndef:如果未定义宏,则编译后面的代码
#if:如果给定条件为真,则编译后面的代码
#else:如果前面的#if、#ifdef或#ifndef条件不成立,则编译后面的代码
#elif:如果前面的#if、ifdef或#ifndef条件不成立,但给定的条件为真,则编译后面的代码
#endif:结束一个#if、ifdef或#ifndef块
#error:输出错误信息并终止编译
#pragma:控制编译器行为的指示
这些预处理指令都以#号开头,并且在编译前进行处理,不会参与实际的程序运行

用户不能创造关键字

auto —— 自动

局部变量进入作用域自动创建,出作用域自动销毁,所以所有局部变量前面本身就有auto,所以干脆省略,表示自动创建自动销毁

auto int num1 = 0;
int num2 = 0;
//二者等价,一般省略auto

break —— 停止(用于循环和分支语句)

case —— 情况(用于switch分支语句)

char —— 字符型

const —— 修饰类型(使被修饰者具有常属性)

continue —— 继续(用于循环语句)

default —— 默认(用于分支语句)

do —— 做(使用于do while循环语句)

double —— 双精度浮点型

else —— 其他情况(使用于if else分支语句)

enum —— 枚举类型(自定义类型的一种)

extern —— 声明外部符号

float —— 单精度浮点型

for —— (for循环语句)

goto —— 跳转语句

if —— 如果(if else分支语句)

int —— 整形

long —— 长整型

register —— 寄存器(把值尽量放到寄存器里,方便快速调用)

return —— 返回值

short —— 短整型

signed —— 有符号的

sizeof —— 计算数据类型、变量、表达式在内存中占据的字节数

static —— 静态的

struct —— 结构体(自定义类型的一种)

typedef —— 类型重定义(重命名)

union —— 联合体类型(自定义类型的一种)

unsigned —— 无符号的

void —— 空(函数返回值/函数参数/修饰指针)

volatile —— 不稳定的

while —— 当…时(while循环语句)

typedef

类型重定义,用来给类型取别名

typedef unsigned int u_int;//将 unsigned int 重命名为 uint,之后可以直接使用 uint
typedef unsigned long long ull;
typedef struct Node
{
    int data;
    struct Node* next;
}Node;//把struct Node命名为Node

int main()
{
    unsigned int num1 = 10;
    u_int num2 = 10;//二者等价
    return 0;
}

register

寄存器

计算机的存储体系:

  1. 寄存器(集成在CPU)
  2. 高级缓存
  3. 内存
  4. 硬盘
  5. 网盘

越往上,速度越快,造价越高,空间越小

int num1 = 10;//4个字节
register int num2 = 20;//建议将20放在寄存器中,最终放不放由编译器决定。非常高频访问的变量可以去使用,目的是提高读写效率

static

静态的

  1. 修饰局部变量 —— 称为静态局部变量
  2. 修饰全局变量 —— 称为静态全局变量
  3. 修饰函数 —— 称为静态函数

修饰变量时,没有被初始化时会被自动初始化为0

static修饰局部变量

void test()
{
    int a = 5;//局部变量出作用域自动销毁,每次重新创建,a的地址理论上都会改变,除非编译器优化(VS)
    a++;
    printf("%d ", a);
}

int main
{
    int i = 0;
    while (i < 10)//输出6 6 6 6 6 6 6 6 6 6
    {
        test();
        i++;
    }
    return 0;
}
void test()
{
    static int a = 5;//出作用域不销毁,只初始化一次
    //a变量不是在代码执行过程中创建的,而是在编译期间就分配好空间,所以调试时会直接跳过
    a++;
    printf("%d ", a);
}

int main
{
    int i = 0;
    while (i < 10)//输出6 7 8 9 10 11 12 13 14 15
    {
        test();
        i++;
    }
    return 0;
}

临时作用的变量都在栈区,栈区被static修饰后的静态的局部变量放在了静态区,改变了变量的存储类型(位置);const修饰的变量不改变存储类型,还在原来的区域

内存大致分为三个区域:栈区,堆区,静态区

暂时无法在飞书文档外展示此内容

栈区上变量的特点:进入作用域创建,出作用域销毁(还给操作系统)

堆区用来做动态内存分配,malloccallocreallocfree这些函数在向内存申请空间是在堆区申请的

静态变量(被static修饰的变量)的特点:

  1. 生命周期:出作用域不销毁,直到程序结束才销毁(还给操作系统),生命周期变长
  2. 作用域:无变化
  3. 初始化:只在第一次调用该变量时进行初始化
  4. 记忆性:后续调用时,该变量使用前一次函数调用完成之后保存的值

static修饰全局变量

//a.c
extern int g_val;//需要声明变量类型和变量名

int main()
{
    printf("%d", g_val);
    return 0;
}
//b.c
int g_val = 2023;

说明全局变量具有外部链接属性,所以在其他源文件内部依然可以使用,全局变量作用域是整个工程(跨文件需要extern声明)

//a.c
extern int g_val;

int main()
{
    printf("%d", g_val);
    return 0;
}//报错
//b.c

static int g_val = 2023;//添加 static

static修饰全局变量的作用:

改变全局变量的链接属性,由外部链接属性变为内部链接属性,让该函数具有文件作用域,只能在当前文件中使用,感觉作用域变小(实际不变)

static修饰函数

static修饰函数和static修饰全局变量是一样的

//a.c
int main()
{
    int a = 10;
    int b = 20;
    int ret = Add(a, b);//警告:"Add"未定义
    printf("%d", ret);
    return 0;
}
//b.c
int Add(int x, int y)
{
    return (x + y);
}
//a.c
extern int Add(int x, int y);//需要声明函数返回类型、函数名、函数参数
extern int Add(int, int);//可以省略形参名
int Add(int x, int y);//不使用extern也可以,一般加上

int main()
{
    int a = 10;
    int b = 20;
    int ret = Add(a, b);//无警告
    printf("%d", ret);
    return 0;
}
//b.c
int Add(int x, int y)
{
    return (x + y);
}
//a.c
extern int Add(int x, int y);

int main()
{
    int a = 10;
    int b = 20;
    int ret = Add(a, b);//报错:无法解析的外部符号
    printf("%d", ret);
    return 0;
}
//b.c
static int Add(int x, int y)
{
    return (x + y);
}

函数具有外部链接属性,但被static修饰后,变为内部链接属性

static修饰函数的作用:

改变该函数的链接属性,由外部链接属性变为内部链接属性,让该函数具有文件作用域,只能在当前文件中使用,感觉作用域变小(实际不变)

编译(CTRL + F7,可以看是否出现错误和警告)+链接+执行

警告:返回值被忽略:“scanf”

解决方法:

int a = 0;
int n = scanf("%d", &a);//接收scanf返回值

解决方案、项目、文件的区别:

创建解决方案时默认创建一个项目,一个解决方案可以创建多个项目,一个项目里面可以创建多个源文件、头文件

想编译哪个项目就设置哪个项目为启动项,项目之间不能互相调用

自定义类型gpt补充

在 C 语言中,可以使用typedef关键字来定义新类型。C语言中的自定义类型有以下几种:

  1. 结构体(struct

结构体是 C 语言中一种自定义复合类型,它由多个不同类型的数据成员组成,可以用于表示一个实体的多个属性。结构体的定义方式如下:

typedef struct {
    数据类型 成员1;
    数据类型 成员2;
    ...
} 结构体标识符;

其中,数据类型可以是基本类型、指针类型或其他结构体类型。例如,以下代码定义了一个表示学生信息的结构体类型Student

typedef struct {int id;
    char name[20];
    double score;
} Student;
  1. 枚举类型(enum

枚举类型是C语言中一种自定义离散类型,它由一组具有相同性质(如颜色、星期)的常量组成。枚举类型的定义方式如下:

typedef enum {
    标识符1 = 常量值1,
    标识符2 = 常量值2,
    ...
} 枚举类型标识符;

其中,常量值可以是整数、字符等类型的常量表达式。例如,以下代码定义了一个表示星期的枚举类型Weekday

typedef enum {
    MONDAY = 1,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
} Weekday;

在这个例子中,枚举类型Weekday由七个常量组成,分别表示星期一到星期日

  1. 联合类型(union

联合类型是C语言中一种自定义复合类型,它与结构体相似,但联合体中的所有成员共用同一块内存空间。联合类型的定义方式如下:

typedef union {
    数据类型 成员1;
    数据类型 成员2;
    ...
} 联合类型标识符;

其中,数据类型可以是基本类型、指针类型或其他结构体类型。例如,以下代码定义了一个表示颜色的联合类型Color

typedef union {int rgb;         // 整数值表示的RGB颜色char name[20];   // 颜色名称
} Color;

在这个例子中,联合类型Color可以用一个整数值或一个字符串来表示颜色

  1. 指针类型(*)

指针类型是C语言中一种自定义类型,它用于存储另一种类型的地址。指针类型的定义方式如下:

typedef 数据类型 *指针类型标识符;

其中,数据类型可以是基本类型、结构体类型、联合类型等。例如,以下代码定义了一个指向学生信息结构体类型Student的指针类型StudentPtr

typedef struct {int id;
    char name[20];
    double score;
} Student;

typedef Student *StudentPtr;

在这个例子中,指针类型StudentPtr可以用来存储指向学生信息结构体的地址

快捷键

HOME跳到本行最后位置

END调光本行最初位置

SHIFT+←/→多个选中

CTRL+X剪切本行,接着CTRL+V粘贴到上一行

CTRL+D复制本行到下一行

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值