techdoc centre
本站搜索 用户名: 密码:
   HOME  TECHDOC  WEB  SDK  NSDT  TOPIC  BIZDOC   LOGIN
  发布地区 Global 发布类别 TECHDOC Programming
字体:
  C语言中级笔记
于 2017-10-14 编辑: Eric 查看: 433 次   Article Url Print this page

有些是从其他资料里找的。希望对大家有用。

1.表达式的值:表达式有表达式的值,它是无名的,短暂的。
2.case 常量(不可以是运算)
3.数据区(栈,静态区,堆)和代码区
4.sizeof与数组(下边的说明不考虑机器或者平台等因素).
一.
 int i[10];
 int *p
 p=i;
 上边sizeof(i)为40.但是sizeof(p)是4.原因:数组名不是指针.
 
二.
 数组的大小:
 sizeof(i)/sizeof(i[0]);
 前者为40,后者为4,于是就是10个.
三.
 如果把数组名作为参数传给函数,那么函数的形参一定是指针了.于是在函数内就无法算出来数组的大小了.因为sizeof(这个参数)是4.所以我觉得很多函数需要传size进去.而不是函数内计算大小.
5.const

const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前两个的作用是一样:a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针和所指向的整型数都是不可修改的)。

6.typedef的陷阱:

  typedef char * pstr;
  /*若我们这样使用:*/
  int mystrcmp(const pstr, const pstr);
  /*我们希望表达的是:*/
  int mystrcmp( const char*, const char* );
  /*(即 2个指向常量的char指针)*/
  /*可它被解释为:
  int mystrcmp( char* const, char* const ) ;
  /*(2个指向char的常指针)*/

分析:
const修饰的是pstr,而pstr被定义为char *,而不是char。

应修改为:
    typedef const char* cpstr;
    int myctrcmp( cpstr, cpstr);

7.复杂指针解析
 比如int (*(*func)[5][6])[7][8];
 func是指向三维数组的指针,这类数组的大元素是具有5X6个int元素的二维数组,而指向三维数组的指针又是另一个三维指针数组的元素。

8.为什么会有匿名结构体呢?
 为了不想让其他人再声明该类型的变量.
9.struct的大小
 struct{
  char ch;
  int i;
  float f;
  char ch2;
 }a;
 struct{
  char ch;
  char ch2;
  float f;
  int i;
 }b;

  sizeof(a)==16
  sizeof(b)==12
  为什么成员一样,但是顺序不同,占的空间不一样呢?
  a的存储:ch,_,_,_(补了三个字节),i,float f,ch2,_,_,_
  b的存储:ch,ch2,_,_f,i
  得出结论,用成员中占最大字节的类型为单位,然后填充变量.要是填得下就填,填不下就新找个该单位填.如b的存储ch,ch2,放到四字节的内存,还空两个位置.
  再一个结论:声明struct 的时候要注意成员的先后顺序.
10.malloc和calloc
  一.malloc(大小),calloc(个数,每个的大小)用哪个更好?
   用calloc好.
   原因:因为大小虽然可以个数*每个的大小得出来.但是要使这个值很大很大怎么办?所以分开写(calloc)比计算这个大小(malloc)要好.这个原因是个人认为.但是应该用calloc的结论非个人认为.
  二.malloc(0)
   虽然申请0大小的内存,但是结果是malloc返回的结果并不等于NULL,就是说它是有返回内存的.有多大?忘了...

11.FILE指针
一.
  当使用文件指针的时候,指针指的是一个结构体,该结构体除了包含各种各样的和该文件相关的信息,还指着一个buffer,而该buffer和文件又有一个有时读入有时写入的流.
  就是说,fopen,不单单返回了一个文件指针,而是构建了整个读取文件的环境.
二.文件的文本方式与二进制方式.
  假设123,文本方式用每个字的ASCII值表示'49','50','51'
  二进制方式则一个字节就可以表示了1111011.
 
  使用场合:一个是方便人类,一个方便计算机

  另外,附一个ASCII编码表的链接http://www.blabla.cn/ref/ascii.html

12.预处理
一.
不要忽视宏定义中的空格:
#define f (x) (x) +1 //实际上是把f 定义成了(x) (x)+1

对于不带参的宏,若宏值多于一项,一定要使用括号
#define MAX (M+N)
要给每个参数加上括号,否则可能影响计算的优先级
#define abs(x) (x>=0)?x:-x
z =abs(a+b); /*相当于 z= (a+b>=0)?a+b:-a+b
//修改后:
#define abs(x) ((x)>=0?(x): -(x))
尽量用typedef而不是宏定义去定义类型。
 
二.
用typedef和宏都可以定义新类型.那么哪个更好.
答:typedef更好.
原因:int* a,b;  a和b的类型,a是指针,b是整形.同样的,用宏定义出来的新类型,使用的时候也会出现这样不知道是新类型指针还是新类型的情况.

三.
由于头文件包含可以嵌套,那么C文件就有可能多次包含同一个头文件,就可能出现重复定义的问题
通过条件编译开关来避免重复包含
例如
#ifndef __headerfileXXX__
  #define __headerfileXXX__
  …
  文件内容
  …
#endif
四.
#include “xxxx.h”
到本级目录去找和到系统默认目录去找。
#include <xxxx.h>
到系统默认目录。

13.常用库函数(总结略,举assert为例)
诊断函数(assert.h)
测试一个条件test ,当结果为假时使程序终止,为真时没反应 。

不要将assert函数用于程序的执行逻辑中,它仅用于调试。
即:程序的 if( 条件 ) 语句不可用 assert( 条件 ) 来替代。

如果在程序开始加入代码:
#define NDEBUG   
则该程序中的assert函数全部失效,不必逐一删除。(有待验证.因为我试验了怎么不管用)

14.关键字static的作用是什么?
在C语言中,关键字static有三个明显的作用:
 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

15.竟然允许这样使用指针:
#include "stdio.h"
void main()
{
    int a = 1234;
           // 0x0012ff7c是&a的值。
    int *p =( (int*)0x0012ff7c );
    printf("&a = %x\n",&a);
    printf("a = %d\n*p = %d\n",a,*p);
}

http://www.yuanma.org/data/2006/1216/article_1953.htm


相关文章:

o GDB中的“观察点”/watchpoint使用
o 在用户空间编程使用linux内核链表list,hlist宏定义和操作
o C语言家族扩展
o 嵌入式linux调试:用gdbserver调试共享库
o 共享库的初始化和~初始化函数分析
o C语言中const的用法
o 优质代码的十诫
o 如何加密/混乱C源代码
o 语言的歧义
o 谁说C语言很简单?


   Search:

   

   Categories:

 Open All Close


Copyright techdoc.netsoftlab.ca powered by netsoft lab. 2007-2012  
Friend Websites:   netsoftlab.ca   cnstar.ca   CS lessions