【C语言】根本语法布局篇

[复制链接]
发表于 2025-10-22 00:37:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
步伐布局

头文件包罗(#include)



  • 功能与用途:头文件包罗指令是 C 语言中用于模块化和代码复用的告急机制。它答应我们将常用的函数声明、宏界说和范例界说等会合存放在一个文件中,然后在须要利用这些内容的源文件里通过 #include 指令将其引入。
  • 标准库头文件:标准库头文件由 C 语言标准规定,包罗了浩繁实用的函数和范例声明。比方:

    • stdio.h:提供了标准输入输出函数,像 printf、scanf、fopen 等。
    • stdlib.h:包罗了动态内存分配函数(如 malloc、free)、随机数天生函数(如 rand)和步伐停止函数(如 exit)等。
    • string.h:界说了一系列用于字符串处置惩罚的函数,比方 strcpy、strlen、strcmp 等。

  • 自界说头文件:当我们在项目中编写了一些通用的函数或数据布局时,可以将其声明放在自界说头文件中。自界说头文件通常利用 .h 作为扩展名,利用双引号 “” 包罗。比方,创建一个名为 myheader.h 的头文件:
  1. // myheader.h
  2. #ifndef MYHEADER_H
  3. #define MYHEADER_H
  4. int add(int a, int b);
  5. #endif
复制代码
在源文件中利用该头文件:
  1. // main.c
  2. #include "myheader.h"
  3. #include <stdio.h>
  4. int add(int a, int b) {
  5.     return a + b;
  6. }
  7. int main() {
  8.     int result = add(3, 5);
  9.     printf("Result: %d\n", result);
  10.     return 0;
  11. }
复制代码


  • 头文件掩护:为了防止头文件被重复包罗,通常会利用预处置惩罚器指令 #ifndef、#define 和 #endif 来创建头文件掩护。如上述 myheader.h 中的示例,通过界说一个唯一的宏 MYHEADER_H,可以克制头文件被多次包罗导致的重复界说错误。
main() 函数

函数界说与返回值:main() 函数是 C 步伐的入口点,步伐从这里开始实行。它有两种常见的界讨情势:


  • int main():这种情势表现 main 函数不继承任何参数,返回一个整数值。返回值通常用于表现步伐的退出状态,0 表现步伐正常退出,非零值表现步伐非常退出。
  • int main(int argc, char *argv[]):argc 表现下令行参数的数目,argv 是一个指向字符串数组的指针,存储了每个下令行参数。比方:
  1. #include <stdio.h>
  2. int main(int argc, char *argv[]) {
  3.     if (argc > 1) {
  4.         printf("You provided %d arguments:\n", argc - 1);
  5.         for (int i = 1; i < argc; i++) {
  6.             printf("%s\n", argv[i]);
  7.         }
  8.     } else {
  9.         printf("No arguments provided.\n");
  10.     }
  11.     return 0;
  12. }
复制代码
步伐实行流程:当步伐启动时,利用体系会调用 main 函数,main 函数中的代码按序次实行。当 main 函数实行完毕并返回一个值后,步伐竣事,返回值会转达给利用体系。
解释(// 和 /* */)

单行解释(//):用于对代码的某一行或某一部门举行简短的阐明。单行解释从 // 开始,到该行竣事为止。比方:
  1. // 这是一个简单的加法函数
  2. int add(int a, int b) {
  3.     return a + b; // 返回两数之和
  4. }
复制代码
多行解释(/* /):实用于对一段代码举行具体的阐明,大概暂时禁用一段代码。多行解释以 / 开始,以 */ 竣事,可以凌驾多行。比方:
  1. /*
  2. * 这是一个更复杂的函数
  3. * 它接受两个整数作为参数
  4. * 并返回它们的乘积
  5. */
  6. int multiply(int a, int b) {
  7.     return a * b;
  8. }
复制代码
变量与常量

界说与初始化

变量界说:在 C 语言中,变量必须先界说后利用。变量界说的一样平常情势为:数据范例 变量名;。比方:
  1. int num; // 定义一个整型变量 num
  2. char ch; // 定义一个字符型变量 ch
  3. float f; // 定义一个单精度浮点型变量 f
  4. double d; // 定义一个双精度浮点型变量 d
复制代码
变量初始化:变量初始化是在界说变量的同时为其赋初值。可以利用直接赋值、表达式赋值等方式举行初始化。比方:
  1. int age = 25; // 直接赋值初始化
  2. float radius = 3.14f * 2; // 表达式赋值初始化
复制代码
未初始化变量:如果界说变量时没有举行初始化,那么变量的值是未界说的,大概包罗恣意的垃圾值。在利用未初始化的变量之前,最好先给它赋值,否则大概会导致不可预期的效果。
作用域(全局变量、局部变量)

全局变量:全局变量界说在函数外部,具有全局作用域,即可以在步伐的任何函数中访问。全局变量在步伐启动时被创建,在步伐竣事时被烧毁。比方:
  1. #include <stdio.h>
  2. // 全局变量
  3. int global_var = 10;
  4. void func() {
  5.     printf("Global variable in func: %d\n", global_var);
  6. }
  7. int main() {
  8.     printf("Global variable in main: %d\n", global_var);
  9.     func();
  10.     return 0;
  11. }
复制代码
局部变量:局部变量界说在函数内部或代码块内部,具有局部作用域,只能在界说它的函数或代码块内部访问。局部变量在函数或代码块实行时被创建,实行竣事后被烧毁。比方:
  1. #include <stdio.h>
  2. void func() {
  3.     // 局部变量
  4.     int local_var = 20;
  5.     printf("Local variable in func: %d\n", local_var);
  6. }
  7. int main() {
  8.     func();
  9.     // 下面这行代码会导致编译错误,因为 local_var 是 func 函数的局部变量
  10.     // printf("Local variable in main: %d\n", local_var);
  11.     return 0;
  12. }
复制代码
变量的生命周期:全局变量的生命周期贯穿整个步伐的实行过程,而局部变量的生命周期仅限于其地点的函数或代码块的实行期间。
常量



  • 字面常量:字面常量是直接出如今代码中的常量值,如整数常量(10、-20)、浮点常量(3.14、2.718)、字符常量(‘A’、‘b’)和字符串常量(“Hello, World!”)等。
  • const 修饰的常量:利用 const 关键字可以界说常量,一旦界说,其值不能被修改。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     const int MAX_VALUE = 100;
  4.     // 下面这行代码会导致编译错误,因为 MAX_VALUE 是常量,不能被修改
  5.     // MAX_VALUE = 200;
  6.     printf("Max value: %d\n", MAX_VALUE);
  7.     return 0;
  8. }
复制代码


  • 宏界说常量:利用 #define 预处置惩罚器指令可以界说宏常量。宏常量在预处置惩罚阶段会被直接更换为其对应的值。比方:
  1. #include <stdio.h>
  2. #define PI 3.14159
  3. int main() {
  4.     float radius = 5.0;
  5.     float area = PI * radius * radius;
  6.     printf("Area of circle: %f\n", area);
  7.     return 0;
  8. }
复制代码
数据范例

根本数据范例

int 范例:int 范例用于表现整数,其巨细通常取决于编译器和利用体系。在大多数 32 位体系中,int 范例占用 4 个字节,取值范围为 -2147483648 到 2147483647。可以利用差别的修饰符来改变 int 范例的范围,如 short int(通常占用 2 个字节)、long int(通常占用 4 或 8 个字节)和 long long int(通常占用 8 个字节)。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int num = 100;
  4.     short int short_num = 32767;
  5.     long int long_num = 2147483647L;
  6.     long long int long_long_num = 9223372036854775807LL;
  7.     printf("int: %d\n", num);
  8.     printf("short int: %d\n", short_num);
  9.     printf("long int: %ld\n", long_num);
  10.     printf("long long int: %lld\n", long_long_num);
  11.     return 0;
  12. }
复制代码
char 范例:char 范例用于表现单个字符,通常占用 1 个字节。字符常量用单引号括起来,如 ‘A’、‘b’。char 范例可以作为整数范例利用,由于它现实上存储的是字符的 ASCII 码值。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     char ch = 'A';
  4.     printf("Character: %c\n", ch);
  5.     printf("ASCII value: %d\n", ch);
  6.     return 0;
  7. }
复制代码
float 和 double 范例:float 范例用于表现单精度浮点数,通常占用 4 个字节,有用位数约为 6 - 7 位。double 范例用于表现双精度浮点数,通常占用 8 个字节,有用位数约为 15 - 16 位。在利用浮点数常量时,默认是 double 范例,如果要表现 float 范例,须要在数字背面加上 f 或 F。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     float f = 3.14f;
  4.     double d = 3.1415926535;
  5.     printf("Float: %f\n", f);
  6.     printf("Double: %lf\n", d);
  7.     return 0;
  8. }
复制代码
范例转换(隐式 / 显式)

隐式范例转换:隐式范例转换是编译器主动举行的范例转换,通常发生在差别范例的数据举行运算时。隐式范例转换的规则是将低精度范例转换为高精度范例,以克制数据丢失。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 10;
  4.     float b = 3.14f;
  5.     float result = a + b; // 整数 a 会被隐式转换为浮点数
  6.     printf("Result: %f\n", result);
  7.     return 0;
  8. }
复制代码
显式范例转换:显式范例转换也称为逼迫范例转换,通过逼迫范例转换运算符 (范例名) 来实现。逼迫范例转换可以将一种数据范例逼迫转换为另一种数据范例,但大概会导致数据丢失。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     float f = 3.14f;
  4.     int i = (int)f; // 显式将浮点数 f 转换为整数,小数部分会被截断
  5.     printf("Integer: %d\n", i);
  6.     return 0;
  7. }
复制代码
运算符

算术运算符

根本算术运算符

包罗加(+)、减(-)、乘(*)、除(/)和取模(%)。须要注意的是,整数除法会截断小数部门,取模运算符只能用于整数范例。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 10;
  4.     int b = 3;
  5.     int sum = a + b;
  6.     int diff = a - b;
  7.     int prod = a * b;
  8.     int quot = a / b; // 结果为 3,小数部分被截断
  9.     int rem = a % b;
  10.     printf("Sum: %d\n", sum);
  11.     printf("Difference: %d\n", diff);
  12.     printf("Product: %d\n", prod);
  13.     printf("Quotient: %d\n", quot);
  14.     printf("Remainder: %d\n", rem);
  15.     return 0;
  16. }
复制代码
自增和自减运算符

自增运算符(++)和自减运算符(–)用于将变量的值加 1 或减 1。它们有前置和后置两种情势,前置情势先辈行自增或自减利用,再返回变量的值;后置情势先返回变量的值,再举行自增或自减利用。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 10;
  4.     int b = ++a; // 前置自增,a 先加 1 变为 11,然后将 11 赋值给 b
  5.     int c = a--; // 后置自减,先将 a 的值 11 赋值给 c,然后 a 减 1 变为 10
  6.     printf("a: %d\n", a);
  7.     printf("b: %d\n", b);
  8.     printf("c: %d\n", c);
  9.     return 0;
  10. }
复制代码
逻辑运算符

逻辑与(&&)

逻辑与运算符用于判断两个条件是否同时为真。只有当两个利用数都为真时,效果才为真;否则,效果为假。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 1;
  4.     int b = 0;
  5.     int result = a && b;
  6.     printf("Logical AND: %d\n", result);
  7.     return 0;
  8. }
复制代码
逻辑或(||)

逻辑或运算符用于判断两个条件是否至少有一个为真。只要有一个利用数为真,效果就为真;只有当两个利用数都为假时,效果才为假。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 1;
  4.     int b = 0;
  5.     int result = a || b;
  6.     printf("Logical OR: %d\n", result);
  7.     return 0;
  8. }
复制代码
逻辑非(!)

逻辑非运算符用于取反一个条件的值。如果利用数为真,效果为假;如果利用数为假,效果为真。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 1;
  4.     int result = !a;
  5.     printf("Logical NOT: %d\n", result);
  6.     return 0;
  7. }
复制代码
位运算符

按位与(&)

按位与运算符对两个利用数的对应二进制位举行与运算。只有当两个对应位都为 1 时,效果位才为 1;否则,效果位为 0。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 5; // 二进制: 0101
  4.     int b = 3; // 二进制: 0011
  5.     int result = a & b; // 二进制: 0001
  6.     printf("Bitwise AND: %d\n", result);
  7.     return 0;
  8. }
复制代码
按位或(|)

按位或运算符对两个利用数的对应二进制位举行或运算。只要有一个对应位为 1,效果位就为 1;只有当两个对应位都为 0 时,效果位才为 0。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 5; // 二进制: 0101
  4.     int b = 3; // 二进制: 0011
  5.     int result = a | b; // 二进制: 0111
  6.     printf("Bitwise OR: %d\n", result);
  7.     return 0;
  8. }
复制代码
按位异或(^)

按位异或运算符对两个利用数的对应二进制位举行异或运算。当两个对应位差别时,效果位为 1;当两个对应位雷同时,效果位为 0。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 5;  // 二进制: 0101
  4.     int b = 3;  // 二进制: 0011
  5.     int result = a ^ b;  // 二进制: 0110,结果为 6
  6.     printf("Bitwise XOR: %d\n", result);
  7.     // 利用异或交换两个变量的值
  8.     a = a ^ b;
  9.     b = a ^ b;
  10.     a = a ^ b;
  11.     printf("After swap: a = %d, b = %d\n", a, b);
  12.     return 0;
  13. }
复制代码
按位取反(~)

按位取反运算符对利用数的每一个二进制位举行取反利用,即 0 变为 1,1 变为 0。示比方下:
  1. #include <stdio.h>
  2. int main() {
  3.     int num = 5;  // 二进制: 0000 0000 0000 0000 0000 0000 0000 0101
  4.     int result = ~num;  // 二进制: 1111 1111 1111 1111 1111 1111 1111 1010
  5.     printf("Bitwise NOT: %d\n", result);
  6.     return 0;
  7. }
复制代码
在有符号整数中,按位取反后的效果会根据补码规则表明,通常会得到一个负数。
左移(<<)

左移运算符将利用数的二进制位向左移动指定的位数,右边空出的位用 0 添补。左移一位相称于将原数乘以 2。示例代码如下:
  1. #include <stdio.h>
  2. int main() {
  3.     int num = 5;  // 二进制: 0000 0000 0000 0000 0000 0000 0000 0101
  4.     int result = num << 2;  // 二进制: 0000 0000 0000 0000 0000 0000 0001 0100,结果为 20
  5.     printf("Left shift: %d\n", result);
  6.     return 0;
  7. }
复制代码
须要注意的是,如果左移导致最高位(符号位)发生变革,大概会产生溢出环境。
右移(>>)

右移运算符将利用数的二进制位向右移动指定的位数。对于无符号整数,左边空出的位用 0 添补;对于有符号整数,左边空出的位根据符号位添补(正数补 0,负数补 1,这称为算术右移)。右移一位相称于将原数除以 2(向下取整)。示比方下:
  1. #include <stdio.h>
  2. int main() {
  3.     int num = 20;  // 二进制: 0000 0000 0000 0000 0000 0000 0001 0100
  4.     int result = num >> 2;  // 二进制: 0000 0000 0000 0000 0000 0000 0000 0101,结果为 5
  5.     printf("Right shift: %d\n", result);
  6.     int negative_num = -20;  // 假设为补码表示
  7.     int negative_result = negative_num >> 2;
  8.     printf("Right shift of negative number: %d\n", negative_result);
  9.     return 0;
  10. }
复制代码
赋值运算符

简单赋值(=)

简单赋值运算符用于将右边表达式的值赋给左边的变量。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 10;
  4.     int b;
  5.     b = a;  // 将 a 的值赋给 b
  6.     printf("b: %d\n", b);
  7.     return 0;
  8. }
复制代码
复合赋值

复合赋值运算符(+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=)是将算术运算或位运算与赋值利用团结起来的简写情势。比方:
  1. #include <stdio.h>
  2. int main() {
  3.     int a = 10;
  4.     a += 5;  // 等价于 a = a + 5
  5.     printf("a after +=: %d\n", a);
  6.     int b = 8;
  7.     b &= 3;  // 等价于 b = b & 3
  8.     printf("b after &=: %d\n", b);
  9.     return 0;
  10. }
复制代码
运算符优先级和团结性

在一个表达式中,如果包罗多个运算符,运算符的优先级和团结性决定了运算的先后序次。比方,乘法和除法的优先级高于加法和减法,括号可以改变运算的优先级。团结性则决定了雷同优先级运算符的盘算序次,大多数算术运算符是左团结的。以下是一个示例:
  1. #include <stdio.h>
  2. int main() {
  3.     int result = 2 + 3 * 4;  // 先计算 3 * 4,再加上 2
  4.     printf("Result: %d\n", result);
  5.     result = (2 + 3) * 4;  // 先计算括号内的 2 + 3,再乘以 4
  6.     printf("Result with parentheses: %d\n", result);
  7.     return 0;
  8. }
复制代码
常见运算符的优先级和团结性可以参考 C 语言的运算符优先级表,在编写复杂表达式时,公道利用括号可以进步代码的可读性和克制歧义。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表