当前位置: 首页 > article >正文

C语言基础系列【4】C语言基础语法

基本结构

看个稍微复杂点的C语言程序,了解C语言程序的整体结构,后面我们会对每个知识点展开介绍。

#include <stdio.h>   // 头文件包含

#define PI 3.1415926    // 宏定义

// 函数声明
double add(int a, int b);

int main() {         // 主函数
    // 变量声明
    int num1, num2;
    double sum;

    // 用户输入
    printf("Enter two integers: ");
    scanf("%d %d", &num1, &num2);

    // 函数调用
    sum = add(num1, num2);

    // 输出结果
    printf("Sum: %lf\n", sum);

    return 0;        // 返回 0 表示程序成功执行
}

// 函数定义
double add(int a, int b) {
    return PI + a + b;
}
  • 头文件包含
    • 头文件通常在程序的开头使用 #include 指令包含。头文件提供了函数和库的声明,如标准输入输出库 <stdio.h>、标准库 <stdlib.h> 等。它们定义了函数、宏、常量等使程序能够使用预定义的库函数。
    • 示例:#include <stdio.h>
  • 宏定义
    • 宏是通过 #define 指令定义的符号常量或代码片段。宏在编译前由预处理器替换为其定义的内容。常用于定义常量或者复杂的代码块。
    • 示例:#define PI 3.1415926
  • 函数声明
    • 函数的声明必须在函数定义或调用之前。声明提供了函数的返回类型、函数名和参数列表,以便编译器知道如何调用该函数,它的作用是提供了函数的原型。
    • 示例:double add(int a, int b);
  • 主函数
    • main() 函数是 C 程序的入口点,每个 C 程序都必须包含一个 main() 函数。程序从 main() 开始执行,返回值通常为 0 表示程序成功执行。
    • 示例:int main() { ... }
  • 变量声明
    • 所有变量必须在使用前声明。变量可以在 main() 函数中声明,也可以在其他函数中或全局声明。
    • 示例
int num1, num2;
double sum;
  • 用户输入
    • 用于接收用户输入的信息,主要使用 scanf
    • 示例:scanf("%d %d", &num1, &num2);
  • 语句和表达式
    • 语句是 C 程序的基本执行单元,通常是函数调用、赋值、控制语句(如 iffor 等)或表达式。表达式是由变量、操作符和常量组成的代码片段。
    • 示例
printf("Enter two integers: ");
sum = add(num1, num2);
  • 输出结果
    • 输出信息到屏幕中,主要使用printf
    • 示例:printf("Sum: %lf\n", sum);
  • 控制流语句
    • 控制流语句用于控制程序执行的顺序,包括 ifforwhiledo-while 等循环和条件分支语句。
    • 示例
if (a > b) {
    printf("a is greater than b");
}
  • 函数定义
    • 函数定义包含实际的函数体,它描述了函数的具体实现。函数通常包含参数、局部变量和返回值。
    • 示例
double add(int a, int b) {
    return PI + a + b;
}
  • 返回语句
    • return 语句用于终止函数的执行,并将控制权交还给调用函数。main() 函数的返回值通常是 0 表示正常执行。
    • 示例:return 0;

注释

C语言有两种注释方式

  • 单行注释,// 开头,后面的就是注释内容,这种注释可以单独占一行。
int a = 1; // 这里的就是单行注释
  • 多行注释,/* 这里可以注释多行 */,这种格式的注释可以占一行或者多行。
// 这是单行注释

/**
这里可以注释多行
这里可以注释多行
*/
int a = 1; // 这是单行注释

注意,不能在注释内嵌套注释,注释也不能出现在字符串或字符值中。

标识符

标识符是程序中变量、函数、数组等的名字。标识符由字母(大写或小写)、数字和下划线组成,但第一个字符必须是字母或下划线,不能是数字

一个标识符以字母 A-Za-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。

C 是区分大小写的编程语言。因此,abcaBC是两个不同的标识符。

下面列出几个有效的标识符:

abcd
_fda
a_123
a324
aBc
myfds134
my123adb

关键字

下表列出了 C 中的保留字。这些保留字不能作为常量名、变量名或其他标识符名称。

关键字说明
auto声明自动变量
break跳出当前循环
const定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变
continue结束当前循环,开始下一轮循环
default开关语句中的"其它"分支
do循环语句的循环体
double声明双精度浮点型变量或函数返回值类型
else条件语句否定分支(与 if 连用)
enum声明枚举类型
extern声明变量或函数是在其它文件或本文件的其他位置定义
float声明浮点型变量或函数返回值类型
for一种循环语句
goto无条件跳转语句
if条件语句
int声明整型变量或函数
long声明长整型变量或函数返回值类型
register声明寄存器变量
return子程序返回语句(可以带参数,也可不带参数)
short声明短整型变量或函数
signed声明有符号类型变量或函数
sizeof计算数据类型或变量长度(即所占字节数)
static声明静态变量
struct声明结构体类型
switch用于开关语句
typedef用以给数据类型取别名
unsigned声明无符号类型变量或函数
union声明共用体类型
void声明函数无返回值或无参数,声明无类型指针
volatile说明变量在程序执行中可被隐含地改变
while循环语句的循环条件

变量与数据类型

变量

在C语言中,变量是用来存储数据的内存单元。每个变量都有一个名称(标识符)和一个类型,用于确定变量可以存储的数据类型和大小。

变量名必须以字母或下划线开头,后续字符可以是字母、数字或下划线。变量名区分大小写,且不能与C语言的关键字(如intfloatdouble等等)同名。

数据类型

数据类型是用于存储不同类型数据的工具。以下是几种常见的基本数据类型:intfloatdoublechar。本节将分别介绍如何使用它们定义变量、它们占用的字节数以及它们的表示范围。

int(整型)

int表示整数类型。

int a = 10;
int b = -5;

float(单精度浮点型)

float用于存储带有小数点的数,但精度较低。

float pi = 3.14f;

注意:在数字后加上fF来表明这是一个float类型的字面量。

double(双精度浮点型)

double用于存储带有小数点的数,精度较高,通常用于需要更高精度的计算。

double precise_pi = 3.141592653589793;

char(字符型)

char用于存储单个字符,例如字母或数字。

char letter = 'A';
char digit = '5';

long(长整型)

long用于存储比int类型更大范围的整数。

long longValue = 123456789012345; // 定义一个long类型的变量并赋值

bool(逻辑型)

用于表示逻辑值:真(true)或假(false)。

bool boolValue = true; // 定义一个bool类型的变量并赋值为true

各数据类型占用的字节数

这些字节数可能会因编译器和平台的不同而略有差异,但以下是一般情况下的标准:

  • int:通常为4字节(32位)。
  • float:通常为4字节(32位)。
  • double:通常为8字节(64位)。
  • char:通常为1字节(8位)。
  • long:通常32位系统上占4字节(32位),64位系统上占8字节(64位)。
  • bool:通常占1字节。

可以通过sizeof运算符在程序中动态获取这些类型的大小:

(可以直接打开https://godbolt.org/z/1jvT9WK4G查看运行结果)

#include <iostream>

int main() {
    std::cout << "int: " << sizeof(int) << std::endl; // 4
    std::cout << "float: " << sizeof(float) << std::endl; // 4
    std::cout << "double: " << sizeof(double) << std::endl; // 8
    std::cout << "char: " << sizeof(char) << std::endl; // 1
    std::cout << "long: " << sizeof(long) << std::endl; // 8
    std::cout << "bool: " << sizeof(bool) << std::endl; // 1
    return 0;
}

变量初始化

变量的初始化是在定义变量的同时为其赋予一个初始值。变量的初始化可以在定义时进行,也可以在后续的代码中进行。

初始化器由一个等号,后跟一个常量表达式组成,如下所示:

type name = value;

其中,type 表示变量的数据类型,name 是变量的名称,value 是变量的初始值。

举例:

int a = 10; // 初始化a为10,类型为整型

char b = 'a'; // 初始化b为'a',类型为字符型

变量不初始化

如果变量没有显式初始化,那么它的默认值将取决于该变量的类型和其所在的作用域。

对于全局变量和静态变量(在函数内部定义的静态变量和在函数外部定义的全局变量),它们的默认初始值为零。

以下是不同类型的变量在没有显式初始化时的默认值:

  • 整型变量(int、short、long等):默认值为0。
  • 浮点型变量(float、double等):默认值为0.0。
  • 字符型变量(char):默认值为’\0’,即空字符。
  • 指针变量:默认值为NULL,表示指针不指向任何有效的内存地址。

注意,局部变量(在函数内部定义的非静态变量)不会自动初始化为默认值,它们的初始值是未定义的(包含垃圾值)。因此,在使用局部变量之前,应该显式地为其赋予一个初始值。

常量与符号常量

常量

常量是在程序执行过程中其值不变的量。常量可以是整型、浮点型或字符型。在C语言中,常量通常使用字面量表示,如整数100、浮点数3.14、字符’A’等,一般使用const定义常量。

常量是固定值,在程序执行期间不会改变。

常量可以是整型常量、浮点型常量、字符常量、枚举常量等。

我们使用const关键字定义常量,如下所示:

示例:

const int NUM = 100; // 整数常量
const double PI = 3.1415126; // 浮点数常量

字符串字面量

字符串字面量是由双引号括起来的字符序列。

字符串末尾会自动添加一个空字符 \0

char message[] = "Hello";

符号常量

符号常量是使用预处理指令#define定义的常量。与字面量常量不同,符号常量具有一个易于理解和记忆的名称。在程序中,每当编译器遇到符号常量的名称时,都会将其替换为对应的值。

示例代码

#include <stdio.h>

#define PI 3.14159 // 定义符号常量PI

int main() {
    const int MAX_VALUE = 100; // 定义整型常量MAX_VALUE,const关键字表示该变量为常量
    float radius = 5.0f;
    float area = PI * radius * radius; // 使用符号常量PI计算圆的面积

    printf("Area of circle: %.2f\n", area);
    printf("Max Value: %d\n", MAX_VALUE); // 输出整型常量MAX_VALUE的值

    // 尝试修改常量的值会导致编译错误
    // MAX_VALUE = 150; // 错误:不能修改const变量的值

    return 0;
}

#define 与 const 区别

#defineconst这两种方式都可以用来定义常量,通常情况下,建议使用const关键字来定义常量,因为它具有类型检查和作用域的优势,而 #define 仅进行简单的文本替换,可能会导致一些意外的问题。

#define 处理指令和 const关键字在定义常量时有一些区别:

  • 替换机制#define 是进行简单的文本替换,而 const 是声明一个具有类型的常量。#define 定义的常量在编译时会被直接替换为其对应的值,而 const 定义的常量在程序运行时会分配内存,并且具有类型信息。
  • 类型检查#define 不进行类型检查,因为它只是进行简单的文本替换。而 const 定义的常量具有类型信息,编译器可以对其进行类型检查。这可以帮助捕获一些潜在的类型错误。
  • 作用域#define 定义的常量没有作用域限制,它在定义之后的整个代码中都有效。而 const 定义的常量具有块级作用域,只在其定义所在的作用域内有效。
  • 调试和符号表:使用 #define 定义的常量在符号表中不会有相应的条目,因为它只是进行文本替换。而使用 const 定义的常量会在符号表中有相应的条目,有助于调试和可读性。

运算符与表达式

运算符

运算符是用于执行数学运算或逻辑运算的符号。C语言提供了多种运算符,包括算术运算符(如+、-、*、/、%)、关系运算符(如>、<、==、!=)、逻辑运算符(如&&、||、!)等。

表达式

表达式是由变量、常量、运算符和括号组成的序列,用于计算一个值。表达式的计算结果可以是整型、浮点型或字符型等。

示例代码

https://godbolt.org/z/7nPKeonaY(点击链接可查看运行结果)

#include <stdio.h>

int main() {
    int a = 10, b = 20;
    int sum = a + b; // 算术表达式
    int product = a * b;
    int quotient = b / a; // 整数除法,结果为商
    float float_quotient = (float)b / a; // 浮点除法,结果为浮点数

    int is_greater = (b > a) ? 1 : 0; // 三元条件表达式,b大于a时结果为1,否则为0

    printf("Sum: %d\n", sum);
    printf("Product: %d\n", product);
    printf("Quotient (int): %d\n", quotient);
    printf("Quotient (float): %.2f\n", float_quotient);
    printf("Is b greater than a? %d\n", is_greater);

    return 0;
}

输入输出函数

标准输入输出库

C语言的标准输入输出库(stdio.h)提供了用于输入输出的函数,如printf()用于输出,scanf()用于输入。

printf()函数

printf()函数用于向标准输出(屏幕)输出格式化的字符串。它接受一个格式字符串和一系列参数,根据格式字符串指定的格式输出参数的值。

scanf()函数

scanf()函数用于从标准输入(通常是键盘)读取格式化的数据。它接受一个格式字符串和一系列变量的地址,根据格式字符串指定的格式读取输入数据并存储到相应的变量中。

示例代码

#include <stdio.h>

int main() {
    int num;
    float price;
    char name[50];

    // 使用printf输出提示信息
    printf("Enter a number: ");
    // 使用scanf读取整数输入
    scanf("%d", &num);

    printf("Enter a price: ");
    // 使用scanf读取浮点数输入
    scanf("%f", &price);

    printf("Enter your name: ");
    // 使用scanf读取字符串输入(注意:%s格式符会自动在字符串末尾添加空字符'\0')
    scanf("%s", name);

    // 使用printf输出读取的数据
    printf("You entered:\n");
    printf("Number: %d\n", num);
    printf("Price: %.2f\n", price);
    printf("Name: %s\n", name);

    return 0;
}

在使用scanf()函数读取字符串时,应确保提供的字符数组足够大,以容纳输入的字符串和空字符\0(字符串的结束标志)。

此外,为了避免缓冲区溢出等安全问题,建议使用更安全的输入函数,如fgets()


作者介绍

  • 程序喵大人
  • 35- 资深C/C++/Rust/Android/iOS客户端开发
  • 10年大厂工作经验
  • 嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手
  • 《C++20高级编程》《C++23高级编程》等多本书籍著译者

C++训练营

专为校招、社招3年工作经验的同学打造的1V1 C++训练营,量身定制学习计划、每日代码review,简历优化,面试辅导,已帮助多名学员获得offer!训练营介绍


http://www.kler.cn/a/534888.html

相关文章:

  • 不同数据库与 WebGL 集成
  • Python爬虫实战:一键采集电商数据,掌握市场动态!
  • JAVA_内部类
  • 2025最新软件测试面试大全
  • 解锁.NET Fiddle:在线编程的神奇之旅
  • 51单片机看门狗系统
  • 深度剖析 C++17 中的 std::byte:解锁字节级编程新境界
  • PHP JSON操作指南
  • uniapp使用uts插件调用原生API
  • 鸿蒙 Next 开发实践:使用 WebView 适配移动端网站
  • JAVA异步的UDP 通讯-客户端
  • 云端IDE如何重定义开发体验
  • VS Code Python 开发环境配置
  • Linux环境下的事件驱动力量:探索Libevent的高性能IO架构
  • Java 中接口和抽象类的异同
  • Hive之数据操作DML
  • 神经网络常见激活函数 3-ReLU函数(修正线性单元)
  • 网络安全--边界安全-防火墙
  • Java 中的 Spring 框架,以及 Spring Boot 和 Spring Cloud 的区别?
  • 2025.2.6总结
  • opentelemetry-collector 配置prometheus
  • ssh中公钥和私钥怎么生成
  • Markdown介绍与语法
  • (2024|NEJM,多模态医学应用,Med-PaLM M,MultiMedBench,医学问答)迈向通用生物医学 AI
  • 二手房屋数据分析可视化系统-python
  • Redis学习(hmdp-缓存优化模块)