零散知识

来源:互联网 发布:中国汽车制造业 数据 编辑:程序博客网 时间:2024/05/02 01:17

1.

while(1)其中1代表一个常量表达式,他永远不会等于0。所以,循环会一直执行下去。除非你设置break等类似的跳出循环语句循环才会中止。

2.

scanf一个数组不能for(i=0;str[i]!=’\0’;i++)
因为输入的时候不会检索\0
只有输出时才会检索\0;

3.

要写好C语言,漂亮的宏定义是非常重要的。宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等。
  在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍。
  我们来看一个例子,比较两个数或者表达式大小,首先我们把它写成宏定义:
  #define MAX( a, b) ( (a) > (b) (a) : (b) )
  其次,把它用函数来实现:
  int max( int a, int b)
  {
  return (a > b a : b)
  }
  很显然,我们不会选择用函数来完成这个任务,原因有两个:首先,函数调用会带来额外的开销,它需要开辟一片栈空间,记录返回地址,将形参压栈,从函数返回还要释放堆栈。这种开销不仅会降低代码效率,而且代码量也会大大增加,而使用宏定义则在代码规模和速度方面都比函数更胜一筹;其次,函数的参数必须被声明为一种特定的类型,所以它只能在类型合适的表达式上使用,我们如果要比较两个浮点型的大小,就不得不再写一个专门针对浮点型的比较函数。反之,上面的那个宏定义可以用于整形、长整形、单浮点型、双浮点型以及其他任何可以用“>”操作符比较值大小的类型,也就是说,宏是与类型无关的。
  和使用函数相比,使用宏的不利之处在于每次使用宏时,一份宏定义代码的拷贝都会插入到程序中。除非宏非常短,否则使用宏会大幅度增加程序的长度。
  还有一些任务根本无法用函数实现,但是用宏定义却很好实现。比如参数类型没法作为参数传递给函数,但是可以把参数类型传递给带参的宏。
  看下面的例子:
  #define MALLOC(n, type) \
  ( (type ) malloc((n) sizeof(type)))
  利用这个宏,我们就可以为任何类型分配一段我们指定的空间大小,并返回指向这段空间的指针。我们可以观察一下这个宏确切的工作过程:
  int *ptr;
  ptr = MALLOC ( 5, int );
  将这宏展开以后的结果:
  ptr = (int ) malloc ( (5) sizeof(int) );
  这个例子是宏定义的经典应用之一,完成了函数不能完成的功能,但是宏定义也不能滥用,通常,如果相同的代码需要出现在程序的几个地方,更好的方法是把它实现为一个函数。
  下面总结和宏和函数的不同之处,以供大家写代码时使用,这段总结摘自《C和指针》一书。

4.

(p++)与(++p)区别:
*(p++)是:先取p所指向地址的值,然后让p+1;
*(++p)是:先让p+1,再取(p+1)后指向地址的值。
(4)、++*(p)。表示取出p指向地址的值后,再将此值加一。

5

void*calloc(unsigned int num ,unsigned int size);
它相当于一个声明了一个一维数组。
float *pf=NULL;
pf=(float*)calloc(10,sizeof(float));
等价于
pf=(float*)malloc(10*sizeof(float));

6

在这里要特别强调用内部名称(internal name)和外部名称(external name)。这两者的要求从来都不一样。早期的C要求只有前8个字符是标识符是有效的,也就是说internal name的有效长度为8,而external name有效长度为7。之所以是7是因为当时有操作系统实现上的差异,针对Unix平台来讲external name有效长度是6。语言发展到C89,标准要求internal name的有效长度为31,而external name的有效长度依然为6。直到C99,internal name的有效长变为63,external name才变为31.所有版本的语言规范和标准都明确指出标识符是区分大小写的,但对针external name的处理有特例。由于早期某些系统符号表(符号依赖操作系统的可执行文件的格式限制)不能区别大小所,所以早期C标准特别明确了Unix中external name是区分大小写。C89标准在对编译器的实际要求上也明确说明了编译器实现可以选择忽略alphabetical大小写限制。但从C99开始就不再有这个规定,也就是说C99标准中的name都是区分大小写的。
前6个字符的唯一性” —— 举个例子:字符串ABCDEF与字符串ABCDEFG,被当作是“一致”的,即不能通过两者做指涉上的区别。因为,对于字符串ABCDEFG(看上去有7个字符),只有前6个字符是“有效”的。那么,所有具有相同6个字符打头的字符串,都被当作同一个字符串;只有那些在前6个字符中存在区别的字符串,才是“不同”的字符串 —— 这就是“保证了……之唯一性”的意思。

“并且不区分大小写” —— 这意味着,字符串ABCDEF、字符串ABCDEFG、字符串abcdef、字符串AbCdEfG …… 等等等等,被当作是“一致”的。

7

“#define无类型检查,enum有。是否有效不管。”

“ 比如typedef enum{ ALPHA, GAMMA, BETA } EnType;”

“我声明个EnType eType = 5; 如果ALPHA = 0,那么eType是无效的。但是类型是有效的,所以编译器不会报错。”

8

一元运算符+-表示正负运算

9

  1. 整型升级:所有的char,short int和位段都会首先自动转换成int或者unsigned int。如果int能够表示源类型的所有值,那么就转换为int,否则转换为unsigned int。
  2. 当表达式中存在无符号和有符号类型的操作数时,如果一个操作数是unsigned long int,那么另一个操作数也被转换为 unsigned long int;如果一个操作数是long int,另一个操作数是unsigned int。如果long int能够表达unsigned int的表示范围,则另一个操作数被转换为long int;否则两个操作数都被转换为unsigned long int;如果一个操作数是unsigned int,另一个操作数是int,那么另一个操作数被转换为unsigned int。

下面看一个例子:

假设int是16位,long int是32位。

那么对于-1L < 1U,因为-1L是signed long int型的,而1U是unsigned int型,由于signe long int能够完全表示unsigned int的范围,所以1U被转换为signed long int;

对于-1L>1UL,因为-1L是signed long int型的,而1UL是unsigned long int型,则-1L被转换为unsigned long int。
赋值时也要进行类型转换。赋值运算符右边的值需要转换为左边变量的类型,左边变量的类型即赋值表达式结果的类型。
传参数时在没有函数原型的情况下,char和short类型都将被转换为int型,float类型将被转换为double型。
库函数sqrt的参数为double类型
rand函数:返回取值在0~32767之间的伪随机数

10

链接:https://www.nowcoder.com/questionTerminal/887b711571514376b70fcd495e0746a8
来源:牛客网

a 和 &a 是同一个地址。但是其代表的含义不同,(a+1)代表从a数组首地址跳跃一个int的长度,(&a+1)表示从a数组首地址跳跃一个数组的长度,也就是指向a数组最后一个元素的下一个位置,因此*(ptr - 1)表示a数组的最后一个元素。

11

trcmp(const char s1,const char s2); 你看下你这个函数调用的地方,第一个参数的类型是
char * 吗?你的应该是 char 类型的,所以会提示错误;char 是字符类型, char *是指向字符的指针
比如说
char a = ‘a’;
char b = ‘a’;
strcmp(&a,&b);如果写成 strcmp(a,b)就会提示你所说的那个问题,形参与形参类型不一样

原创粉丝点击