linux C学习(散)
ls /usr/include -- linux c 预处理头文件
gcc xx.c -o hello -- 编译xx.c重命名hello
./hello -- 执行
末行模式:set all
Vim ~/.exrc -- vi 初始化文件
set ts=4
sizeof() -- 只关注类型
gcc -S xx.c -- 汇编程序
gcc -E xx.c -- 预处理
const -- 常量不可变 比define要好 -- 防止一般替换 常量只读 程序不可变 系统管理
printf -- %p 输出地址
int a=0,b=0;
printf("% d %d %d \n," b=a+++(a+++2),b,a=b++); --先做运算,但是还是与编译器有关,从右向左,如果a=1,b=2,c=a+b;就是从左到右
第二 第三 第一
2 2 0
printf("% d %d \n",a,b);
2 2
小数比较最好不要用== 因为有误差 一般取差的绝对值 (也有绝对值函数)
scanf(" %c",&c); -- %c一般前面有一个空白字符,以防其他字符出错
#include<stdio.h> int main() { int a=8,b=5; printf("%d ,%d , %d\n",a<=b,a>=b,a>=3); int c,d; printf("&c=%p,&d=%p\n",&c,&d); return 0; } ---------------------------------------------- #include<stdio.h> int main() { /* int age; printf("you are age:"); scanf("%d",&age); if (age<0||age>1000) printf("welcome\n"); */ int s; do { puts("you are score:"); scanf("%d",&s); if(s<60) {printf("you are so low\n");} scanf("%*[^\n]%*c"); // clear buffer }while(s<60); printf("congratulation pass\n"); return 0; }
----------------------------------------------------
switch {}
case --int 类型
case: 内部不要定义或者初始化变量一定要这样就要大括号括起来这样表示只有自己在这个范围内有用
default: -- 谁都可以进来
scanf("%*[^\n]%*c"); -- 清除输入缓冲区剩余字符
a+i == &a[i]
a[i] ==> *(a+i) ==i[a]===*(i+a)
arry 初始名+下标就是对应元素地址
越界访问可能访问到无法预知的数据;
越界存放数据可能破坏其他变量的值;
越界存放数据甚至可能导致程序崩溃;
字符数组‘\0‘!!!
读字符数组 没遇到结束符,可能会输出乱码(把数组大小大一点,或许不会有乱码)
struct -- 结构体a=b 不能复制字符串 可以用strcpy
定义一个结构体
sizeof(person)
会发现sizeof对齐在内存中 一个char 1 short 2 int 4 double 4(大小超过4的类型就按4算,4(自身长度倍数)的倍数开始(补齐)有的系统是八的倍数开始,或许更长些,系统间也没完全统一原则)-- 不要假设各个成员是挨着放的,或许最后一个成员后面都是空着的 -- 对于设计结构体时可以优化,其实也没有多大影响,效率上还是一样的
函数声明可以多次 函数定义只有一份 声明前定义后 或是定义在调用函数前否则会有声明错误
<sys/types.h>
注意函数中的语句块局部变量(离开范围就释放)的作用范围 --返回值最好不要是局部变量
static 局部或全局没初始化则系统默认0 --那么就是不会有垃圾数据 --只能本文件使用--不会释放
register变量 --速度快 是一种请求
volatile变量 --防止编译器优化给变化的数据,一般不怎么用
形参,局部变量等--堆栈适合恢复现场
形参void表示不允许接受任何参数-- date input(void)
形参数组和实参数组实际上是同一个数组 同一类型同一地址同一变量 --只需要向函数传递数组,不需要(不能)返回数组
------------------------------------------- #include<stdio.h> int main() { const int bits=sizeof(int)*8; unsigned int mask=1<<bits-1; int n; printf("input a number"); scanf("%d",&n); int i; for(i=0;i<bits;i++) { printf("%c",n&mask?‘1‘:‘0‘); //printf("%c",n<0?‘1‘:‘0‘); //printf("%d",n<0); mask=mask>>1; // n<<=1; } printf("\n"); return 0; } ------------------------------------------ #include<stdio.h> void decbit(int n) { if(n>9){ decbit(n/10); } printf(" %d",n%10); } int main() { decbit(67389); printf("\n"); return 0; } ------------------------------------------------- 左移乘2右移除2 x<<=1; reverse --数组反序 int i; for(i=0;i<n/2;i++) { int t=x[i]; x[i]=x[n-1-i]; x[n-1-i]=t; } #include<stdarg.h> int max(int cnt,...) --定义未知个数形参 { va_list v;//保存可变长参数表 return cnt; }
#include<stdio.h> int main() { int sco,sum=0,i=0; for(i=0;i<10;i++) { printf("input the %d you are score:\n",i+1); scanf("%d",&sco); sum+=sco; // if(s<60) // {printf("you are so low\n");} // scanf("%*[^\n]%*c"); // clear buffer } //while(s<60); //printf("congratulation pass\n"); printf("avg %f\n",sum/10.0); return 0; }
------------------------------------------------
#include<stdio.h> int main() { int cnt,n; do{ printf("print a num 1-9:"); cnt=scanf("%d",&n); scanf("%*[^\n]%*c"); }while(cnt!=1||n<1||n>9); int j,i; for(i=1;i<=n;i++) { for (j=1;j<=i;j++) printf("%dX%d=%d%c",j,i,j*i,(j!=i?‘,‘:‘\n‘)); } return 0; }
------------------------------------------
if控制的内容如果以return结束那么else可以省略
汉诺塔: A的n个移到B
A B C
先n-1个从A到C然后把第n个移到B再把C的n-2个移到A,第n-1个移到B,以此类推
#include<stdio.h> void hano(char from,int n,char to,char spare) { if(n>0) { hano(from,n-1,spare,to);//n-1 move to spare printf("move %d %c==>%c\n",n,from,to);//move the n hano(spare,n-1,to,from);//spare to dest } } int main() { hano(‘a‘,4,‘b‘,‘c‘); return 0; }
#define --宏可以代替任何--只是做简单的替换,先做替换,对替换之后的代码做编译
#ifdef
#ifndef
#else --一般上面五个用于头文件编译
#undef
#endif
Vim /usr/include/stdio.h
#define SWAP(T,x,y) (T t=x;x=y;y=t;)
SWAP(double ,a,d); --- 带参的宏,还能带类型(没有类型检查),如果用带参宏记得加括号
调用宏函数最好不要用运算符++ -- = 等
宏函数速度快,缺陷就是容易引起错误以及没有类型检查
#字符串puts(#x) 或是作拼接工作##
-------------------------------------------------------
#include<stdio.h> int main() { char a[9]={‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘,‘g‘,‘h‘}; puts(a); char *p1; p1=&a[0];//char * char* p2=&a[2]; printf("%c\n",*p1); *p1=‘A‘; printf("%c\n",*p1); puts(a); return 0; }
指针作为数据用的时候是地址,保存地址的变量,保存哪种变量类型地址要说清楚,通过其访问变量
char* p1=&a[2]; -- *在定义以及初始化中不表示运算,只表示类型;
类型不匹配或者可以强制类型转换
数组名没空间只是指向第一个地址
数组指针还不如数组方便
int main(int argc,char* argv[]) argc 表示程序后带字符串 包括程序本身代表0 argv是后面具体带的字符串或者参数
二级指针指向指针地址的变量 **可以修改原始变量
char* const p
二者意思不同
const char* p
int* p[5];//p是一个数组,5个元素,每个元素int* 如果是函数,就是返回int*
类型的数据
int(*p)[5];//p是指针,指向五个元素的int数组,如果是函数,那么返回就是int类型的数据
函数名就是函数起始地址,另外函数大小不是类型决定的
野指针:也就是指向不可用内存区域的指针。不是NULL指针,是指向“垃圾”内存的指针。很危险,可能原因(指针变量没被初始化,指针被delete或free后没有置为NULL,指针操作超越了变量的作用范围,不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。),误认为合法。
断言:在使用C语言编写工程代码时,我们总会对某种假设条件进行检查,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式。
溢出:在计算机中有个叫“缓冲区”的地方,他是用来存储用户输入的数据的,缓冲区的长度是被事先设定好的,如果用户输入的数据超过了缓冲区的长度,那么就会溢出,而这些溢出的数据就会覆盖在合法的数据上。
悬空指针:局部变量收回,再用,或许会成功,但是不安全。悬空指针(Dangling Pointer)指的是:一个指针的指向对象已被删除,那么就成了悬空指针。野指针是那些未初始化的指针。
sleep(10);windows不能用
fflush(stdout);刷新缓存区,送到屏幕
malloc、calloc、realloc、free
申请 申请初始0 申请旧的覆盖空间 释放
sscanf(字符串, --string从字符串读取。
sprintf(字符数组, -- 同上字符数组
fprintf(文件, --文件FILE*表示文件
fscanf(文件, --同上
stdout、stdin、stderr --系统的FILE* 文件
FILE是个结构,用来操作文件
执行fclose --防止没写入损失数据--怕在缓存区内
#include<stdio.h> int main() { FILE* fi=fopen("in","r"); if(fi==NULL){ printf("open in failed\n"); return 1; } char name[20]; int age; double weight; fscanf(fi,"%s",name); fscanf(fi,"%d%lf",&age,&weight); fclose(fi); printf("name:%s,age:%d,weight:%g\n",name,age,weight); FILE* fo=fopen("out","w"); if(fo==NULL){ printf("open in failed\n"); return 2; } fprintf(fo,"write to some\n"); fprintf(fo,"name:%s,age:%d,weight:%g\n",name,age,weight); fclose(fo); return 0; }
----------------------------------------------------
puts(自动加上换行)/gets(丢弃换行符) fputs/fgets(不做换行)
#include<stdio.h> int main() { char buf[1000]; printf("input:\n"); // gets(buf); // scanf("%[^\n]%*c",buf); fgets(buf,sizeof(buf),stdin); buf[strlen(buf)-1]=‘\0‘; puts(buf); printf("%s\n",buf); fputs(buf,stdout); return 0; }
-----------------------------------------------------
getchar/putchar fgetc/fputc getc/putc ungetc--把已经读了的字符退回去
fseek ftell feof(FILE*) --超越文件末尾 无效
fread/fwrite(内存地址,每个元素字节数,元素个数,文件)
#include<stdio.h> #include<string.h> int main() { char a[100]; strcpy(a,"good after!"); puts(a); strcpy(a,"dear food xixi friends!"); puts(a); printf("%d , %d\n",sizeof(a),strlen(a)); printf("%s\n",strchr(a,‘f‘)); // serach left to right // printf("%s\n",strchr(a,‘k‘)); seg fault cann‘t alive! printf("%s\n",strrchr(a,‘f‘));// search right to left puts(strstr(a,"ear")); char b[]="hello"; if(strcmp(b,"hello")==0) printf("equal\n"); else printf("not equal\n"); return 0; }
----------------------------------------------------------------------------------------
本文出自 “8430296” 博客,请务必保留此出处http://8440296.blog.51cto.com/8430296/1580784
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。