1.基本结构-输出函数
linux下c语言产生的为.c文件,不可执行,需要翻译连接
vi xxx.c 编辑 产生xxx.c为c语言源文件
gcc xxx.c 编译连接 ,生成可执行文件 a.out //可分开为编译gcc -c xxx.c 生成xxx.o 连接 gcc xxx.o
a.out 执行
c语言源程序.c可移植,.out已生成具体机器代码不可移植
-o制定可执行文件的命令 gcc hello.c -o m1 生成可执行文件m1 执行时m1
\续行符 一行后加\连接两行
%i/ %d : int
%hd / %ld : short int / long int
%u : unsigned int
%x / %o : 十六进制 / 八进制
%%f / %lf : float / double
%g : float / double 去掉尾随的0
%c : char
%s : string
%p : address
2.变量-常量
vi本身存在初始化文件 ~/.exrc 可vi打开编辑进行设置 例如 set nu :set all查看所有可设置命令
查看汇编代码 gcc -S m1 生成汇编文件m1.s 也可直接编译m1.s 查看 vi m1.s
sizeof()中只分析类型不参与计算 eg sizeof()
esp / ebp 栈
const int PI=3.14 <==>int const PI=3.14 const只读变量,一旦确定不能修改
程序编译错误分析 : 程序中有游离的"\nnn" -->标点符号中有中文
#define NAME "黄坤"
#define DATE 20131124 ==>宏
查看预处理后的效果 显示在屏幕上 cc -E xxx.c
scanf("%s",&str) //读取到空格为止
gets() //专业读取一行字符串,危险函数禁止使用
scanf("%*[^\n]%*c"); scanf("%*c");抛弃 ^非 []为范围 //清空缓存。
{
char c;
do
scanf("%c");
while (c!='\n');
}
//接受的键盘信息中除回车外统统抛弃,不作响应
puts() 输出一行字符串
将字符串放进数组中 char a[100]; strcpy(a,"gggggggg");
字符串末尾追加字符串 strcat(a,"zhuijia");//必须确保空间足够 // <string.h>
strchr(a,'s') 字符串中查找字符 返回字符开始的部分,找不到返回空地址
strrchr(a,'s') 从右向左找
strstr(a,"xxx")字符串中查找字符串
strcmp()比较两个字符串是否相等 strlen()查看字符串长度
"hello"[0];即字符'h'
结构体初始化 person c={age:18,name:furong};
引用:c.name,c.age 数组只能初始化,不能赋值 strcpy(a.name,"xxx");
结构体中:unsigned char 或unsigned int (只有这两种变量允许)
允许指定每个成员占的位数 unsigned char userread:1; //指定成员userread占1位 理论上占1字节=4位
但是分配内存时分别补齐1字节和4字节的倍数
小端存储:cpu存储ox12345678时为78 56 34 12
大端存储:存储方式 12 34 56 78 不同的系统存储方式不同
一个人程序函多个文件时 编译连接 分开进行:分别编译gcc *.c形成n个.o文件-->gcc xx.o mm.o
一个文件中插入另一个文件#include"xxx.c";
静态局部变量第一次分配空间,直到程序结束。每次改变静态变量值,即永久保存 }若。。。。
动态局部变量执行完语句后即收回空间 }若未初始化,系统自动初始化为0
register寄存器 和volatile
寄存器变量 register int i;//请求编译器将i放在寄存器中,仅仅是请求
volatile int i;//表明i随时可能被其它未知的原因修改
寄存器无地址,因为地址存在于内存中 若用寄存器的同时用取地址则忽略寄存器
int a(void);//void明确表示不接受任何参数,空表示参数不确定
不定参数表:
int max(int cnt,...)
{
va_list v; //#include<stdarg.h>//va_list为(地址)类型,v保存可变长参数表
va_start(v,cnt);//v保存参数cnt之后的参数表,va_start(开始一个参数表)
int i;
int maxvalue=va_arg(v,int);//从参数表中取出一个int型参数
for(i=0;i<cnt;i++)
{
int data=va_arg(v,int); //一次取参数表中的每个参数
if(data>maxvalue)
maxvalue=data;
}
va_end(v); //释放可变长参数表
return maxvalue;//返回值最大值
}
检查是否定义过宏:#ifdef I //如果没定义过
#define I "sss" //将I定义为"sss"
#else
#undef I //取消对I的定义
防止头文件重复插入 框架
#ifndef VX //(VX通常为文件名 XXX_H)
#define VX 1
头文件内容
#endif
C语言中预先定义好的宏,可直接使用
__FILE__文件名 __LINE__ 行号 __DATE__ 当前日期 __TIME__当前时间 __STDC__C语言 (双下划线)
带参数的宏,后面的参数加()
宏替换天然缺陷:不能将带++ -- 和赋值的式子作为参数
宏中#的作用:将参数变成对应的字符串//#define STR(x) puts(#x) -->STR(he)-->输出he
##作用:拼接
//野指针-->未初始化的指针-->避免方法:每次定义指针变量时int *q=0;
指针变量中0表示空指针NULL,字符变量中表示'\0',整型变量中表示数值0
//悬空指针-->指向一个可能已经释放的地方的指针-->//不要返回普通局部变量的地址
const char* q=NULL //声明不能通过指针p修改p所指向的数据,否则编译报错,但不限制通过其他渠道修改
const char * q==char * const q 为常量,必须初始化
命令行参数的使用:(由main()函数参数决定,由shell执行)
int main(int argc,char*argv[]) //argc为参数个数,argv[]每个元素中放每个字符串地址
//命令行是字符串,即使数字也是"12"、"34"字符串
void*addr //void类型指针,在使用时先强制类型转换,如*(unsigned char*)addr++
int* p[5]; //p是一个数组,5个元素,每个元素是 int *
int* p(double); //p是一个函数,形参double,返回类型int*
int (*p)[5]; //p是指针,指向5个元素的int型数组-->指向数组的指针
int(*p)(double);//p是指向(参数为double型,返回值为int型)的函数的指针
对函数名取地址,&可有可无-->函数名本身是个地址
fflush(stdout);//标准刷新
sscanf() //从字符串中读取数据
sprintf(); //输出到字符数组中
(*p).成员==p->成员
查询某一函数所需的头文件,man 函数名
stdin//标准输入 stdout//标准输出 stderr//标准错误输出,不缓冲,不能重定向
即可以将键盘当做一个输入文件,将屏幕当做一个输出文件(操作系统将屏幕键盘分别当做一个文件)
fscanf(FILE*,);
fprintf(文件,);
fopen();打开文件 //FILE* fi=fopen("in","r");//in文件名 r打开方式
//fscanf(fi,"%s",name);
//fclose(fi);
puts();输出一行并换行 char buf[100];gets[buf];
gets();丢弃换行符,换成'\0'
fgets();从文件读取一行,保留换行符作为字符串的一部分
fputf();向文件写时不自动加换行符
scanf("%[^\n]%*c",buf);//读取一行,直到换行为止,并丢弃换行符
tee file 回车+内容==》将内容打印在屏幕上并输入在file文件里
定位读写:交换一个文件中第一行的第10,20两个数,假设共27字母
#include<stdio.h>
int main()
{
FILE* fp=fopen("file","r++"); //打开文件file
if(fp==NULL)
{printf("无法打开file\n");
return 1;} //判断是否成功打开
fseek(fp,9,SEEK_SET); //fp文件从行首偏移9个字节
char c10,c20;
c10=getc(fp); //读取一个字符,放在c10中
fseek(fp,9,SEEK_CUR); //从当前位置偏移9字符,到第20个
c20=getc(fp); //此时停留在21位置
fseek(fp,-11,SEEK_CUR); //回退
putc(c20,fp);
fseek(fp,-8,SEEK_END); //从尾部后退8个,因为末尾有换行。END最后一字符后面
putc(c10,fp);
fclose(fp);
return 0;
}
读写一块数据:fread/fwrite 不分数据类型
读:从文件向内存
fread(内存地址,每条记录字节数,记录条数,文件名);
fwrite();//同上
#include<stdio.h>
{
typedef struct person{
char name[20];
char gender;
int age;
double salary;//姓名,性别,年龄,工资;
} person; //定义结构体变量,名person
#int main()
{
person a[5]={{"ss".'F',18,4000},{},{},{},{}}; //结构体变量数组,含5个数组元素,初始化
//将此数组数据存入文件
FILE* fp=fopen("person.dat","wb");//wb:保持文件内容原样
//判断是否打开成功
int b[10]={11,22,33,44,55,66,77,88,99,1010};
short s=12345;
fwrite(a,sizeof(person),5,fp);
fwrite(b,sizeof(int),10,fp);
fwrite(&s,sizeof(short),1,fp);
fclose(fp);
return 0;
} //end
//从文件中读取数据到变量(内存)--接上
FILE* fp=fopen("person.dat","rb");
fread(a,sizeof(person),5,fp);
fread(b,sizeof(int),10,fp);
fread(&s,sizeof(short),1,fp);
fclose(fp);
ungetc(); 向文件中退回一字节(退回到:下次读马上读位置)
不能将内存地址存入文件,程序结束内存收回