C语言学习问题汇总(2019/2/1更新)

记录学习C语言中自己遇到的问题

1. “~”取反符号具体运算。为什么(~0 = -1 , ~10 = - 11,~77 = -78)

概念相关:1. 正整数,原码补码反码一样。负整数,符号位固定为1,原码取反=〉反码 + 1 =〉补码。

2. 负数是用补码存储。

解释:(~10=-11)

10转换成二进制为0|1010,|前面是符号位。取反为1|0101,存储。因为是负数,所以1|0101是补码,要转换成十进制的话要先转换成原码。1|0101 - 1 = 1|0100(补码转反码),然后取反,符号位固定为1,得原码为1|1011,再转换为十进制,即-11。

同理~0=-1。0转二进制0|0000,取反1|1111(补码) =〉1|1110(反码) =〉 1|0001(原码) =〉-1(十进制)

~77=-78。77转二进制0|01110111,取反1|10001000(补码) =〉1|10000111(反码)=〉1|01111000(原码)=〉-78(十进制)

具体应用:输出int范围

#include 
#include 

int main(void)
{
    //方法一
	printf("int_min = %d.\n", INT_MIN);
	printf("int_max = %d.\n", INT_MAX); 
    //方法二
	printf("min = %d.\n", -(int)((unsigned int) ~0 >> 1)-1);
	printf("max = %d.\n", (int)((unsigned int)~0 >> 1)); 
	return 0;
}

limits.h头文件定义了很多类型的取值范围,这是最简单的。然后则是取反。>>1 是为了去掉符号位。

2. strlen()与sizeof

对于字符串,sizeof会计算空字符,strlen()不会。  

对于数组(a[40]),sizeof会得出其存储单元40, strlen()会得出其具体存储的字符串长度。

转换字符为%zd,代表unsigned int。若不支持C99和C11可用%u,%lu代替。

3. scanf(),getchar()与gets() 

原文:https://blog.csdn.net/sinat_33523805/article/details/79570953 

1. scanf()遇到空格,回车或者tab键时都会自动停止输入,剩下的内容逗留在缓冲区中。(除了正则表达式。)

关于正则表达式: 
[ ]是个集合的标志,%[ ]特指读入此集合所限定的那些字符,比如%[A-Z]是输入大写字母,一旦遇到不在此集合的字符便停止。 
如果集合的第一个字符是“^”,这说明读取不在”^”后面集合的字符,既遇到”^”后面集合的字符便停止(这就是scanf函数里的正则表达式应用)。 
注意:此时读取的字符串是可以含有空格的。 
例如: 
“%[^\n]”则表示当遇到回车时才结束输入。 
“%[A-Z]”则表示输入A到Z的任何字符(包括回车、空格)都会停止。 
“%[0-9a-zA-Z]”则表示只能输入数字加字母。

2. gets()主要用来接收字符串,可以接受空格,遇到‘\n’时结束,但不接收‘\n’,把其留在缓冲区;把接收的一串字符存储在形式参数指针指向的空间,并在最后自动添加一个‘\0’。

3. getchar()主要用来接收单个字符,不管是空格还是回车都可以,可以用作特别字符作为结束的时候进行判断。

(c=getchar())!= ‘\n’ 表示遇到回车的时候结束接收字符。

你可能感兴趣的:(C语言学习问题汇总(2019/2/1更新))