在某培训机构的听课笔记

时间:2020-11-30 17:13:02

某实训机构有些小坑,听课加反省就当作对C语言的一种补充吧,哎~~~~,记录给自己看看。

1.int a=9,b=10,d=9;是可以的。

2.%*d ,在scanf中使用的时候,是1整数但不赋给任何变量,有个小代码:

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

int main()
{
int a=23,b=5,c=9;
scanf("%*d%d%d",&a,&b,&c);
printf("%d,%d,%d",a,b,c);
return 0;
}

a的值,你是赋值不进去的,仅仅占位用的。

3.对于冒泡排序,怎么在不完全执行完循环前就预先判断,已经排序结束了:

在一次内层循环的时候,一次都没有进行数据交换,就说名冒泡排序已经排序ok了。

4.不要总记得scanf,同样还存在getchar()和gets()函数,gets能接收含有空格的字符串,这个是scanf不能做到的。

scanf("%ls",a);  //接收有效字符串的第一个字符

scanf("%ns",a);   //这个是格式化输入,接收字符串的从头开始的n个字符

其实我想说,scanf函数真心没有什么用,很不好的一个函数。

5.堆区分配内存是从两头开始增长的,不是单向增长的。

6.typedef int [10]   其实[10]就是int了,个人觉得这个代码风格,很不好,千万不能写成这样,可读性很差!

7.要记住函数在传递参数的时候,其实是数据的拷贝,直接对形参进行改变或者赋值,是毫无意义的,实参是不会改变的。对于指针也是一样的。只有通过指针,取得了当前这个指针指向的内容的时候,改变了这个内容,这样实参才会被改变。因为是直接改变了内存地址中保存的数值。

举个例子就是:在数据结构那节中的链表,creat函数就是一个典型的例子。仔细想想为什么不能在main函数中定义一个头结点,再把这个头结点的地址传给creat函数呢?一定要通过creat返回一个头结点指针呢?再想想,为什么在想通过形参获得子函数中数据的时候,一定要传入地址或者指针呢?然后再把想要获得数据,写入这个地址或者指针中去?

给一段代码,帮助理解这个问题:

#include <stdio.h>
#include <malloc.h>
typedef struct _tag_str
{
int a;
int b;
}str;
void fun(str* str1)
{
str1 = (str* )malloc(sizeof(str));
str1->a = 12;
str1->b = 34;
}
int main()
{
/*str* strp;
fun(strp);
printf("%d\n",strp->a);
printf("%d\n",strp->b);*/
str str1;
fun(&str1);
printf("%d\n",str1.a);
printf("%d\n",str1.b);
}

想想,为什么子函数中赋值,在main中打印出来是不一样的!!!
      对于fun(strp)的过程是这样的:在函数传递参数的时候,strp的值 赋值给了子函数的str1,这个过程就是函数参数拷贝的过程,然后str1的值在malloc的时候不幸被malloc改变了,所以在main中打印出来的不一样。

      对于fun(&str1)的过程是这样的:在函数传递参数的时候,&str1的值  赋值给了子函数的str1,后面的过程跟上面一样。所以在main中打印的也是不一样的。

对于这种情况,最好的解决办法就是利用函数返回值,把str1返回 回来就ok了!!!

注意:可能你会问了,那怎样通过参数获得子函数传递的值啊,其实很简单,你在main中开辟好一段内存,然后把这个内存地址传递到子函数中去,然后对这个内存进行赋值,不要去改变这个指针的指向(即指针的值),仅仅改变指针指向的内存(即指针指向的内容),自然就获得了你想要的值!

8.c语言文件操作的一个问题:

   c语言中打开文件有两种方式,一种是二进制方式,另一种是文本方式(ASCII码方式)。这两种方式有什么区别?(对于Linux这种只有一种文件类型的操作系统来说是没有区别的)

   我们就以windows为例说说区别:

   a.以文本方式打开文件,若将数据写入文件,如果遇到换行符'\n'(ASII 值为10,0A),则会转换为回车—换行'\r\n'(ASCII值为13,10,0D0A)存入到文件中,同样读取的时候,若遇到回车—换行,即连续的ASCII值13,10,则自动转换为换行符。

      而以二进制方式打开文件时,不会进行这样的处理。

   b.还有如果以文本方式打开文件时,若读取到ASCII码为26(^Z)的字符即0x1a,则停止对文件的读取,会默认为文件已结束,而以二进制方式读取时不会发生这样的情况。由于正常情况下我们手动编辑完成的文件是不可能出现ASCII码为26的字符,所以可以用feof函数去检测文件是否结束。

   所以,由于存在上面的两个区别,我们在明确文件类型的时候,最好使用相对应的方式对文件进行打开。对于那些不明确文件类型的时候,最好使用二进制方式打开文件。