记录一些之前没有注意到的小细节。
char ex[20];
scanf("%19s", ex);
scanf()
用于吸收结构化字符串,%19s
可以防止数组越界,不吸收回车。
fgets(ex, sizeof(ex), stdin);
fgets()
用于吸收非结构化字符串,sizeof(ex)
是吸收的字符串的总长度,包括'\0'
,这里为20
,吸收回车。
int j;
scanf("%i", &j);
%i
自动将输入转化为十进制,接受的输入样式为:十进制、十六进制、八进制,如:12
,0xc
,014
。
printf("%i", j);
这里%i
和%d
没什么区别。另外,printf()
用于输出格式化字符串,实际上调用fprintf()
,即:fprintf(stdout, "%i", j);
若要直接输出字符串则可以使用puts()
,如:puts("Hello world!");
puts()
会自动在字符串结尾输出回车。即:puts("");
== printf("\n");
int doses[] = {1, 3, 2, 1000};
printf("%i", 3[doses]);
输出结果为1000
,参考帖子:*(3+doses)怎么就等于3[doses]了
doses[3] == *(doses + 3) == *(3 + doses) == 3[doses]
结构体/联合体初始化:
typedef union {
short count;
float weight;
float volume;
} quantity;
quantity p = {4};
C89方式,保存为第一字段的值。quantity q = {.weight = 4.0};
C99标准,指定初始化器。quantity r; r.volume = 4.0;
”点“表示法。
(结构体可也可直接赋值,如:quantity s = {4, 4.0, 4.0};
)
指针退化是指将数组地址赋值给指针变量时长度信息丢失的情况,即:数组地址包含地址信息和长度信息(用sizeof),而指针变量只包含地址信息。如:
char str[] = "Hello world!";
char *p = str;
printf("%s == %s\n", str, p);
printf("%i != %i\n", sizeof(str), sizeof(p));
输出结果为:
Hello world! == Hello world!
13 != 8
故将数组地址作为函数参数时,要考虑是否需要加多一个长度参数接收数组的长度。
位字段主要用于一些使用空间很宝贵的程序设计中,如嵌入式程序设计。成员类型必须为unsigned int
,需要用:
指定成员所占的位数。如:
typedef struct{
unsigned int first_visit:1;
unsigned int come_again:1;
unsigned int fingers_lost:4;
unsigned int shark_attack:1;
unsigned int days_a_week:3;
}survey;
在同一结构中,位字段才能节省空间。
strdup()
将字符串复制到堆上,要用free()
释放空间,不释放会导致内存泄漏。如:
char str[] = "Hello world!";
char *copy = strdup(str);
printf("%s == %s\n", str, copy);
free(copy);
strdup()
头文件为string.h,free()
头文件为stdlib.h。
size_t
是unsigned int
类型,是数组下标值的类型,也是sizeof
操作符返回的值的类型,也是str*
相关函数返回的长度等的类型。
在C语言中,所有的表达式都有值。如:z = y = x = 4
。x = 4
返回值为4
,于是z = y = 4
;y = 4
返回值为4
,于是z = 4
。这也就是”连等赋值“。
在%08x
中,0
是标志字符,当输出值的宽度小于最小宽度(这里设置为8)时用”0“(默认用空格)填充。
malloc()
返回的是通用指针,即void *
类型的指针。