①--C语言学习中容易疏漏的地方总结(上)

来源:互联网 发布:串行控制端口 编辑:程序博客网 时间:2024/05/22 13:46

C语言学习中容易疏漏的地方总结

知识点①输出、输入函数格式化占位符和格式修饰符的使用  

%c 一个字符  

%d 十进制整数 %ld:长整型 %lldlonglongint %hdshortint

%i十进制整数  

%o 八进制整数  

%x,%X十六进制整数  

%s 一个字符串,遇空格、制表符或换行符结束。  

%f,%F,%e,%E,%g,%G用来输入实数,可以用小数形式或指数形式输入。  

%p 一个指针   

%u 读入一个无符号十进制整数%zd:无符号长整型unsignedlong  

%n 至此已读入值的等价字符数   

%% %符号

printf()函数格式修饰符说明:

   最小宽域m(整数)

指定输出是所占的列数;若m是正整数,当输出数据宽域小于m时,在域内向右靠齐,左边多余位补空格;当输出数据宽域大于m时,按实际宽度全部输出;若m有前导符0,则左边多余位补0;若m为负整数时,则输出数据在域内向左靠齐。

   显示精度.n(大于等于0的整数):

精度修饰符位于最小宽域之后,由一个圆点及其后的整数构成,对于浮点数,用于指定输出的浮点小数位数;对于字符串,用于指定从字符串左侧开始截取的子串字符个数。

   *

最小宽域m和精度.n代替时,表示他们的值不是常数,而由printf()函数的输出项按顺序依次指定

      #:修饰格式符feg时,用于确保输出的数据有小数点,即使无小数位时,也是如此修饰格式符x时,用于确保输出的十六进制数前带有前导符0x.

scanf()函数格式修饰符:

忽略输入修饰符*:表示对应的输入项在读入后不赋值给相应的变量。

知识点②经常使用代码块{}及时释放不需要的变量占用的内存。

知识点③(面试用)奇葩的交换两个整数的方法。

奇葩一:

a = b - a;b = b - a;a = b + a;
奇葩二:

a = a^b;b = a^b;a = a^b;
知识点④scanf("%d%d");如果格式串中有空格可以用空格、tab、回车

知识点⑤取余运算%的结果与被除的符号相同结果为两个正数取余后前面加符号

知识点⑥sizeof运算符

sizeof是一种运算符不要想当然理解为函数

sizeof使用时可以不加()

sizeof可以加变量、常量、数据类型

跟数据类型是必须加()

知识点⑦if后面直接定义变量引起的问题 

if (10 > 6)       int a = 5;//错误*****作用域       //如果在if后面定义新的变量必须用大括号

下面的也是同样的错误

char c ='+';int a = 10;int b = 20;switch(c){       case '+':              int sum= a + b;//错误******作用域              printf("和是%d\n",sum);              break;       case '-':              intminus = a - b;//错误              printf("差是%d\n",minus);//错误              break;}

 

//修改 如果要在case后面定义新的变量必须用{}包住

switch(c){       case '+':       {              int sum = a + b;              printf("和是%d\n",sum);              break;       }       case '-':       {              int minus = a - b;              printf("差是%d\n",minus);              break;       }}

同样的,for循环后面没有{}也不能定义变量

for(int i = 0; i< 10; i++, a++)//这样有错误 作用域{       inta = 10;}

知识点⑧C语言可以在for中初始化计数变量//性能好,怎么我记得当时学得不可以 C++可以

for(int i=0;...;...)
//对比

int i = 0;//这种情况下使i在内存停留的时间太长while(i...)
知识点⑨for初始参数作用域问题

for(int i = 0; i< 10; i++)//作用域 这样是对的 循环体执行10次{       inti = 10;}
//相当于

for(int i = 0; i < 10; i++){       inta = 10;}
for(int i = 0; i< 10; i++, a++)//这样有错误 作用域{       inta = 10;}

//下面有错误 作用域

for(int i = 0; i< 10; i++, a++)//这样有错误 作用域{       int a = 10;}

知识点⑩逗号表达式的陷阱

例如:

for (int i=0,j=0;...;...)不能写成for (int i=0,int j=0;...;...)//逗号表达式的使用
知识点C语言不允许两个函数名字一样 不存在重载的概念

 函数不可以重复定义 但是可以重复声明

知识点#include编译预处理命令与多文件团队开发

#include编译预处理命令可以认为是:将后面的文件内容拷贝到当前的文件中

多文件团队开发:模块分别编译成.o都不能链接成功,合起来链接生成最终程序。

链接:把项目中所有相关联的.o目标文件、C语言函数库合并在一起,生成可执行文件

1.函数的定义放.c文件,函数的声明放.h文件

2.如果要使用某个.c文件中定义的函数,只需要#include这个.c文件对应的.h文件

3..h文件的作用:被别人拷贝。编译链接的时候不需要管.h文件

知识点数组初始化:这个我真没见过

int ages[5] = {[3] = 19, [4] = 20};

这个是可以的

int ages[] = {19,20};
下面这样是不对的:

intages[5];ages = {19, 20, 21, 22, 23};//数组名 是地址
//下面这样是可以的

int count = 5;int ages[count];// ages[0] = 10;ages[1] = 11;ages[2] = 12;//但是ages[3]ages[4]的值是随机的
//下面这样是不对的:

int count = 5;int ages[count]= {10,11,12};//error
结论:如果在定义数组的时候进行初始化,数组元素必须是常量,或者不写

知识点计算数组长度

sizeof(数组名)/sizeof(数组名[0])sizeof(数组名)/sizeof(数组类型)
知识点数组作为函数参数时 在函数内部无法计算数组的长度

因为传递参数时

数组被当做指针,在C语言中64位的编译器环境下指针变量的长度始终是8字节

因此在传递参数要传递数组长度

知识点16字符串初始化

//以下前四种都是字符串

char name[8] ="it";char name2[8] ={'i', 't', '\0'};char name3[8] ={'i', 't', 0};char name4[8] ={'i', 't'};
//这样不可以

char name4[] = {'i','t'};//不是字符串

//理解字符串在内存中的存储

char name[] ="it";char name2[] ={'o', 'k'};printf("%s\n",&name2.[1]);//kit
知识点17strlen函数

1.计算的字符数:"haha"长度是7

2.计算的字符不包括'\0'

3.从传入值的地址开始直到第一个'\0'

知识点18定义指针变量的时候应该同时初始化


int*p = &a;

或者

int*p;p = &a;

int*p; p = &a;

尽量不要定义后放空如:int *p;

知识点19指针常用于函数的多值返回 在C++中使用多的是引用

知识点20数组和字符指针定义字符串的区别

//利用两种方式定义字符串

//1利用数组

char name[] ="it";

name[0] = 'T';//这是可以的,字符串变量

//特点:字符串的字符是可以修改的

//使用场景:字符串的内容要经常发生变化

 

//2.利用指针

char *name2 ="it";

name[0] = 'T';//这是不可以的,字符串常量

//特点:字符串的内容不可以修改

//使用场景:字符串的内容不需要修改,而且这个字符串经常用到

知识点21保存在常量区的相同值 占用的时同一块内存

#include <stdio.h> intmain(){    char *str1 = "abcd";    char *str2 = "abcd";    printf("str1的地址是%p\n",str1);    printf("str2的地址是%p\n",str2);    return 0;}

执行的结果是:

str1的地址是0x10373bf66str2的地址是0x10373bf66
知识点22常量区、堆、栈

可编程内存在基本上分为这样的几大部分:静态存储区、堆区和栈区。他们的功能不同,对他们使用方式也就不同。

静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。

栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

堆区:亦称动态内存分配。程序在运行的时候用mallocnew申请任意大小的内存,程序员自己负责在适当的时候用freedelete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。

 

知识点23指向函数的指针

void test(int a){   printf("%d\n", a);}void (*p)(int) = test;//固定写法//void (*p)();p = test;同上(*p)(3);//函数调用,也可以直接p()


0 0
原创粉丝点击