C语言纯文本笔记(基础结构+Linux多任务编程)

1.数组

注意:数组下标越界问题
数组初始化:
	int arr[5] = {1,2,3} ;           部分初始化,没初始化的默认为0
	int arr[5] = { 0 };              全部清0

获取数组元素个数
	printf("sizeof() = %d",sizeof(stu)/sizeof(stu[0])); 

数组作函数参数,会转换成指针,也就是在函数内部sizeof(arr)是4

2.字符串

字符串的存储方式:
eg1:char str[20]="hello linux";//字符数组
eg2:char *buf="hello linux";//字符指针

字符串以'\0'结束
	strlen(buf)是字符串的有效长度,不包含'\0',sizeof(buf)包括'\0'.
	sprintf(str,"hello %d is age = %s",age,name);//字符串格式化
	system(char * cmd);

字符串函数头文件<string.h>
	字符串函数有:strcpy(),strncpy(),strcat(),strcmp(),strncmp(),strstr(),strlen().

3.函数

void *thread_handle(void* arg)
{
    printf("hello\n");
}

int main(int argc,char* argv[])
{
    return 0;
}

注意:
	1.不可以在函数内部定义放在另外一个函数
	2.形参是实参的拷贝本,形参和实参占用不同的内存空间,形参改变不会影响实参。
	3.实参和形参:在调用的时候括号中的实际参数,是在内存中存在的。
	4.在定义函数的时候,小括号中的参数(有类型) 

4.链表

链表:结构体加指针
优点:增加节点、删除节点方便、链表大小可动态增加
缺点:查数据需要遍历链表
struct list_head {    
	int data;
	struct list_head *next,*prev;
};

5.递归

递归:函数自己调用自己
 递归的诀窍:
   1.需要找到特殊值,(结束值)。
   2.找到通用公式。
   3.尽量避免定义变量和申请内存
   4.一定是要有出口,有return。

6.开关变量和标志位

   	1、开关变量可用于循环中控制代码块的执行次数。
	2、标志位用于判断程序的执行状态

7.标准I/O

	标准IO通过操作FILE* 指针对文件进行读写。标准IO创建了缓冲区,以实现减少系统调用的次数。
头文件:#include<stdio.h>
标准IO函数:
	fopen(),fscanf(),fprintf(),fread(),fwrite(),fseek(),fclose().
错误处理:
头文件:#include<errno.h>,#include<strerror>
eg:
{
    FILE *fp;
    if((fp=fopen("hello.txt","a+"))==NULL)
    {
        perror("fopen error");//不换行,换行不好查看
        exit(-1);
    }
}
    
eg:
#include <stdio.h>
int main()
{
    char a, b;
    while (scanf("%c %c", &a, &b) != EOF)
    {
    	getchar();
        printf("%c %c\n", a, b);
    }
    return 0;
}
使用scanf且输入的是%c时scanf()会读取换行符,使用getchar()获取空格。 

8.文件I/O


1.linux一切皆文件,文件描述符是一个索引值,读写文件时需要把文件描述符当做参数进行传递。


2.一个进程启动都会打开三个流,stdin,stdout,stderr;对应文件描述符是0,1,2
	写代码时根据函数参数判断,FILE* 是stdin,stdout,stderr;int 是0,1,2。

3.文件IO函数
	open(),write(),lseeK(),read(),close();
	read()读文件时注意对文件读写位置进行定位。
	文件IO函数不带缓冲区。

9.linux多任务编程

1.进程(资源分配的最小单位)
    	进程之前是独立的,通过特定的通信机制可以实现相互通信。
    	进程标识符唯一标识一个进程
    1.1进程函数
    	
   	1.fork()  
   		getpid():获取当前进程的id.getppid():获取当前进程夫进程的id.
		xxx_t 类型 大部分情况下是unsigned int
   		注意:子进程没有执行fork()语句,而是fork下一条开始执行。
   		 	
   	进程是通过if-else结构实现的。
    eg:
    pid_t fid=fork();
    if(fid<0)
    {
        perror("fork error");
        exit(-1);
    }
    if(fid>0)
    {
        此代码块相当于父进程main();
    }
    if(fid==0)
    {
        此代码块相当于子进程main();
    }


     2.exec函数族
    	调用可执行文件替换当前进程的数据段,代码段,堆栈段。不创建新的进程。
    	
     3.exit()和_exit():进程退出函数
    		exit()函数检测进程打开了哪些文件,将缓冲区的内容写入文件
  		  _exit()直接退出
  		  
   	 4.wait()和waitpid():等待进程
    		wait();wait()使父进程阻塞,等待一个终止的子进程
    		waitpid();等待一个特定的子进程终止
    		阻塞:等待需要的资源,释放cpu。被动的,因为得不到资源。
   			挂起:进程挂起的结果是从内存移到外存,所以挂起不占内存.
         因为挂起后还要受到CPU的监督(等待着激活),所以挂起不释放CPU
2.线程(cpu调度的最小单位)
    	1.线程与同一进程下的其他线程共享进程的内存空间和资源,所以线程的上下文切换比进程小很多。
    共享进程内存空间和资源带来的问题,数据谁都可以操作,不能保证它的准确性,需要引入互斥和同步机制。
    
    互斥:一个时间点(很小的时间段)只能有一个线程访问共享数据。
    同步:在互斥的基础上按一定的顺序进行访问。
    
    	线程是通过函数结构实现的。
    	2.线程函数
    	pthread_create()创建线程
    	pthread_exit()退出线程
    	pthread_join()等待线程结束
   		pthread_cancel()主动取消线程
    
  		3.线程之间的同步与互斥
    	互斥锁机制
   		 1.pthread_mutex_init()互斥锁初始化函数
    	 2.pthread_mutex_lock()上锁函数,阻塞
    	 3.pthread_mutex_trylock()判断是否上锁,没上就上锁,上了就立即返回,不阻塞
    	 4.pthread_mutex_unlock()解锁
    	 5.pthread_muxtx_unlock()销毁锁
    	信号量机制
    	信号量本质是一个非负整数,用于控制公共资源的访问
    	PV操作,P减1,V加1
    	互斥:只设置一个信号量sem
    	同步:需要设置多个信号量
    	 1.sem_init() 初始化信号量
   		 2.sem_wait() 相当于P操作,阻塞
    	 3.sem_trywait() 相当于P操作,不阻塞
    	 4.sem_post()相当于V操作
    	 5.sem_getvalue()获取信号量的值
    	 6.sem_destroy()删除信号量
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值