1.大程序的头文件
将函数原型放到一个头文件(以.h结尾)中,在需要使用这个函数的源代码
文件中#include这个头文件即可。
一般任何.c都有对应的同名.h,把所有公开的函数原型和全局变量放进去。
2.#include的误区
- #include不是用来引入库的
- stdio.h里只有printf的原型,printf的代码在另外的地方,某个.lib(Win)或者.a(Unix)中
- #include <stdio.h>只是为了让编译器知道printf的原型,保证调用时给出的参数值是正确的类型
3.不对外公开的函数
- 在函数前加static使它成为只能在所在单元使用。
- 在全局变量前加static也是使它只能在所在单元使用。
4.声明
- 在.c文件中定义一个变量,在.h文件中使用extern声明变量。
int i; extern int i;
- 在同一个编译单元里,同名的结构不能被重复声明。
5.区分声明和定义
- 声明是不产生代码的东西:
函数原型、变量声明、结构声明、宏声明、枚举声明、类型声明、inline函数 - 定义是产生代码的东西:
函数、全局变量
6.标准头文件结构
#ifndef __NAME_HEAD__
#define __NAME_HEAD__
…… ……
#endif
标准头文件,防止重复声明。
7.格式化输入输出
7.1 printf %[flags][width][.prec][hil]type
flag | 含义 | ~ | width或prec | 含义 | ~ | 类型修饰 | 含义 |
---|
- | 左对齐 | ~ | number | 最小字符数 | ~ | hh | 单个字节 |
+ | 在前面放+或- | ~ | * | 下一个参数是字符串 | ~ | h | short |
(space) | 正数留空 | ~ | .number | 小数点后的位数 | ~ | l | long |
0 | 用0填充 | ~ | .* | 下一个参数是小数点后的位数 | ~ | ll | longlong |
| | ~ | | | ~ | L | long double |
示例:
%09d 整个输出占9位,右对齐,使用0填充
%+9d 整个输出占9位,右对齐,数前放入加号
%9.2f 整个输出占据9个字符位,保留两位小数
%*d 需要给两个数,第一个即占几个位,第二个即数
printf("%*d\n", 6, 123);
%hhd printf("%hhd",(char)12345);转为单字节为57,使用强制转无警告
type | 用于 | type | 用于 |
---|
i或d | int | g | float |
u | unsigned int | G | float |
o | 八进制 | a或A | 十六进制浮点 |
x | 十六进制 | c | char |
X | 字母大写的十六进制 | s | 字符串 |
f或F | float,6 | P | 指针 |
e或E | 指数 | n | 读入/写出的个数 |
示例:
printf("%d%n", 8564, &num);
到%n的时候输出了几位,本次为4。(需要打印num变量)
7.2 scanf %[flag]type
flag | 含义 | flag | 含义 |
---|
* | 跳过 | l | long,double |
数字 | 最大字符数 | ll | long long |
hh | char | L | long double |
h | short | | |
示例:
scanf("%*d%d",&num); printf("%d",num);
如果输入“123 456”最后则输出为”456“,因为第一个整数被跳过啦
type | 用于 | type | 用于 |
---|
d | int | a,e,f,g | float |
i | 整数,可能十六进制或八进制 | c | char |
u | unsigned int | o | 八进制 |
x | 十六进制 | s | 字符串(单词) |
[…] | 所允许的字符 | P | 指针 |
8.文件的输入输出
- 用>和<做重定向
- ./test.cpp < math.in > res.out
- 运行test文件,math.in里面的是输入的内容,程序运行结果放入res.out中。
- fopen的类型"…x"为只新建如果文件已存在则不能打开。
打开文件的标准代码
FILE *fp = fopen("file","r");
if(fp){
int num;
fscanf(fp,"%d",&num); 读取fp文件中的内容放入num中
fclose(fp);
}else{
……
}
9.位运算
- & 与:有假则假,都真则真
- | 或:有真则真,都假则假
- ~ 取反
- ^ 异或:相同为0,相反为1
- << 左移:对于int来说,x<<=n等价于x*=2^n
- '>> 右移:x>>=1等价于x/=2,对于不同的类型,移位不同
- 移位时不要使用负数,没有意义。
10.可变数组
#include "array.h"
#include <stdio.h>
#include <stdlib.h>
const BLOCT_SIZE = 5;
Array array_create(int init_size)
{
Array a;
a.size = init_size;
a.array = (int*)malloc(sizeof(int)*a.size);
return a;
}
void array_free(Array *a)
{
free(a->array);
a->array = NULL;
a->size = 0;
}
int array_size(const Array *a)
{
return a->size;
}
int* array_at(Array *a, int index)
{
if(index >= a->size){
array_inflate(a, (index/BLOCT_SIZE+1)*BLOCT_SIZE-a->size);
}
return &(a->array[index]);
}
void array_inflate(Array *a, int more_size)
{
int *p = (int*)malloc(sizeof(int)*(a->size+more_size));
int i;
for(i=0; i<a->size; i++){
p[i] = a->array[i];
}
free(a->array);
a->array = p;
a->size += more_size;
}
int main(int argc, char const *argv[])
{
Array a = array_create(100);
printf("%d\n", array_size(&a));
printf("%d\n", a.size);
*array_at(&a,0) = 10;
printf("%d\n", *array_at(&a,0));
int number = 0;
int cnt = 0;
while(number != -1{
scanf("%d", &number);
if(number != -1)
*array_at(&a, cnt++) = number;
}
array_free(&a);
return 0;
}
11.链表
124
12.ACLLib入门