C基础复习总结

C基础

数据类型说明

数据类型16位平台32位平台64位平台
char1字节1字节1字节
pointer2字节4字节8字节
short2字节2字节2字节
int2字节4字节4字节
float4字节4字节4字节
double8字节8字节8字节
long4字节4字节8字节
long long8字节8字节8字节

volatile关键字

变量是随时可能变换的,为了防止出现意外的取值(例如从cash,寄存器等中取值),每次使用它的时候必须从变量的地址中取值(从内存中取值),使用volatile关键字后编译器生成的汇编代码会重新从变量的地址中读取数据。

使用场合:

  1. 并行设备的硬件寄存器
  2. 一个中断服务子程序中会访问到的非自动变量,可以使用关键区保护
  3. 多线程应用中被几个任务共享的变量,可以关闭系统调度

指针

函数指针

int (*fun)(int *a)

函数指针数组

int (*fun[10])(int *data,int size);

使用方法

int (*sort_fun[5])(int *data, int size) = {
    QuickSort,       /* 快速排序 */
    InsertSort,      /* 插入排序 */
    BubblSort,       /* 冒泡排序 */
    ShellSort,       /* 希尔排序 */
    SelectSort       /* 选择排序 */
};
// 或者
SortFun[0]=QuickSort;
SortFun[1]=InsertSort;

指针数组

int *a[10];

数组指针

int (*a)[10];
/*
a为指向含10个元素的一维数组的指针变量,
()优先级高,说明a是一个指针,指向一个包含10个整型的一维数组.
 a+1时,a要跨过10个整型数据的长度
*/

二级指针

int **a;

main函数的返回值

  1. 0表示程序正常退出
  2. 负数表示程序异常退出

const关键字

const T

定义一个常量,声明的同时必须进行初始化。一旦声明,这个值将无法更改

const int ConstInt=10; //正确
//constInt=20 ;   //错误,常量值无法更改
const int ConstInt1;   //错误。常量声明时必须进行初始化

const T*

指向常量的指针,不能用于改变其指向的对象的值

const int i = 5;
const int i2 = 10;
const int* pInt = &i;           //正确,指向一个const int对象,即i的地址
//*pInt = 10;                   //错误,不能改变其所指向的对象的值
pInt = &i1;                     //正确,可以改变pInt指针本身的值,此时pInt指向的是i1的地址
//int* pInt = &i;               //错误,i是const int类型,类型不匹配,不能将const int * 初始化为int *
int Value = 15;
const int * pConstInt = &Value;    //正确,可以把int *赋给const int *,但是不可以通过pConstInt改变其所指向对象的值,即Value
//*pConstInt = 40;                    //错误,不能改变其所指向对象的值

const int *与int *const的区别

两者都为指针变量,其区别在于const关键字修饰的对象
简单来说如果const在指针符号*之前时,const修饰的为int ,不可以改变指针本身的值,但是可以通过该指针修改其指向的对象的值,称为常量指针
如果const在指针符号
之后时,const修饰的为指针指向的对象的值,不可以通过该指针修改其指向的对象的值,但是可以改变指针本身的值,称为指针常量

int Value = 10;
int* const p = &Value;
int *const p2 = &Value;
//const int* 指针指向的对象不可以改变,但指针本身的值可以改变;int* const 指针本身的值不可改变,但其指向的对象可以改变。
int Value1 = 10;
int Value2 = 20;
int* const constPoint = &Value1;
//constPoint = & Value2;           //错误,不能改变constPoint本身的值
*constPoint = 40;                   //正确,可以改变constPoint所指向的对象,此时Value1 = 40

const int ConstValue1 = 5;
const int ConstValue2 = 15;
const int* Point = &ConstValue1;
//*Point  = 55;                    //错误,不能改变Point所指向对象的值
Point = &ConstValue2;             //正确,可以改变Point指针本身的值,此时Point邦定的是ConstValue2对象,即Point为ConstValue2的地址

const int* const 是一个指向常量对象的常量指针,即不可以改变指针本身的值,也不可以改变指针指向的对象。

浮点数存储方式

  1. float占4个字节,32bits

|符号位|指数位|尾数部分
-------- | -----|-----|-----
1bits| 8bits|23bits
2.double占8字节,64bits

|符号位|指数位|尾数部分
-------- | -----|-----|-----
1bits| 11bits|52bits

C题目总结

printf返回值

#include <stdio.h>
int main() 
{
  int i = 43;
  printf("%d\n", printf("%d", printf("%d", i)));
  return 0;
}

输出:4321
printf返回值是输出字符的个数(不包括字符串结尾的\0)

enum枚举类型

#include <stdio.h>
int main() 
{
  enum color{
    RED,
    BLUE,
    GREEN=-2,
    YELLOW,
    PINK
  };
  printf("%d %d\n", BLUE, PINK);
  return 0;
}

输出:1,0
enum默认是从0开始的,所以RED=0,BLUE=1,GREEN=-2,YELLOW=-1,PINK=0;

可变参函数

#include "stdarg.h"

char buf[512]={0};

int func(const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  vsprintf(buf, fmt, args);
  va_end(args);
}

大小端判断

#include <stdio.h>

int main(int argc, const char *argv[])
{
	union s
	{
		int a;
		char b;
	};
	union s s1;
	
	s1.a=1;
	if(s1.b=1)
	{
		printf("is small end\n");
	}
	else
	{
		printf("is big end\n");
	}


	return 0;
}

链表

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int DataType;

typedef struct node
{
	DataType data;
	struct node *pNext;
}LinkNode;

typedef struct list
{
	LinkNode *pHead;
	int cLen;
}LinkList;

int IsEmptyLink(LinkList *pList)
{
	return pList->pHead==NULL?1:0;
}

LinkList *createLinkList()
{
	LinkList *pList=malloc(sizeof(LinkList));
	if(NULL==pList)
	{
		perror("fail to malloc");
		return NULL;
	}
	pList->pHead=NULL;
	pList->cLen=0;

	return pList;
}

int insertHeadLinkList(LinkList *pList,DataType data)
{
	LinkNode *pInsertNode=malloc(sizeof(LinkNode));
	if(NULL==pInsertNode)
	{
		perror("fail to malloc");
		return -1;
	}

	pInsertNode->data=data;
	pInsertNode->pNext=pList->pHead;
	
	pList->pHead=pInsertNode;
	pList->cLen++;

	return 0;

}

int insertTailLinkList(LinkList *pList,DataType data)
{
	if(IsEmptyLink(pList))
	{
		insertHeadLinkList(pList,data);
		return 0;
	}

	LinkNode *pTmpNode=pList->pHead;
	while(pTmpNode->pNext)
	{
		pTmpNode=pTmpNode->pNext;
	}

	LinkNode *pInsertNode=malloc(sizeof(LinkNode));
	if(NULL==pInsertNode)
	{
		perror("fail to malloc");
		return -1;
	}


	pInsertNode->data=data;
	pInsertNode->pNext=NULL;
	pTmpNode->pNext=pInsertNode;
	pList->cLen++;

	return 0;
}

int deleteHeadLinkList(LinkList *pList)
{
	if(IsEmptyLink(pList))
	{
		return 0;
	}

	LinkNode *pDeleteNode=pList->pHead;
	pList->pHead=pDeleteNode->pNext;
	pList->cLen--;
	free(pDeleteNode);

	return 0;
}

int deleteTailLinkList(LinkList *pList)
{
	if(IsEmptyLink(pList))
	{
		return 0;
	}

	LinkNode *pTmpNode=pList->pHead;

	if(NULL==pTmpNode->pNext)
	{
		deleteHeadLinkList(pList);
	}
	else
	{
		while(pTmpNode->pNext->pNext)
		{
			pTmpNode=pTmpNode->pNext;
		}

		LinkNode *pDeleteNode=pTmpNode->pNext;
		free(pDeleteNode);
		pTmpNode->pNext=NULL;
		pList->cLen--;
	}

	return 0;
}

LinkNode *findMidLinkList(LinkList *pList)
{
	if(IsEmptyLink(pList))
	{
		return NULL;
	}
	
	if(NULL==pList->pHead->pNext)
	{
		return pList->pHead;
	}

	LinkNode *pFastNode=pList->pHead;
	LinkNode *pSlowNode=pFastNode;

	while(pFastNode)
	{
		pFastNode=pFastNode->pNext;
		if(NULL==pFastNode)
		{
			break;
		}
		pFastNode=pFastNode->pNext;
		pSlowNode=pSlowNode->pNext;
	}

	return pSlowNode;
}

LinkNode *findLastKLinkNode(LinkList *pList,int K)
{
	if(IsEmptyLink(pList))
	{
		return NULL;
	}

	LinkNode *pFastNode=pList->pHead;
	LinkNode *pSlowNode=pFastNode;

	for(int i=0;i<K;i++)
	{
		pFastNode=pFastNode->pNext;
		if(NULL==pFastNode)
		{
			return NULL;
		}
	}

	while(pFastNode)
	{
		pSlowNode=pSlowNode->pNext;
		pFastNode=pFastNode->pNext;
	}

	return pSlowNode;

}

void reverseLinkList(LinkList *pList)
{
	if(IsEmptyLink(pList))
	{
		return;
	}

	LinkNode *pInsertNode=NULL;
	LinkNode *pTmpNode=pList->pHead;

	pList->pHead=NULL;

	while(pTmpNode)
	{
		pInsertNode=pTmpNode;

		pTmpNode=pTmpNode->pNext;
		
		pInsertNode->pNext=pList->pHead;
		pList->pHead=pInsertNode;

	}

	return;
}

void sortLinkList(LinkList *pList)
{
	if(IsEmptyLink(pList))
	{
		return;
	}

	LinkNode *pTmpNode1=NULL;
	LinkNode *pInsertNode=NULL;

	pTmpNode1=pList->pHead->pNext;
	pList->pHead->pNext=NULL;
	
	while(pTmpNode1)
	{
		pInsertNode=pTmpNode1;
		pTmpNode1=pTmpNode1->pNext;

		if((pList->pHead->data)>(pInsertNode->data))
		{
			pInsertNode->pNext=pList->pHead;
			pList->pHead=pInsertNode;
		}
		else
		{
			LinkNode *pTmpNode2=pList->pHead;
			
			while(pTmpNode2->pNext)
			{
				if((pTmpNode2->pNext->data)>(pInsertNode->data))
				{
					break;
				}

				pTmpNode2=pTmpNode2->pNext;
			}

			pInsertNode->pNext=pTmpNode2->pNext;
			pTmpNode2->pNext=pInsertNode;
		}
	}

	return;

}

void destroyLinkList(LinkList **ppList)
{
	if(IsEmptyLink(*ppList))
	{
		*ppList=NULL;
		return;
	}

	while((*ppList)->pHead)
	{
		deleteHeadLinkList(*ppList);
	}

	free(*ppList);
	*ppList=NULL;

}

void showLinkList(LinkList *pList)
{
	if(IsEmptyLink(pList))
	{
		return;
	}

	LinkNode *pTmpNode=pList->pHead;

	while(pTmpNode)
	{
		printf("data:%d\t",pTmpNode->data);
		pTmpNode=pTmpNode->pNext;
	}

	printf("\n");

	return;
}

排序算法

在这里插入图片描述

冒泡排序

  1. 算法步骤
    在这里插入图片描述
  2. 时间复杂度
    平均: O(n2) 最好: O(n) 最坏:O(n2)
  3. 空间复杂度
    O(1)
void bubble_sort(int a[],ssize_t len)
{
	ssize_t i=0,j=0;
	int tmp=0;

	for(j=0;j<len-1;++j)
	{
		for(i=0;i<len-j-1;++i)
		{
			if(a[i]>a[i+1])
			{
				tmp=a[i];
				a[i]=a[i+1];
				a[i+1]=tmp;
			}
		
		}
	}

	return;
}

选择排序

  1. 算法步骤
    在这里插入图片描述
  2. 时间复杂度
    平均: O(n2) 最好: O(n2) 最坏:O(n2)
  3. 空间复杂度
    O(1)
void select_sort(int a[],ssize_t len)
{
	ssize_t i=0,j=0,min=0;
	int tmp;

	for(j=0;j<len-1;j++)
	{
		min=j;
		for(i=j+1;i<len;i++)
		{
			if(a[i]<a[min])
			{
				min=i;
			}
		}
		if(min!=j)
		{
			tmp=a[j];
			a[j]=a[min];
			a[min]=tmp;
		}
	}

	return;
	
}

插入排序

  1. 算法步骤
    在这里插入图片描述
  2. 时间复杂度
    平均:O(n2) 最好:O(n) 最坏:O(n2)
  3. 空间复杂度
    O(1)
void insert_sort(int a[],ssize_t len)
{
	int i=0,j=0;
	int tmp=0;

	for(j=0;j<len;++j)
	{
		tmp=a[j];
		for(i=j;i>0&&tmp<a[i-1];--i)
		{
			a[i]=a[i-1];
		}

		a[i]=tmp;
	}

	return;
}

快速排序

  1. 算法步骤
    在这里插入图片描述

  2. 时间复杂度
    平均: O(nlogn) 最好: O(nlogn) 最坏:O(n2)

  3. 空间复杂度
    O(nlogn) 用于方法栈

void quick_sort(int a[],ssize_t head,ssize_t tail)
{
	if(head>tail)
	{
		return;
	}

	int i=head,j=tail,key=a[i];

	while(i<j)
	{
		while(i<j&&key<=a[j])
		{
			j--;
		}
		a[i]=a[j];
		while(i<j&&key>=a[i])
		{
			i++;
		}
		a[j]=a[i];
	}
	a[i]=key;

	quick_sort(a,head,i-1);
	quick_sort(a,j+1,tail);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值