1、 当非const的char*作为函数形参时:例:void func(char *p);可以改变*p的值但是不能改变p的值。当在函数中new一个新空间时,改变了p的值,此时只是改变了p在函数中的副本,它是局部的,所以当函数执行完,不会改变实参的值。
2、 Char*p = “abf”和char p[] = “abf” 的区别:*p指向的是一块只读的内存区域,当*p的p作为实参传入函数中时,函数不能修改*p的p指向的字符串,如果做参数传入函数,程序编译和链接都不会报错,在执行的时候会使程序垮;p[]的p指向的是一块读写的内存区域,当p[]作为实参传入函数中时,函数可以修改p[]的p指向的字符串。
*p在堆中 p[]在栈中
3、 fgets(char *p, size_p,fp)从fp中读入长度为size_p的字符串到p中,
FILE *fp = fopen("Setup.log","r+"), fwrite(buff, sizeof(char), strlen(buff), fp);1表示一个字符,当用fwrite写文件时,从fp指针指的文件位置开始写如文件中,只是修改或覆盖从该位置开始到strlen(buff)长度的文件的内容。fseek(fp, offset, SEEK_SET)表示fp指到文件开始位置之后offset长度的位置,也就是从该位置读写文件;fseek(fp, offset, SEEK_CUR)表是fp指到文件当前fp的位置,fseek(fp, offset, SEEK_END)文件末尾。Int ftell(FILE *fp) 获得文件指针的当前位置。
4、 typedef struct{enum{a, b, c}}item; sizeof(item) = 1; 与空结构体的长度是一样的都是1;
typedef struct{enum{a, b, c}b}item; sizeof(item) = 4; 还不知道为什么是这样的结果。
5、 sizeof是个操作符不是个函数。当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺寸。sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸。
例子:char* ss = "0123456789";sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针sizeof(*ss) 结果 1 ===》*ss是第一个字符
char ss[] = "0123456789";sizeof(ss) 结果 11 ===》ss是数组,计算到\0位置,因此是10+1sizeof(*ss) 结果 1 ===》*ss是第一个字符
char ss[100] = "0123456789";sizeof(ss) 结果是100 ===》ss表示在内存中的大小 100×1strlen(ss) 结果是10 ===》strlen是个函数内部实现是用一个循环计算到\0为止之前
int ss[100] = "0123456789";sizeof(ss) 结果 400 ===》ss表示再内存中的大小 100×4strlen(ss) 错误 ===》strlen的参数只能是char* 且必须是以''\0''结尾的
char q[]="abc";char p[]="a\n";sizeof(q),sizeof(p),strlen(q),strlen(p);结果是 4 3 3 2
7、典型例子:struct
{
int i;
long j;
char c;
}* st , s[3];
int main(int argc, char* argv[])
{
st = s;
st->c = 'c';
st->i = 10;
st->j = 100;
printf("%d %d %d", s[0], s[1], s[2]);
return 0;
}
输出结果为:10 100 99(c的asii)
分析:输出结果按照结构体定义的顺序对应数组的相应元素。
8、典型2
union
{
int i;
char c[3];
}a;
int main(int argc, char* argv[])
{
a.c[0] = 'a';
a.c[1] = 'b';
a.c[2] = 'c';
printf("%d\n", a.i); //i不可预知的结果
return 0;
}
9、关于类的sizeof()问题
例:类的sizeof值等于类中成员变量所占用的内存字节数。如:
****************************************************************
class A
{
public:
int b;
float c;
char d;
};
int main(void)
{
A object;
cout < < "sizeof(object) is " < < sizeof(object) < < endl;
return 0 ;
}
************************************************************
输出结果为12(我的机器上sizeof(float)值为4,字节对其前面已经讲过)。
不过需要注意的是,如果类中存在静态成员变量,结果又会是什么样子呢?
************************************************************
class A
{
public:
static int a;
int b;
float c;
char d;
};
int main()
{
A object;
cout < < "sizeof(object) is " < < sizeof(object) < < endl;
return 0 ;
}
************************************************************
16?不对。结果仍然是12.
因为在程序编译期间,就已经为static变量在静态存储区域分配了内存空间,并且这块内存在程序的整个运行期间都存在。
而每次声明了类A的一个对象的时候,为该对象在堆上,根据对象的大小分配内存。
如果类A中包含成员函数,那么又会是怎样的情况呢?看下面的例子
************************************************************
class A
{
public:
static int a;
int b;
float c;
char d;
int add(int x,int y)
{
return x+y;
}
};
int main()
{
A object;
cout < < "sizeof(object) is " < < sizeof(object) < < endl;
b = object.add(3,4);
cout < < "sizeof(object) is " < < sizeof(object) < < endl;
return 0 ;
}
************************************************************
结果仍为12。
因为只有非静态类成员变量在新生成一个object的时候才需要自己的副本。
所以每个非静态成员变量在生成新object需要内存,而function是不需要的。
10、使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字
段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字
段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方
式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
还是让我们来看看例子。
示例1:
struct BF1
{
char f1 : 3;
char f2 : 4;
char f3 : 5;
};
其内存布局为:
|_f1__|__f2__|_|____f3___|____|
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
0 3 7 8 1316
位域类型为char,第1个字节仅能容纳下f1和f2,所以f2被压缩到第1个字节中,而f3只
能从下一个字节开始。因此sizeof(BF1)的结果为2。
示例2:
struct BF2
{
char f1 : 3;
short f2 : 4;
char f3 : 5;
};
由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C++中为2。
示例3:
struct BF3
{
char f1 : 3;
char f2;
char f3 : 5;
};
由于有非位域字段,不采用压缩,sizeof(BF3)为3