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 }
 
posted @ 2022-09-21 20:25  QianFa01  阅读(200)  评论(0)    收藏  举报