C语言总结

C语言常见总结

1.通过调用指针,交换数值
在这里插入图片描述
2.带头结点和不带头结点链表的区别

一、两者区别:

1、不带头结点的单链表对于第一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常在单链表的开始结点之前附设一个头结点。
2、带头结点的单链表,初始时一定返回的是指向头结点的地址,所以一定要用二维指针,否则将导致内存访问失败或异常。
3、带头结点与不带头结点初始化、插入、删除、输出操作都不一样,在遍历输出链表数据时,带头结点的判断条件是while(head->next!=NULL),而不带头结点是while(head!=NULL),虽然头指针可以在初始时设定,但是如1所述,对于特殊情况如只有一个节点会出现问题。

 二、为什么不带头结点初始化有2种方式,而带头结点只有1种方式呢?       

因为不带头结点声明Node *head 时;C编译器将其自动初始化为NULL,于是根本不需要调用InitList(head);也即不带头结点的初始化是个伪操作。而带头结点的初始化在堆开辟了一段内存,需要修改head指针变量指向的地址(即head的值),所以要修改head的值,必须传保存head变量的地址(即二维指针)。而直接调用CreatList(head);相当于传head变量的值,函数修改的是head的副本,无法真正改变head的值。 注:这里可以将head指针看成一个变量(不管它保存的是地址),就比较好理解了。

  三、其实本质上还是传值,传址的问题,只不过指针本身保存的地址,让这个过程变得有点纠结。

在函数调用需要修改指针变量的指向(value)时,应该传递指针变量的地址(address)。 另外,对于函数的形参是指针时,只要该参数不在左边(即都是右值操作),二维指针(形参)就可以简化为一维指针。如上面带头结点的尾插简化版本。

所有链表都有头指针head,带有头结点的链表中的head的数据项为空;不带头的链表直接在头结点处存入数据,那么当从头插入数据时,head需要时刻变化。

3.C语言常见类型占用字节数目
int 4 byte ,32 bit ;
short 2 byte at least;
long int 8 byte;
char 1 byte;
在这里插入图片描述
decimal 十进制
在这里插入图片描述

continue,break
break只可以用于循环体和switch语句中的跳出;只能跳出一层循环;结束整个循环过程
continue为结束本次循环
在这里插入图片描述
return 返回计算结果或者状态码来表示函数执行顺利与否
“return;”在被调用函数是void类型时候,可以起到退出结束函数作用。

编码
ASCII码是一种等长编码
等长编码
优点:每个字符对应的二进制编码长度相同,容易设计,方便读写;
缺点:编码结果太长,会占用过多资源;(计算机的存储的空间和网络传输的带宽是有限的)
哈夫曼编码:
1.任何一个字符编码,都不是其他字符编码的前缀
2.信息编码的总长度最小
3.实现算法:
根据所给元素所占权重值构造哈夫曼树;在哈夫曼树上求出每个叶节点的编码
求哈夫曼树的叶结点的实现方式
从叶子结点一直找到根结点,逆向记录途中经过的结点的权重值;
从根结点出发,一直到相应叶子结点,记录途中经过结点的权重值;

文件指针
在这里插入图片描述
fputs()和fgets()函数用于从流中写入和读取字符串。
写文件:fputs()函数 fputs()函数将一行字符串写入文件,它将字符串输出到流。
其行为方式如下:
(1)遇到换行或文件结束EOF则返回。
(2)按行读取。
(3)每一行结束处的换行字符‘/n’也算该行字符。
(4)对于大小为size的buf,最多只读取size-1个字符。
(5)自动地把buf中最后一个字符(通常是换行符)的后面一个字节填充零结束符(’/0’)。

char fgets(char *s,int n,FILE *fp)
从fp中逐个读取字符,碰到换行符,停止读取动作,把当前字符包括换行符赋给s;如果当前字符串是空值就不会赋值给s,但是s原来有值的话,s会保持原值。
如果用fgets读取文件的内容,文件结尾是一个换行符,用以下程序,最后一行会输出两次。

while( !feof(fp) )

{
fgets( s , sizeof(s) , fp );

printf("%s" , s);

}

因为当读到最后一行时,只读到换行符,因为没有读到结束符 ,所以 !feof(fp) 还是真,继续下一轮循环。
最后一次fgets时,读取不到内容,所以 s 的内容没有更新 (并不是在最后一行读了两次的原因才导致输出两次,而是因为没读到新值)。

解决方法,在 fgets( s , sizeof(s) , fp ) 之前清空s ,即加上一句memset(s , 0 , sizeof(s) ) ,最后一行就不回输出两次。

while( !feof(fp) )

{
memset(s , 0 , sizeof(s) );

fgets( s , sizeof(s) , fp );

printf("%s" , s);

}
如果文件最后一行没有换行符,那么最后读取得到的s值是一个没有换行符的字符串。

ld returned exit 1 status 可能原因:
1.找不到主函数
2.函数,变量,句柄的声明没有定义
3.链接器出错

assignment to expression with array type 可能原因

1.数组不能直接给数组赋值
2.指针不能直接给指针赋值
在这里插入图片描述
在未知输入数字个数时,利用指针存储数字

#include<stdio.h>
#include<malloc.h>

int main()
{
	int i=0,j=0,num=0;
	int* n;
	int *x;
	scanf("%d",&num);
	while(num!=-1)
	{
	//(n+i)=(int *)malloc(sizeof(int)); 是错误写法  
        x=(n+i); 
		x=(int*)malloc(sizeof(int));
		n[i]=num;
		scanf("%d",&num);
		i++;
		
	}
	printf("i=%d\n",i);	
	for(j=0;j<i;j++) 
	  printf("%d ",n[j]);
	
	return 0;
}
备注:错误写法出现:lvalue required as left operand of assignment
左值应该是变量而不是表达式

C语言指针

1.结构体指针

当左边是个对象时用“.”
当左边是个指向对象的指针时用“->”

比如,Class A;
Class *B=A;
A有函数myfun()

则调用时用
A.myfun();
B->myfun();

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值