C陷阱于缺陷这本书到图书馆借了很久,一直都没有细细的看,现完整的看了之后把认为重要的,一般人可能忽视的问题给做了笔记,希望有所帮助
2010.02.25
二维数组:
int calendar[12][31];
int * p;
int i;
calendar[4]的含义:
calendar[4]是calendar数组的第5个元素,是calendar数组中12个有着31个整型元素的数组之一。
szieof(calendar[4])的结果是31与sizeof(int)的乘积。
p=calendar[4];表示指针p指向calendar[4]中下标为0的元素。
i=calendar[4][7];i=*(calendar[4]+7);i=*(*(calendar+4)+7);为同样的功能。
p=calendar;非法,calendar是一个二维数组,即"数组的数组",被转换为一个指向数组的指针;p为指向整型变量的指针。
int (*monthp)[31];monthp=calendar:为合法的。monthp指向calendar的第一个元素
calendar[i][j]=0;与*(*(calendar+i)+j)=0;等价。
for(monthp=calendar;monthp< &calendar[12];monthp++)//可以用monthp步进的方式便利数组calendar;
for(monthp=calendar;monthp< &calendar[12];monthp++)
int * dayp;
for(dayp=* monthp;dayp<&(*monthp)[31];dayp++)
  ......
第一个问题,百钱百鸡,囧到了
#include<stdio.h>
void main()
{
int cocks=0,hens=0,chicks=0;
while(cocks<=19)
{
while(hens<=33)
{
chicks=100-cocks-hens;
if((cocks+hens+chicks==100)&&(cocks*5+hens*3+chicks/3==100))
printf("cocks=%d,hens=%d,chicks=%d\n",cocks,hens,chicks);
hens++;
}
cocks++;
};
}
如果照以上编译,将只有一组数据,在第一个while循环中未初始化hens,造成cocks》=1时,hens始终为34.。。。。
以下为正确代码
#include<stdio.h>
void main()
{
int cocks=0,hens,chicks;
while(cocks<=19)
{ hens=0;
while(hens<=33)
{ chicks=100-cocks-hens;
if((cocks+hens+chicks==100)&&(cocks*5+hens*3+chicks/3==100))
printf("cocks=%d,hens=%d,chicks=%d\n",cocks,hens,chicks);
hens++;
}
cocks++;
};
} ......
对野指针的一些认识:
我对野指针的认识,我觉得野指针就是一个指针变量它里面的值是不确定的,这样当你操作这个变量所指定的内存地址的时候,就会带来一些不确定的因素,拿一个比较常见的问题来举个例子来说明一下:
看下面代码:
int a = 10;
int *p;
*p = a;
1. 当执行完第一句话的时候,内存映像示意图如下(方框表示内存块,方框内容表示对应的内存块的值)
a [10]
2. 当执行完第二句话的时候,假设内存映像如下
p [1000]
3. 因为还没有给p指定值,而可能给p划分的内存处,里面的值为1000。
当执行第三句话的时候,通过*p=a来赋值,其实也就是给p所指定的内存处,即单元为1000的内存处,赋值为10。这个时候,如果内存单元为1000的地方是系统的某个重要的数据区,那么接下来的问题。。?不用多说了吧。
举这个例子是为了比较很容易的理解,当指针为野指针的时候会带来的坏处。
还有一个值得注意的地方是当p被free ......
1. 首先要理解几个概念:
文件: 按一定规则存储在磁盘上的数据集合。
文件名: 能唯一标识某个磁盘文件的字符串。形式: 盘符:\ 路径 \ 文件名.扩展名
文本文件:: 数据以其数字字符的ASCII码形式、一个字节一个字节地存储在磁盘上。
二进制文件:数据以二进制形式在存储在磁盘上。
(文本文件和二进制文件具体区别见前一篇文章,概括为就是编码方式的区别,前者是固定长度编码、后者是变长编码)
设备文件:输入/输出设备
标准输入文件:键盘
标准输出文件/标准错误输出文件:显示器
文件型指针:C语言是通过名为FILE的结构型指针来管理文件读写的。FILE *<变量名>
文件的打开和关闭 :文件操作先建立文件与文件指针之间的关系,接着进行文件的读与写。建立文件与文件指针之间的联系的过程是文件的打开。终止这种联系就是文件的关闭。
FILE结构:定义在〈stdio.h〉中。形式如下:
typedef struct
{
int _fd; /*文件代号*/
int _cleft; /* 文件缓冲区所剩字节数*/
int _mode; /* 文件使用模式*/
char *nextc;   ......
#include <stdio.h>
#define SIZE 50
int main()
{
FILE *fps=NULL;
fps=fopen("tests.txt","r");
FILE *fpd=NULL;
fpd=fopen("testd.txt","wt+");
fseek(fpd,0,SEEK_END);
char buffer[SIZE];
while (fps || fpd)
{
int t=fread(buffer,sizeof(char),SIZE,fps);
if (t==0)
{
break;
}
for (int i=0;i<t;++i)
{
printf("%s",buffer);
}
fwrite(buffer,sizeof(char),t,fpd);
}
printf("File operater end!\n");
} ......
char * c = "hello"; c是个分配在堆栈中的一个变量。里面装的是字符串hello的首地址,而hello是常量区。PE文件在编译的时候就确定了的。
char []c = "hello";
"hello"是放在堆栈中保存的,跟上面的那个例子不同,由于hello是堆栈中的所以是可以修改的。而常量区里的是不可以修改的。因为PE的内存页属性是只读的。当然可以有办法强行修改它。那属于HACK技术了。
那c保存在哪里呢?c根本在内存中不存在,只是编译器的一个标记,用于编译期来计算地址用的。用完就不要了。 ......