1.字符串
(1)!strcmp(“alush”, “flush”):比较两个字符串,相同为1,不同为0
strcmp(“alush”, “flush”):比较两个字符串,相同为0,不同为非0(1或-1)
举例:
#include <stdio.h> int main(void) { { printf("Hello World %d\n",!strcmp("alush", "flush")); printf("Hello World %d\n\n",strcmp("alush", "flush")); printf("Hello World %d\n",!strcmp("flush", "flush")); printf("Hello World %d\n\n",strcmp("flush", "flush")); printf("Hello World %d\n",!strcmp("glush", "flush")); printf("Hello World %d\n",strcmp("glush", "flush")); return 0; }
输出:
Hello World 0
Hello World -1
Hello World 1
Hello World 0
Hello World 0
Hello World 1
(2)
2.编译流程
假设我们有一个简单的 C 程序 hello.c
,内容如下:
cCopy code#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
编译 hello.c
程序的四个主要步骤如下:
- 预处理(Preprocessing):
- 编译器会处理源代码,执行一些预处理指令,例如
#include
指令会将包含的头文件内容插入到源代码中。 - 预处理生成的文件通常以
.i
或.ii
为扩展名。
gcc -E hello.c -o hello.i
生成产物:hello.i
- 编译器会处理源代码,执行一些预处理指令,例如
- 编译(Compiling):
- 预处理后的代码会被编译器转换成汇编代码(Assembly code)。
- 汇编代码是由特定机器体系结构的汇编语言编写的,用于表示程序的机器级指令。
- 生成的文件通常以
.s
为扩展名。
gcc -S hello.i -o hello.s
生成产物:hello.s
- 汇编(Assembling):
- 汇编器将汇编代码转换成机器码,生成目标文件(Object file)。
- 目标文件包含了二进制代码和数据,但还没有进行链接。
gcc -c hello.s -o hello.o
生成产物:hello.o
- 链接(Linking):
- 链接器将目标文件和其他库文件(例如标准库等)进行链接,生成可执行文件。
- 在链接过程中,解析函数的引用,将函数调用与定义进行关联,生成最终的可执行程序。
gcc hello.o -o hello
生成产物:hello
(可执行文件)
注意:在实际的编译过程中,可以简化命令,将预处理、编译、汇编和链接步骤合并为一个命令,例如:gcc hello.c -o hello
,这样会自动执行四个步骤,生成最终的可执行文件。
3.静态库链接:在链接阶段,如果程序引用了静态库中的某些函数,链接器会将静态库中与这些函数对应的目标文件复制到最终的可执行文件中。这样,可执行文件就包含了静态库中的代码。
动态库链接:在链接阶段,可执行文件只记录动态库的引用信息,而不复制库的实际代码。在执行可执行文件时,操作系统会查找系统中的动态库,并将动态库加载到进程的地址空间中。

3.指针的那点事
(1)指针数组
指针数组是一个数组,其中的每个元素都是指针。这意味着它存储的是多个指针,每个指针指向不同的数据或内存位置。声明一个指针数组时,需要先声明指针的类型,然后用方括号来表示数组。例如:
cCopy codeint *ptr_array[5]; // 声明一个包含5个指向int类型的指针的数组
在上面的例子中,ptr_array
是一个包含5个指针的数组,每个指针都可以指向一个int类型的变量或数组。
(2)数组指针
- 数组指针是一个指针,它指向一个数组的首元素。它相当于一个指向数组的指针,因此可以通过它来访问数组中的元素。声明一个数组指针时,需要先声明数组的类型,然后用指针符号(*)表示它是一个指针。例如:
int (*arr_ptr)[5]; // 声明一个指向包含5个int类型元素的数组的指针
- 在上面的例子中,
arr_ptr
是一个指向包含5个int类型元素的数组的指针。可以通过arr_ptr
来访问数组中的元素。
区别总结:
- 指针数组是一个数组,每个元素都是指针。
- 数组指针是一个指针,它指向一个数组的首元素。
- 指针数组的声明中,指针类型在前,用方括号表示数组。
- 数组指针的声明中,数组类型在前,用指针符号(*)表示指针。
(3)函数指针
int (*start)(struct host_service* svc);
:这是一个函数指针成员,表示一个指向函数的指针。函数的原型为 int (*start)(struct host_service* svc)
,其中:
int
是该函数的返回类型。start
是函数的名称。struct host_service* svc
是函数的参数,它是一个指向struct host_service
类型的指针。
这表示结构体中有一个名为 start
的函数指针成员,用于执行某个服务的启动操作。函数返回一个整数值作为状态码或错误码。
(4)指针函数
指针函数是返回一个指针的函数,它的返回类型是指针类型。指针函数可以用于返回指向某个特定类型的指针。
示例代码:
#include <stdio.h>
// 定义一个指针函数,返回指向整数的指针
int* getNumber() {
static int num = 42;
return # // 返回指向静态变量的指针
}
int main() {
int* ptr;
ptr = getNumber(); // 调用指针函数,得到指向整数的指针
printf("Value: %d\n", *ptr); // 输出指针所指向的值
return 0;
}
在上面的示例中,getNumber
是一个指针函数,它返回一个指向整数的指针。在 main
函数中,我们调用了指针函数并将返回的指针用于访问整数值。
总结:
- 函数指针是指向函数的指针变量,可以用来调用函数。
- 指针函数是返回一个指针的函数,其返回类型是指针类型。
4.基本数据类型
逻辑类型。只有两个量true和false,表示逻辑真值和逻辑假值。
整数类型。C支持四种整数类型:char, short, int和long,整数类型用于处理整数。
浮点类型。C支持两种浮点类型:float和double,浮点类型用于处理包含小数部分的数值。
void类型。该类型也叫缺省型,用于描述值为空集, 主要用于说明不返回值的函数或指向任一类型的指针等。





变量
变量在程序中使用时,必须预先说明它们的存储类型和数据类型。
变量说明的一般形式是:
<存储类型> <数据类型 > <变量名> ;
<存储类型>可以是关键词auto、register、static和extern之一;
<数据类型>可以是前面讲的基本数据类型,也可以是后面要讲解的自定义的数据类型.
<变量名>是一个合法的标识符,其前面的32字符有效。
注意:在上面变量说明的式子里,<变量名>之后有一个分号“;”意味着它是一个语句,该语句我们通常称为变量的说明语句
用auto存储类型说明的变量都是局部于某个程序范围内的,只能在某个程序范围内使用,通常在函数体内或函数中的复合语句里。
C语言中,在函数体的某程序段内说明auto存储类型的变量时可以省略关键字auto。
register称为寄存器型,使用register关键词说明的变量主要目的是想将所说明的变量放入CPU的寄存器存储空间中,这样可以加快程序的运行速度。
如申请不到就使用一般内存,同auto ;
register 存储类型说明变量的方式如以下例子所示:
register int count;
说明一个存储类型为register的整数变量;
extern称为外部参照引用型,使用extern说明的变量是想引用在其它文件中函数体外部说明的变量。
当变量在一个文件中的函数体外说明,所有其他文件中的函数或程序段都可引用这个变量。
一般用于在函数之间传递数据。
static称为静态存储类型,在C语言中,既可以在函数体内,也可在函数体外说明static 存储类型的变量。
在函数体内说明的static 存储类型的变量也是一种局部变量,与auto最大不同点是:static存储类型的变量在内存中是以固定地址存放的,而不是以堆栈方式存放的;只要整个程序还在继续运行静态变量就不会随着说明它的程序段的结束而消失,它下次再调用该函数,该存储类型的变量不再重新说明,而且还保留上次调用存入的数值。
位运算符
例如,
unsigned char x=0126, y=0xac, z;
z = x & y ;

unsigned char x=0126转成2进制是多少?列出计算步骤
十进制数 0126 是一个八进制数,不是十进制数。在C语言中,以0开头的整数常量被解释为八进制数。
要将八进制数 0126 转换为二进制数,首先需要将每个八进制数字转换为其对应的三位二进制数字。然后将这些三位二进制数字组合在一起,就得到了最终的二进制表示。
- 将八进制数 0126 分解为单独的数字:0、1、2、6。
- 将每个八进制数字转换为三位二进制数字(十六进制要用4位二进制数字表示):
- 0: 000
- 1: 001
- 2: 010
- 6: 110
- 将所有的三位二进制数字组合在一起:000 001 010 110。
最终,八进制数 0126 转换为二进制数是 000001010110。
位运算符
位逻辑异或“^”运算符的运算规律如下:相同为0不同为1

格式字符:

