Chinaunix首页 | 论坛 | 博客
  • 博客访问: 336729
  • 博文数量: 79
  • 博客积分: 2466
  • 博客等级: 大尉
  • 技术积分: 880
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-07 16:47
文章分类

全部博文(79)

文章存档

2014年(3)

2012年(7)

2011年(14)

2010年(2)

2009年(2)

2008年(2)

2007年(18)

2006年(31)

分类: C/C++

2006-03-13 17:52:45

54- 如果要把一个二维数组传递给一个函数,第一维的长度可以省略。例如下面的三个函数声明是等效的:

f(int a[2][13])

f(int a[][13])

f(int (*a)[13])

 

 

55- 比较下面两个声明:

int a[10][10]

int *b[10]

a[3][4]或者b[3][4]都可以引用到一个整数。a是一个真正的二维数组,系统会为它分配200个整数大小的内存。b不是一个二维数组,系统只为它分配10个指针大小的存储空间。使用b这样的声明,虽然需要单独为它指向的那些整数另外分配空间,但是b相比a的好处在于b的每一个元素指向的一维数组长度可以各不相同。

 

 

56- C标准规定argv[argc]必须是一个空指针。

 

 

57- printf函数的第一个参数可以是表达式:

$ cat main.c

#include

 

int

main(int argc, char **argv) {

  printf((argc > 1) ? "Has arguments.\n" : "No argument.\n");

  return 0;

}

$ ./a.exe

No argument.

$ ./a.exe arg1 arg2

Has arguments.

$

 

 

58- 任何指针都可以被强制转换为void*类型再转换回来而不丢失任何信息。

 

 

59- 注意下面的用法:在printfformat string中可以用下面的语法指定输出字符串时的最大长度,以及输出整数时的最小宽度:

$ cat main.c

#include

 

int

main(int argc, char **argv) {

  char a[] = "Which season do you like best?";

  printf("%.9s\n", a);

  int i = 100;

  printf("%.5d\n", i);

  return 0;

}

 

$ make run

Which sea

00100

 

$

小数点’.’之后的数字一般情况下是用来指定浮点数的输出精度,上面的用法不太常见。

 

 

60- printf输出的时候可以动态指定输出的最大长度,这是通过用”*”这种特殊的格式符指定输出长度来实现的。这种格式符中的*需要一个对应的整型实际参数,来确定最大长度。仔细观察这个例子:

#include

 

int

main(int argc, char **argv) {

  char a[] = "otorhinolaryngology";

  int i;

  for (i = 0; i < 9; ++i) {

    printf("#%.*s#\n", i, a);

  }

  return 0;

}

 

$ make run

##

#o#

#ot#

#oto#

#otor#

#otorh#

#otorhi#

#otorhin#

#otorhino#

 

 

61- scanf/sscanf函数的格式化字符串中,可以用*符号指定跳过某个输入数据,还可以用一个整数来指定读取数据时的最大宽度。看下面的例子:

$ cat main.c

#include

 

int

main(int argc, char **argv) {

  char a[] = "12345 12345 12345";

  int i, j, k = 0;

 

  // assignment supression

  sscanf(a, "%d %*d %d", &i, &j);

  printf("%d, %d, %d\n", i, j, k);

 

  // width specification

  sscanf(a, "%3d %3d %3d", &i, &j, &k);

  printf("%d, %d, %d\n", i, j, k);

 

  // to skip a partial number

  sscanf(a, "%3d %*d %d", &i, &j);

  printf("%d, %d\n", i, j, k);

 

  return 0;

}

$ make run

12345, 12345, 0

123, 45, 123

123, 12345

 

$

在第一个sscanf中,第二个输入数据被跳过了,所以实际只读入了两个数据;

第二个sscanf中,第一个12345被分成了两部分分别赋给ij,因为指定i读取的最大宽度为3

第三个sscanf中,把第一个12345的前三个数字读入i,然后用*跳过剩下的’45’,再读j的时候没有指定宽度,于是读到的第二个输入数据12345

 

 

62- ANSI C标准对C语言的一个主要修改就是定义了结构体赋值。同一个程序中,某一个成员名称可以同时出现在不同的结构体中而不会发生冲突。

 

 

63- 一个结构体可以在定义的同时被初始化,这是通过对其中每一个成员提供一个初始值来实现的,这些初始值必须都是常量表达式:

struct point pt = {320, 320};

 

 

64- 一个自动结构体变量可以用函数返回值来初始化:

void fun(void) {

  struct point pt = topleftcorner();

}

 

 

65- 结构体成员访问运算符’.’’->’,以及函数调用运算符(),数组下标运算符[],这四个运算符在C语言的运算符优先级体系中处于最高的一级。

 

 

66- 结构体数组的初始化中,如果(1)结构体的成员都是简单类型或者字符指针类型,(2)对数组所有元素的全部成员都给出了初始值,那么可以只要一层花括号,如下所示:

struct point {

  int x, y;

  char *pos;

} points[] = {

  0, 0, “topleft”,

  9, 9, “bottomright”

};

也可以用下面这种,但内层花括号不是必需的:

...

} points[] = {

  {0, 0, “topleft”},

  {9, 9, “bottomright”}

};

 

 

67- sizeof运算的结果类型是一个无符号整数,具体的类型是size_t,定义在stddef.h中。Sizeof不能用于预处理语句#if,因为预处理器不分析类型名但必须求出表达式的值是否非零,但是预处理语句#define可以使用sizeof,因为它只做字符串替换,不求值。

 

 

68- C标准规定,指针运算中引用到数组末尾之后的第一个元素是合法的,这个运算应该能得到正确结果。即如果定义了a[n],虽然a+n已经超出了数组的范围,但是引用了a+n的指针运算应能得到正确结果。

 

 

69- 不要认为一个结构体占用的空间等于其各个成员占用的空间的总和。因为内存对齐的需要,结构体储存的时候经常会出现一些空洞,只有sizeof返回的结果才是可靠的。

阅读(1200) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~