C语言概括总结

1.基础:

(1)system函数:支配电脑干活
函数调用system:运行window命令
例:system(“ifconfig”);

system("pause");//作用:等待用户输入,造成程序在输入之前不会结束

(2)提高程序效率的方法:

1.少用全局变量
2.少用if
3.少定义函数

(3)getchar()函数用来获取一个字符
使用:吸收回车,回车也是一个字符

(4)putchar()函数用来输出一个字符

例如:putchar('\n');

(5)不同类型的数据运算时,比如两个整数相除,必须将除数或者被除数强制转换成小数,否则小数点后面的数据将被忽略

int a;
int b;
float ret;
ret = (float)a/b;

(6)在windows啊哈c中用4个字节表示地址,linux 64位中用8个字节表示地址

(7)一般在main()里面(包括定义的函数里面)是局部变量
main外面是全局变量
少用全局变量

2.选择/判断语句:

(1)死循环:

while1);
for(;;);

(2)一些选择语句的使用:

if(判断){
......
}else{
.....}
if(判断){
......
}else if(判断){
......
}else if(判断){
......
}else{
......
}
switch(){
	case _ :
	case _ ://(执行结果一样)
		执行;
		break;
	case _ :
		执行;
		break;
	default:
		执行;
		break;
}

(3)一些循环语句的使用:

while1{

}
for(初始条件;当不满足此情况不执行循环体;让条件变化)
例:for(i = 0;i < 3;i++){

}

(4)while和do…while的区别:

while

do{...}
while(1);
//后者比前者至少多运行一次

3.函数(函数可以多级调用)

函数调用中,传参就是一个赋值的过程!!!实际参数的值给形式参数
(1)如何定义一个函数:

1.返回值
2.形式参数(局部变量)
3.函数名
4.函数体(代码块)

(2)如何调用一个函数

1.函数名(实际参数);
2.函数名();

(3)一般函数定义几种情况:

1.无返回值无参数
2.无返回值有参数
3.有返回值有参数
4.有返回值有多个同类型参数
5.有返回值有多个参数,参数类型不同
6.根据需求,各种组合都行

4.数组(地址连续):

(1)数组几个重要特征:

1.数组是数据的集合
2.数组的数据是同类型的
3.数组的地址是连续的

(2)数组的几种定义方式

int array[100];没有初始化的数组,仅仅申请了100个整型数的内存空间(最好进行初始化:int array[100] = {0};int array2[3] = {1,2,3};有初始化的数组,完整初始化,该数组申请了三个整型数的内存空间,并赋值三个数1,23
int array3[100] = {1,23};有初始化的数组,不完整初始化,该数组申请了100个整形数的内存空间,但只赋值三个数1,23放在数组的前3个位置

(3)数组的访问和赋值:

scanf("%d",&array[i];
printf("%d",array[i]);

(4)数组的遍历(for循环):

int i;
for(i = 0;i < sizeof(array)/sizeof(array[0]);i++){
	printf(" %d ", array[i]); 
}

(5)数组与函数(数组关心的是数组的首地址(数组名:array;)(第一个元素的首地址:&array[0];))

形式参数中,中括号中的数组的大小是无效的,中括号仅仅用来表示形式参数的一个地址
函数定义void arrayPrint(int data[],int cnt);
						//地址		//个数
函数调用:arrayPrintf(array,sizeof(array)/sizeof(a[0]);
		arrayPrintf(&array[0],sizeof(array)/sizeof(a[0]);
					//一样的(数组的首地址的两种表示形式)

5.指针(地址):

(1)定义和赋值:

  • :只有在定义一个指针变量的时候,才是指针的标识符其余为:取内容
int *p;   或者	int *p = &a;	(错误写法:int *p; *p = &a;)
p = &a;

(2)指针与数组:

int *parray;
parray = &array[0];或者parray = array;
两种遍历方式:printf("%d",*parray);  parray++;(注意指针的位置,不要超出数组,否则会看到乱码)
			printf("%d",array[i]);

(3)指针数组与数组指针

1.指针数组:指针的数组(多个指针)://偏移值:偏移一位
int a = 1;
int b = 2;
int c = 3;
int *P[3] = {&a,&b,&c};

2.数组指针(一个指针)//偏移值:整个数组的大小
int a[3] = {1,2,3};
int (*p)[3];
p = &a;

(4)使用指针的原因:

原因1:给内存的指定位置赋值
int *p = (int *)0x0060ff00;
*p = 10;
printf("在内存的%p位置,存放值是%d\n",p,*p);
原因2:指针操作的是本身(如果操作的是内容本身,main里面的值不变)
例如:void jiajiaA(int *p){
	*p = *p + 1;
	printf("a = %d",*p);
}

int main(){
	int a = 10;
	jiajiaA(&a);
	printf("a = %d);
	return 0;
}

(5)函数指针(存放的是函数的地址)

1.定义
void (*p)();
2.赋值
p = 函数名(函数名就是地址,跟数组一样,数组名就是地址)
3.如何调用
p();	直接通过指针名字加();
(*p)();		取内容(*指针名字)();

(6)无类型指针

定义:int *parray = (int *)malloc (n*sizeof(int));
			数组
int *p; //野指针
int *p = NULL;//不是野指针

(7)内存泄漏
现象:程序刚跑起来很好,跑几个小时,几天程序奔溃
原因:malloc申请的空间,程序不会主动释放,linux中的话,程序结束后,系统会回收这个空间
如何避免:1.注意循环中有没有一直申请空间
2.及时合理的释放

free (p);-----变成野指针
p = NULL;------避免变成野指针

6.字符串(字符数组):

(1)定义

1.char str[5] = "abcde";
2.char str[] = "abcdefgh";
数组元素不写,会根据真实大小来默认分配(整形数组也是)
3.char *pstr = "abcdefghijk";
(指针操作不当,易造成段错误)

(2)字符串的存储方式以及如何计算字符串的大小

存储方式:字符串在内存中,除了有效字符以外,还会自动在后面补一个"\0",作为字符串的结束标识

计算方式:不能用sizeof来计算字符串中有效字符的个数!!!
应该要用strlen,它在计算字符串大小的时候,遇到"\0"后,就结束计数

(3)字符串几种常用的API

头文件:<string.h>(具体使用可以使用的时候百度)
对于一个数组指针要进行多次复制,最好使用memset进行初始化'\0'
1.输出字符串:puts();   printf("%s",pstr);
2.获取字符串:gets();	scanf("%s",p);//内存必须合法
3.计算长度:strlen();
4.初始化:memset(); // memset(cmd,'\0',sizeof(cmd));
5.拷贝:strcpy(); strnpy();
6.拼接:strcat();
7.比较:strcmp();
8.查找子字符串:strchr();
9.查找子串:strstr();
(接下来几个在window环境下,要定义成数组的形态,否则奔溃,Linux下是可以的)
10.转为小写字符串:strlwr();
11.转为大写字符串:strupr();
12字符串分割:strtok();

(4)野指针,避免段错误‘’

char *pstr;//野指针,造成非法内存空间,会出现段错误(具体现象:cmd窗口闪退)
如何避免:开辟空间(char pstr[128] = {'\0');char *pstr = NULL;
pstr = (char *)malloc(128);//malloc一旦使用必须注意内存泄漏
memset(pstr,'\0',128);

7.结构体(类型不同的一组数的集合):

(1)定义、使用和访问

定义:
struct student{
	char *name;(正确写法:strcpy(stu.name,"张三");)(错误做法:stu.name = "张三";)
	(char *name:使用的时候一定要开辟空间)
	int score;
};
使用:
struct student stu = {};
访问:
stu.name;

(2)结构体数组、结构体指针数组

结构体数组:struct student stus[10];
结构体指针数组:
1.struct student stus[5];
struct studnet *p = stus;
2.struct student *p = (struct studnet*)malloc(len*sizeof(struct student);

(3)结构体指针

1.如果使用结构体指针,就不能用点运算符访问结构体中的变量,要用->
2.指针要注意是否为野指针或者NULL,要进行初始化,不然会发生段错误
例:struct student *p;//野指针(初始化)
p = (struct student *)malloc(sizeof(struct student);
3.一旦使用malloc,为了避免内存泄漏:及时合理的释放free(p);

(4)结构体函数指针

struct student *findMaxStu(){

}

(5)面试宝典之结构体的大小如何计算

1.结构体成员的偏移量必须是成员大小的整数倍
2.结构体大小必须是所有成员(数组、结构体除外)大小的整数倍
//结构体中的结构体,如果只是申明,直接不算!!!要定义一个结构体变量才算
对齐方式很浪费空间,确实。。。可是按照计算机的访问规则,这种对齐方式提升了效率

一些注意事项:
联合体的大小就是成员中最大类型的大小

#pragma pack(4);
如果成员的大小超过了pack要求的,就按pack来对齐,如果最大成员大小没有超过pack,结构体的总大小,就按最大成员大小来对齐

(6)typeof为c语言的关键字

作用:为一种数据类型定义一个新名字(这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等))
例:typedef unsigned char u_int8;//8位
typedef unsigned short int u_int16;//16位
typedef unsigned int u_int32;//32位
结构体:typedef struct studnet{
	int score;
	char *name;
}STU;

8.链表(链表的每一项都是结构体)----灵活:

(1)静态创建:

struct Test {
	int data
	struct Test *next;
};
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};

t1.next = &t2;
t2.next = &t3;

printf("use t1 to print three nums\n");
printf("%d %d %d",t1.data,t1.next->data,t1.next->next->data);

(2)链表的遍历:

void printLink(struct Test *head);
{
	struct Test *point;
	point = head;
	while(point != NULL){
		printf("%d",point->data);
		point = point->next;
	}
	putchar('\n');
}

(3)链表的插入—插入新节点

1.节点的后方
void insertBehind(struct Test *head,int data,struct Test *new){
	struct Test *point;
	point = head;
	while(point != NULL){
		if(point->data == data){
			new->next = point->next;
			point->next = new;
		}
		point = point++;
	}	
}
2.节点的前方
两种情况:
//第一个节点目标节点(链头)
//不是头
struct Test* insertHand(struct Test *head,int data,struct Test *new){
	struct Test *point;
	point = head;
	if(point->data = data){
		new->next = head;
		return new;
	}
	while(point->next != NULL){
		if(point->next->data == data){
			new->next = point->next;
			point->next = new;
			printf("已经找到,插入成功\n");
			return head;
		}
		point = point->next;
	}
	printf("没有找到,插入失败\n");
	return head;
}

(4)链表的删除

两种情况://第一个节点(头)//后面的节点
struct Test *deleteNode(struct Test *head,int data){
	struct Test *point;
	point = head;
	if (point->data == data){
		point = point->next;//(如果使用malloc,记得free();,避免内存泄露)
		return head;
	}
	while(p->next != NULL){
		if(p->next->data ==data){
			p->next = p->next->next;
			return head;
		}
		point = point->next;
	}
	return head;
}

(5)链表的动态创建—头插法

struct Test *insertFromHead(struct Test *head,struct Test *new){
	if(head == NULL){
		head = new;
	}else{
		new->next = head;
		head = new;
	}
	return head;
}
struct Test *createLink(struct Test *head){
	struct Test *new;
	while(1){
		new = (struct Test *)malloc(sizeof(struct student));
		printf("input your new node data:\n");
		scanf("%d",&(new->data));
		if(new->data == 0){
			printf("0 quit\n");
			free(new);
			return head;
		}
		head = insertFromHead(head,new);
	}
}

(5)链表的动态创建—尾插法

struct Test insertFromBehind(struct Test *head,struct Test *new){
	struct Test *point = head;
	if(point == NULL){
		head = new; 
		return head;
	}
	while(point->next != NULL){
		point = point ->next
	}
	point->next = new;
	return head;
}
struct Test *createLink(struct Test *head){
	struct Test *new;
	while(1){
		new = (struct Test *)malloc(sizeof(struct student));
		printf("input your new node data:\n");
		scanf("%d",&(new->data));
		if(new->data == 0){
			printf("0 quit\n");
			free(new);
			return head;
		}
		head = insertFromBehind(head,new);
	}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值