C语言笔记杂记

来源:互联网 发布:js图片旋转代码 编辑:程序博客网 时间:2024/05/04 02:03
C语言编译过程
1 -E 预编译
gcc -E -o a1.c a.c
-o指的是编译成为的文件名为a,-E指的是预编译,预编译直接将头文件内容原封不动移到文件中。

2 -S 汇编
gcc -S -o a.s a1.c
将预编译后生成的a1.c文件汇编为a.s汇编文件,即C语言转化为C语言。

3 -C编译
gcc -C -o a.o a.s
将代码编译为二进制指令。a.s汇编文件转化为a.o二进制文件。

4 链接
gcc a.c
./a.out

删除命令:
sudo rm -rf a.out

用户:fangding fangding
用户:zhu zhu
ibus-daemon -d -x -r


gcc -o a a.o
gcc没有任何参数就是代链接


计算机内存(用户区域/内核区域)
32位操作系统最大内存为4G,操作系统占用1G,其他3G给用户。
1 用户模式
应用程序都是运行在用户区域
2 内核模式
操作系统的内核,设备驱动程序这些都在系统内核上运行
8位CPU a b c d(寄存器)
16位CPU ax bx cx dx(ah+al=ax)(寄存器)
32位CPU eax ebx ecx edx(寄存器)
64位CPU reax rebx recx redx(寄存器)

IT三大重要因素
1 操作系统
2 编译器
3 数据库


GBK编码下一个汉字是两个字节
UTF-8编码下一个汉字是三个字节
如果将一个字符串当作char来处理,汉字字符肯定是一个负数


随机数
int t=(int)time(NULL);//得到系统时间
srand(t);//随机数种子发生器
int value=rand();//随机数函数

#include<time.h>
time_t t=time(NULL);

scanf函数输入字符串的时候遇到空格或者回车都会结束。
gets函数输入字符串的时候遇到回车会结束
fgets(a,sizeof(a)-1,stdin); 第一个参数是数组,第二个参数是数组大小(单位:字节),第三个参数是标准输入。
fgets的时候比较安全,只要第二个参数小于数组大小就可以避免溢出的问题。
puts函数在输出的时候会自动打印一个‘\n’
fputs(s,stdout);往文件里面打印

#include<string.h>
strcat(s1,s2);
strncat(s1,s2,n);限制追加多少字符以防止溢出
strcmp(s1,s2);
strncmp(s1,s2,n);比较前n个字符
strcpy(s1,s2);
strncpy(s1,s2,n);把s2的前n个字符拷贝到s1的前n位里面

sprintf(s,"%d",n);将格式化后的字符串输出到第一个参数指定的字符串中。//整数转化为字符串
eg:sprintf(str,"D:\\temp\\%d.jpg",rand()%10);

atoi()是标准的C语言函数
itoa()不是标准的C语言函数

char s[100]="abc=300";
int i=0;
sscanf(s,"abc=%d",&i);//从字符串中得到一个值
printf("%d\n",i);

const char *buf=strchr(s,'o');//在s中查找字符'o',返回一个指针。
char* strstr(char* str,const char* sub_str);返回指针,没有找到返回NULL

strtok 分割字符串
char s[100]="abc_def_12345";
char buf[100];
buf=strtok(s,"_");
buf=strtok(NULL,"_");
buf=strtok(NULL,"_");
第一次调用的时候第一个参数为字符串,后面就是NULL
buf=strtok(s,"_");
while(buf)
{
buf=strtok(NULL,"_"); //如果没有找到指定的符号就会返回NULL
}

atoi/atol/atof

如果C语言函数没有明确标明一个返回值类型,那么默认就是int类型。

汇编语言是一款最基础的C语言,加上能编译一个读写文本和二进制文件的能力成为稍微优化版本的C语言编译器,逐渐优化为高效的C语言编译器

条件预编译
头文件中使用,以防止程序中多次包含同一个头文件时多次重复编译
#ifndef __AH__ //__AH__是自己定义的宏名
#define __AH__ //要大写并且有下划线,必要时加数字
……
#endif


递归给编程问题提供了最简单的方法,但是一个有缺陷的递归会耗尽计算机的资源,递归程序难以理解和维护。


指向NULL的指针叫做空指针,没有指向具体指向任何变量地址的指针叫做野指针。
空指针合法的,野指针是危险的。

指针,
int a=0x1310;
char* p=&a;
printf("%d\n",*p);//打印出16,小端存储

指向常量的指针 const char *p; 指向常量的指针
常指针 char *const p; 指针本身是一个常量

指针数组 int *p[10];
数组指针 int (*p)[10];
函数指针 int *fun();
指针函数 int (*p)();

指针函数:
int add(int a,int b){}
int max(int a,int b){}
int fun(int (*p)(int ,int),int a,int b)
int (*p)(int ,int);
函数指针:
buf[10];
memset(buf,0,sizeof(buf));将buf中的内容全部设置为0
memcpy(buf2,buf1,sizeof(buf1));将buf1中的全部拷贝到buf2中
memmove(buf2,buf1,sizeof(buf1));将buf1中的全部移动到buf2中
memcpy使用的时候不能有重叠区域,而memmove可以在重叠区域移动。

交换两个数
{
*a+=*b;
*b=*a-*b;
*a=*a-*b;
}

主函数中有参数
int main(int argc,char *args[])
{
//argc代表程序执行的时候有几个参数,最小值为1. a.c 参数2 参数3
//args是一个指针数组,每个成员的类型是char *,argc的数量就是成员的
数量
printf("%d\n",argc);
return 0;
}


内存管理
一个C语言变量的作用域可以是代码块作用域,函数作用域,文件作用域。
C语言中默认是auto类型变量。extern是外部变量。register是寄存器变量,寄存器变量是没有地址的,所以不能进行地址操作。静态变量只初始化一次,而且程序运行期间静态变量一直存在。如果全局变量加了static,那么这个变量的全局作用域仅限于本文件。
C语言中函数默认都是全局函数,如果加了static关键字,那么这个函数只能在本文件中使用。

内存区(基本四区)
#include<stdio.h>
int c=0; //全局变量,静态区
int main()
{
static int d=0; //静态区
int a=0; //auto变量存放在栈区
int b=0; //auto变量存放在栈区
printf("%d,%d,%d,%d,%d",&a,&b,&c,&d,main)
return 0;
}
1 代码区
程序被操作系统加载到内存的时候,所有的可执行代码都会被
2 静态区
所有的全局变量和静态变量都存放在静态区
3 堆区
可以动态申请内存空间,堆中申请的空间不会自动释放,用free,但是栈空间中不能用free。
4 栈区
先进后出,对于自动变量,什么时候出栈,什么时候入栈都是自动的。

int *test() //非法,栈空间在函数执行结束后就会释放
{
int a=0;
return &a;
}
int *test() //合法,静态区,但是不能使用free
{
static int a=0;
return &a;
}
int *test() //合法,在堆区
{
int *p=(int *)malloc(sizeof(int));
return p;
}


内存的最小单位是字节,而操作系统管理内存的最小单位是页。
char *p = (char *)malloc(10*sizeof(char));
分配内存后初始值是随机的,memset初始化。
char *p = (char *)calloc(10,sizeof(char));
分配内存后初始值已经弄好了。
char *p1 = (char *)realloc(p,20);
在原有内存的基础上在堆中间增加连续的内存,如果没有足够的连续空间可扩展,那么会新分配一个空间,将原有的空间复制到新的空间,然后释放之前的空间。增加的内存空间初始化值是一个随机数。

C语言函数中的参数都是从右向左的顺序进栈的。内存地址从低到高是递减的。

在C语言函数参数中尽量使用指针,因为效率较高,必要时定义为const类型。









0 0
原创粉丝点击