【自用】小h碎碎念
记一些让我直呼内行的point。
12.17
1 //用typedef避免反复写长串定义 2 typedef char* (*MY_P)(char* , char* ); 3 MY_P _swap; 4 _swap(s1,s2);
1 //神奇的指针 2 char* p; 3 switch(opt) 4 { 5 case 1:p=strcmp; 6 case 2:p=strcpy; 7 } 8 p(s1,s2);
1 //奇怪的学院派链表 2 //next定义为struct*,指向下一个的地址 3 #include<stdio.h> 4 #include<stdlib.h> 5 struct emm{ 6 int v; 7 struct emm* next; 8 }node1; 9 #define N 4 10 int main() 11 { 12 int i; 13 struct emm* now = &node1; 14 for(i=1;i<=N;i++) 15 { 16 struct emm* p; 17 p=(char *)malloc(100); 18 p->v=i*i; 19 now->next = p; 20 now = p; 21 } 22 now = &node1; 23 for(i=1;i<=N+1;i++) 24 { 25 printf("%d ",now->v); 26 now = now->next; 27 } 28 return 0; 29 }
12.21
于是就有:
(s.b+1)[3] = *(s.b+1+3) //s为结构体 b为结构体内数组
(hzz大呼内行!)
12.22
- main居然可以带参数!
- 居然有一个变量类型叫FILE!
- fopen太神奇啦!可以从多文件和控制台输入输出!
- fgets太神奇啦!
1 #include<stdio.h> 2 #include<stdlib.h> 3 int main(int argc,char *argv[]){ 4 //argc:命令中字符串个数 argv[]:命令(截成字符串) 5 FILE *fio;//定义FILE变量的指针fio 6 if(argc==3) fio=fopen(argv[2],"r"); 7 //以读取模式,使fio指向名叫argv[2]的文件 8 else fio=fopen(argv[1],"r"); 9 char buff[1000]; 10 int cnt=0; 11 while(fgets(buff,1000,fio)!=NULL){ 12 //从fio指向的文件里读取一行,存到buff数组 13 //至多存1000个字符 可防溢出 14 printf("%4d %s",cnt+1,buff); 15 //fgets会读回车,所以不用手动输出回车 16 cnt++; 17 if(argc==3 && cnt%25==0) system("pause"); 18 } 19 fclose(fio);//好习惯? 20 }
12.27补充:
注意:调用exe文件的那句话也会存进argv!
eg:
1 //zz.c 2 #include<stdio.h> 3 int main(int n,char *argv[]) 4 { 5 printf("%d\n",n); 6 int i; 7 for(i=0;i<n;i++) 8 printf("%s\n",argv[i]); 9 return 0; 10 }
12.24
由:
1 int main() 2 { 3 int a,b; 4 swap(&a,&b); 5 } 6 void swap(int* x,int *y) 7 { 8 ...//*x == a 9 }
拓展得:
1 int main() 2 { 3 struct emm* p; 4 change(&p); 5 } 6 void change(struct emm **p_now) 7 { 8 ...//*p_now == p 9 }
//如果要取p指向的值就是**p_now(结合*(p+i)==p[i]思考
也就是,想要在自定义函数中改变目标值,只需要:
1.在调用时加个&
2.在函数定义的时候多加个*
12.27
*(t++) == *t++ == *t,t++
这个装饰性的括号...emmm....
- char* const p:p is const pointer to char
- const char* p:p is pointer to const char
- const char* const p:p is const pointer to const char
总之从右往左读。
这几个p指的值貌似都不能更改。
- %h:short
- %hu:unsigned short
- %hx:short(16进制)
用short的时候尤其关注有没有越界,short是 -32768 ~ +32767 ,正的要少一个数。
sizeof():变量所占的内存,对char[ ]而言,包括'\0';
strlen():存了东西的长度,不含'\0';
补充:
定义char数组时,如果写:char[ ] = {"hello"},那么编译器会自动在后面加‘\0’。
但如果是char[5] = {"hello"},那就不会有'\0',但程序健壮性低。
char[ ]={'h','e','l','l','o'}也不会有'\0',健壮性也低。
char数组默认填充'\0'字符。
https://blog.csdn.net/questionhahaha/article/details/84782216
sizeof(结构体)时,需要做字节对齐。eg:
struct emm{
char c;
int x;
};
则:
- 总size是成员的最大size的整数倍,即al=4的倍数
- 需对齐,每一个成员的位置都是它size的整数倍。
所以内存分配:c***xxxx
struct嵌套时,把嵌套的struct拆开。
教材:https://blog.csdn.net/qq_33263769/article/details/88547514
include和define都是编译器的工作,不属于关键字。
fopen:
- r:打开只读文件,必须存在
- r+:打开读写文件,必须存在,从头开始写
- w:打开只写文件,可以不存在,打开的同时清空
- w+:打开读写文件,可以不存在,打开的同时清空
- a:打开只写文件,可以不存在,接在后面写
- a+:打开读写文件,可以不存在,接在后面写
另外加b字符:以二进制文件形式打开
void *p:万能指针
- √ 可以指向任何类型的元素
- × 不能直接取值,需要强转。eg:*(char *)p;
- × 不能左右移
所以通常用作类型中介。
1.3
int 在计算机中的存储:
低位->高位
p[0]->p[3]
即char *p = &a的p指向最低位。
函数指针数组:
int (*a[4])(int a,int b);
转义字符:
- 一般转义字符
- \n \t \\...
- 用来表示不能直接显示的字符
- 八进制转义字符
- \45 \0 \77...
- 反斜杠后面的数,默认为八进制。( \8 ×
- 十六进制转义字符
- \x1 \xa
- 在反斜杠后面加个x,不能加0x。
*(a+1)[1]的时候,要改成(*(a+1))[1],才能输出a[1][1]的值。
变量:
- auto
- 只能修饰局部变量
- 默认值为乱码
- 在C里面属于脱裤子放屁
- extern
- 只能修饰全局变量
- 用来引用其他文件的全局变量
- register
- 只能修饰局部变量
- static
- 把局部变量变成全局变量
- 也能修饰全局变量
- 其它文件不能使用
- 变量只会被初始化一次,默认为0
全局变量的生命周期和程序执行时间相同,局部变量生命周期和对应函数相同。
1.4
对一个常数小数而言,默认为double。
eg:1.0(double类型)
如果要默认为float,则需加f:1.0f(float类型)
21.11.10
malloc
往指针指向的东西里存东西,记得先malloc。
int* p1 = (int *)malloc(sizeof(int)); NODE* p2 = (NODE *)malloc(sizeof(NODE));