C语言笔记(1)

函数返回值

一般来说, 函数在返回的时候会将待返回的值存到eax(累加器)寄存器中, 然后再调用mov指令将eax中的值写到对应的变量中

接下来考虑有返回值的函数不写return语句的情况, 编写以下代码:

// test.c
#include <stdio.h>
int add(int a, int b)
{
    int c = a + b;
}
int main()
{
    int c = add(1, 1);
    printf("%d", c); // 你猜c是几, 对, 就是2
    return 0;
}

然后使用gcc编译为intel汇编代码

gcc -masm=intel -fverbose-asm -S -O0 test.c

编译出来的汇编代码如下(部分):

add:
.LFB0:
	.cfi_startproc
	endbr64	
	push	rbp	#
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	mov	rbp, rsp	#,
	.cfi_def_cfa_register 6
	mov	DWORD PTR -20[rbp], edi	# a, a
	mov	DWORD PTR -24[rbp], esi	# b, b
# return.c:4:     int c = a + b;
	mov	edx, DWORD PTR -20[rbp]	# tmp87, a
	mov	eax, DWORD PTR -24[rbp]	# tmp88, b
	add	eax, edx	# tmp86, tmp87 # 计算edx+eax, 结果存在eax中
	mov	DWORD PTR -4[rbp], eax	# c, tmp86
# return.c:5: }
	nop	
	pop	rbp	#
	.cfi_def_cfa 7, 8
	ret	# 返回
	.cfi_endproc
main:
.LFB1:
	.cfi_startproc
	endbr64	
	push	rbp	#
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	mov	rbp, rsp	#,
	.cfi_def_cfa_register 6
	sub	rsp, 16	#,
# return.c:8:     int c = add(1, 1);
	mov	esi, 1	#,
	mov	edi, 1	#,
	call	add	#
	mov	DWORD PTR -4[rbp], eax	# c, tmp84 # 把eax的值存到c;里
# return.c:9:     printf("%d", c); // 你猜c是几, 对, 就是2
	mov	eax, DWORD PTR -4[rbp]	# tmp85, c
	mov	esi, eax	#, tmp85
	lea	rdi, .LC0[rip]	#,
	mov	eax, 0	#,
	call	printf@PLT	#
# return.c:10:     return 0;
	mov	eax, 0	# _5,
# return.c:11: }
	leave	
	.cfi_def_cfa 7, 8
	ret	
	.cfi_endproc

可以看到, 在上面的代码中, 执行a+b后计算结果储存在eax中, 然后由于add这个函数里没写return语句, 自然eax的值就没有改变, 因此就传回了2

getc与fgetc的区别

f代表function, 因此fgetc是函数
getc是宏, 效率会更高但是可能会有副作用

考察以下代码:

FILE *files[10], *f = files;
int i = 0;
while (f < files + 10)
{
    char = getc(*f++);
}

在这段代码中f++可能会执行多次, 因此这种情况下应使用fgetc

gets与gets_s

gets() 函数不进行边界检查,从而此函数对缓冲区溢出攻击极度脆弱。无法安全使用它(除非程序运行的环境限定能出现在 stdin 上的内容)。因此,此函数在 C99 的第三次勘误中被弃用,而在 C11 标准发布时被移除。推荐的替代品是 fgets() 和 gets_s()
绝对不要用 gets()

摘自https://zh.cppreference.com/w/c/io/gets

也就是说gets在C11标准中已经被移除了, 只能使用fgets和gets_s
然而gets读入整行时会丢弃换行符, 而fgets不会, 为了读入整行, 我需要使用gets或gets_s
但是根据测试, 有些编译器似乎不支持gets_s

标题: C语言笔记(1)
作者: QingChenW
链接: https://dawncraft.cc/2021/04/83/
本文遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 许可
禁止商用, 非商业转载请注明作者及来源!
上一篇
下一篇
隐藏