1.
|| 条件 或 ,有一个为真 条件为真(此时只计算第1个), 有一个为假,条件便为假
| 按位或
2.
#undef 撤销已定义过的宏名
3.
int *p= (int *)0x12ff7c;
给p 赋初值,而不是 *p
*p=0x123;
4.
int a[5];
a代表 数组 首元素的首地址,而非 数组的首地址 ,&a 才是整个数组的首地址
但仅仅是代表,编译器并没有分配一块内存来存其地址,这一点与指针有很大差别
a 不能作为 左值
数组定义必须指明其类型和个数
int a[5]={1,2,3,4,5};
对指针进行加1操作,得到的是下一个元素的地址,而不是原有地址直接加1
一个类型为T 的指针的移动,以sizeof(T)为移动单元
a是数组首元素的首地址,也就是a[0]的地址,a+1 是数组下一元素的首地址,即a[1]地址
&a是数组的地址,&a+1是下一个数组的首地址。
5.对数组和指针元素的
两种 访问方式
通过 指针的形式和 通过下标的 形式
编译器总是把以下标的形式 的操作解析为 以指针的 形式的 操作
6.
指针在32 位系统下 永远占 4个字节
7.
在C语言中,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素首地址的指针。
所有非数组形式的数据实参均以传值得形式调用。
函数本身并没有类型,只有函数的返回值 才有类型
8.
当一维数组作为函数参数的时候,编译器总是把它 解析成 一个指向其 首元素 首地址的指针
9. 静态区,堆,栈 的概念
静态区:保存自动全局变量和 static 变量(包括static全局和局部变量)。静态区的内容在总个程序的生命周期内部存
在,由总个程序的生命周期内都存在,在编译器 编译的时候分配
栈: 保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁。其特点是效率高
但空间大小有限
堆:由malloc 系列函数或 new 操作符分配的内存。其生命周期由free 或delete 决定。在没有释放之前一直存在,直到
程序结束,其特点是使用灵活,空间比较大,但容易出错
10.
定义指针时一定要同时初始化
int *p=NULL;
当用free 释放掉 ,malloc 分配的内存时,要检查,同时一定要将指针 赋值为NULL, 否则极易出错,出现野指针
char *p =(char *)malloc(100);
if (NULL ==p)
{ //分配内存出错
}
。。。。
free(p);
p=NULL;
11. 易犯的错
正确:
int sum (int a, int b)
{
int c;
c=a+b;
return c;
}
return 语句不能返回指向‘栈内存’的‘指针’,
它 是函数局部变量,在栈内存中,函数退出时 会被释放掉
错误代码:
char *func(void)
{
char str[30];
......
return str;
}
12.if 的判断
对于指针 最好用 if(NULL==p)
对于 浮点型
float fTestVal=0.0;
最好用
if((fTestVal>=-EPSINON)&&(fTestVal<=EPSINON)) // EPSINON 为定义好的精度
对于字符型
char a[5];
if(0 == strcmp("const",a))
13
const 修饰的不是常量 而是 readonly 的变量,const 修饰的只读变量不能用来作定义数组的维数,也不能放在 case 关键字后面。
14 定义指针时一定要同时初始化
int *p=NULL;
指针p在定义的同时要被初始化为NULL
不管什么时候,我们使用指针之前一定要 确保指针是 有效的。
一般在函数入口处使用 assert(NULL!=P) 对参数进行校验。
在非参数 的地方使用 if(NULL!=p)
12
注意getchar() 函数的返回值 是 int 型的
函数原型:int getchar(void)
阅读(1492) | 评论(0) | 转发(0) |