C语言学习关键笔记

1.头文件含义(C 语言的.h文件类似于java的interface,只是声明函数,并不实现函数)

在C语言编程中,头文件扮演着至关重要的角色。它们是扩展名为 .h 的文件,包含了C函数声明和宏定义,用于在多个源文件之间共享代码。头文件允许程序员在不同的源文件中重用相同的代码,而无需重复编写代码。

头文件的作用:
头文件的主要作用是提供接口。例如,当你在代码中使用 printf 函数时,实际上是在调用 stdio.h 头文件中定义的函数。如果没有包含相应的头文件,编译器将不知道 printf 是什么,从而无法编译代码。因此,头文件可以看作是一个预先准备好的代码库,你可以从中选择需要的功能来提高代码效率。

stdio.h解释:是C语言标准库中的一个头文件,它定义了处理文件和标准输入/输出流的各种函数和类型。这个库提供了一系列的变量类型、宏定义和函数,用于执行输入和输出操作
std:标准库
i:input
o:output

2.全局变量

2.1全局变量的作用范围是整个工程
其他.c定义的全局变量,此.c文件想调用时,用extern 数据类型 全面变量名即可调用
2.2局部变量生命周期
执行进入{就是开始创建,执行到}就是销毁
2.2全局变量生命周期
整个程序运行中都存在,程序关闭即销毁

3.字符串的结束标志

\0:是字符串的结束标志,指的是读取字符串时遇到转义字符\0就停止

4.占位符理解

占位符(Placeholder)是什么意思?
在 printf 和其他格式化输出函数中,占位符(Placeholder) 指的是格式字符串中以 % 开头的部分(如 %d、%f、%s 等),它表示“这里要插入一个变量的值”。
为什么叫“占位符”?
“占位”:它在字符串中占据一个位置,告诉程序“稍后这里要替换成一个实际的值”。
“符”:它是一个特殊的符号(如 %d),代表某种数据类型。

5.转义字符理解

转义字符(Escape Character) 在 C 语言中主要有两个作用:

  1. 表示无法直接输入/显示的字符(如换行、制表符、引号等)。这样就能正常打印“

    printf("他说:\"你好\""); // 正确,输出:他说:"你好"
    
  2. 执行特殊功能(如换行 \n、响铃 \a 等)。

6.GCC理解

GCC 不是一个单一的编译器,而是一个编译器套件
GCC 是编译器集合
gcc 只是其 C 语言的驱动程序

作用:GCC 不仅是 C 编译器,还是支持多语言(go/Objective-C/C++等语言)的完整工具链,其 gcc 命令专门处理 C 代码,但背后依赖预处理、编译、汇编、链接等多个组件。

关键组件:
cc1:C 编译器核心(gcc 调用它)。
cc1plus:C++ 编译器核心(g++ 调用它)。
libgcc:GCC 的底层运行时库。
libc : C 标准库(如 printf、malloc,通常指 glibc 或 musl)

7.g++理解

关键组件:
libstdc++:C++ 标准库实现。

g++ 是 GCC 中专门针对 C++ 的驱动程序(Driver)

使用 g++ 的完整流程(hello是可执行程序,可直接运行)
g++ hello.cpp -o hello
实际步骤:
预处理:cpp hello.cpp > hello.ii(展开宏、头文件)。
编译:cc1plus hello.ii -o hello.s(生成汇编)。
汇编:as hello.s -o hello.o(生成目标文件)。
链接:ld hello.o -lstdc++ -o hello(自动链接 C++ 库)。

8.单目操作符(前置++和后置++的区分)

前置++ :

int a = 5;
int b = ++a;//(前置++ :先a+1,后赋值)
所以a = 6 ,b = 6

后置++ :

int a = 5;
int b = a++;//(后置++ :先赋值给b,再a+1)
所以a = 6 ,b = 5

9.C语言中static关键字的用法总结(全局变量的时候作用域与java的static正好相反)

.c文件中的全局变量/函数默认是外部链接的!其他.c文件可以外部引用

1.在函数内部(局部变量)

作用:将局部变量变为静态存储期变量

特点:
变量在程序运行期间一直存在(不像自动变量随函数调用结束而消失);
只在第一次进入函数时初始化一次(配合使用单例模式);
保持上次函数调用结束时的值;
作用域限于定义它的函数内部;

void counter() {
    static int count = 0;  // 只初始化一次
    count++;
    printf("Count: %d\n", count);
}

int main() {
    counter();  // 输出 Count: 1
    counter();  // 输出 Count: 2
    counter();  // 输出 Count: 3
    return 0;
}

2.在函数定义(函数本身)

作用:限制函数的作用域为当前文件(将外部链接改成了内部链接,只能在该.c文件中使用),没用static修饰的函数,其他.c源文件都可以调用

特点:
使函数成为文件作用域的(只能在定义它的源文件中使用)
避免与其他文件中的同名函数冲突
隐藏函数实现细节(封装)

// file1.c
static void helper() {  // 只能在本文件使用
    printf("Helper function\n");
}

// file2.c
static void helper() {  // 这是另一个不同的函数
    printf("Different helper\n");
}

3. 在文件作用域(全局变量)

作用:限制全局变量的作用域为当前文件

特点:

变量具有静态存储期(整个程序运行期间存在)
作用域限于定义它的文件(内部链接)
避免命名空间污染

// file1.c
static int fileLocal = 42;  // 只能在本.c文件中访问

// file2.c
extern int fileLocal;  // 错误!!!编译不能通过,无法访问另一个文件的static全局变量

10.宏的理解

宏(Macro)是C语言预处理器提供的一种功能,它允许你在编译前对代码进行文本替换

  1. 对象式宏(Object-like Macro)
    c
    #define PI 3.14159
    这种宏在代码中简单地将PI替换为3.14159。

  2. 函数式宏(Function-like Macro)
    c
    #define SQUARE(x) ((x) * (x))
    这种宏看起来像函数调用,但实际上是文本替换。

11.C中的指针理解

调用函数传的值叫实参,函数的参数叫形参!

  1. java代码
这里的p相当于 Person p = person;(创建对person的引用副本)
void modifyObject(Person p) {
    p.name = "Alice";  // 修改对象属性(生效)
    p = new Person("Bob");  // 修改的是引用的副本,不影响原始引用
}

Person person = new Person("John");
modifyObject(person);
System.out.println(person.name);  // 输出 "Alice"
  1. C的值传递
#include <stdio.h>
#include <string.h>

typedef struct {
    char name[50];
} Person;
这里的p相当于重新创建一个 Person ,然后复制person的值进来!!!
void modifyObject(Person p) {
    strcpy(p.name, "Alice");  // 修改的是副本,不影响原始数据
    Person newPerson = { "Bob" };
    p = newPerson;  // 修改副本,不影响原始数据
}

int main() {
    Person person = { "John" };
    modifyObject(person);
    printf("%s\n", person.name);  // 输出 "John"(未被修改)
    return 0;
}
  1. C的引用传递
这里的p是person的地址,知道地址就什么都能修改
void modifyObject(Person *p) {
    strcpy(p->name, "Alice");  // 修改原始数据
    Person newPerson = { "Bob" }; 
    *p = newPerson;  // 修改原始数据(现在 Alice 变成 Bob),复制 newPerson 的所有数据到 person。
}

int main() {
    Person person = { "John" };
    modifyObject(&person);  // 传递指针
    printf("%s\n", person.name);  // 输出 "Bob"(被修改)
    return 0;
}
行为Java (对象引用)C (结构体副本)C (指针)
参数传递方式引用的副本(类似指针的引用传递,但是只能影响原始对象的 !!!)完整结构体的值拷贝指针的引用传递(用指针)
修改属性✅影响原始对象(p.name = “Alice”)❌ 不影响原始结构体✅ 影响原始结构体数据(p->name = “Alice”)
重新赋值❌ 不影响原始引用(p = new Person())❌ 不影响原始结构体(p = { “Bob” })✅ 影响原始结构体数据,不影响地址!!!(*p = { “Bob” })

看到43!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值