cout与char类型之间的
这个问题源自理解container_of函数原型的时候的困惑。
先看一个简单的例子:
1 char a[] = "hello"; 2 cahr a1[] = {'h' ,'e' , 'l', 'l', 'o',0}; 3 const char *b = "hello";//加上const,否则会发出警告,因为右侧是字符串常量,若不加,则表示在修改const常量
上述例子:第一行和第二行效果相同,第一行右侧的不是字符串常量,只是第二行代码初始化列表的另外一种写法,第三行代码是字符串常量(除了初始化一个字符数组时,其他地方都表示字符常量)

定义了一个结构体及其cout输出例子
1 struct tree{ 2 char a; 3 int b; 4 char c;6 };
这个在内存中的存储方式因4字节对齐,所以占用12个字节(若是换种构成方式:int a;char b;char c;则占用8字节,字符型可以连续存储。)
因为C++中<<重载的缘故,cout打印时:
- 在char *和char[ ] 声明的指针变量 ,可以直接&取地址,但是char 声明的变量取地址得用类型转换 (void*)&a1 ,
- 直接打印char * 和 char[ ] 声明的指针变量,是输出字符串,对于cahr 声明的变量,输出字符,且不能取地址
- char * 只是一个保存字符串首地址的指针变量, char [] 是许多连续的内存单元,单元中的元素为char
- 针对char [ ] ,&a2(理解为地址的地址) 和(void*)a2 (地址) 两者值是相同的
- 针对char * ,&a3(理解为地址的地址) 和 (void*)a3 (地址) 两者值是不同的
代码如下:
1 int main(){ 2 3 struct tree{ 4 char a; 5 int b; 6 char c; 7 }; 8 char a[] = {'a','a','a','a',0}; 9 char a1 = 'a'; 10 char a2[] = "cccccccc"; 11 const char *a3 = "bbbbbbbb"; 12 cout << a1 << "\t" << a2 << "\t" << a << "\t" << a3 << "\t" << *a3 << endl; // *a3 只输出一个元素 13 cout << &a1 << "\t" << endl;//仍然输出字符串,输出不正常 14 cout << (void*) &a1 <<endl; 15 cout << &a2 << "\t"<< "\t"<< (void*)a2 << endl; 16 cout << &a3 << "\t"<< "\t"<< (void*)a3 << endl;//地址存储的字节不理解 17 //结构体 18 struct tree t1; 19 cout <<"&t1 = "<< "\t"<<&t1<<"\t"<<(void*)&t1.a <<"\t" << &t1.b << "\t" << (void*)&t1.c <<endl;//四字节对齐 20 cout <<"&t1.c = " <<"\t" << (void*)&(t1.c)<< endl; 21 cout << "&( (struct tree *) 0 ) ->c"<<"\t"<< ( (void*)&((struct tree *)0)->c) << endl;//offsetof函数原型实现 22 23 system("pause"); 24 return 0; 25 }

浙公网安备 33010602011771号