#include<iostream> #include<cstdio> using namespace std; char * str() { char a[6]="12345";//warning: address of local variable ‘a’ returned [-Wreturn-local-addr] return &a[0]; } void arraySize(char *a) { printf("%d %p ",sizeof(a),a);//8 0x7ffda5e6aeb0 // warning: ‘sizeof’ on array function parameter ‘a’ will return size of ‘char*’ [-Wsizeof-array-argument] a = "aaaa"; //warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] } //数组作为参数传过来,无论接收的是 char* ,char[]还是char[x],这些都是char*,并且可修改 void arraySize1(char a[]) {//note: declared here printf("%d %p ",sizeof(a),a);//8 0x7ffda5e6aeb0 a = "bbbb"; // warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] } void arraySize2(char a[10]) {//note: declared here printf("%d %p ",sizeof(a),a);//8 0x7ffda5e6aeb0 a = "bbbb"; //warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=] } void arraySize3(char *&a) { printf("%d %p ",sizeof(a),a); a = "aaaa"; } struct node { char *a; char b; }; struct node1 { char *a; char b; short c; }; struct node2 { char *a; char b; short c; int d; }; struct node3 { char *a;//50 char b;//58 short c;//5a int d;//5c char e;//60 }; struct node4 { int a; int b; }; struct node5 { int a; }; struct node6 { int a; char *b; }; struct node7 { char a; }; struct node8 { short a; }; struct node9 { char *a;//70 char b;//78 char c;//79 int d;//7c char e;//80 }; struct nodea { char *a;//90 char b;//98 char c;//99 int d;//9c char e;//a0 char f;//a1 }; struct nodeb { char *a;//90 char b;//98 char c;//99 char d;//9a char e;//9b int f;//9c }; int main() { cout<<sizeof(node)<<endl;//16 cout<<sizeof(node1)<<endl;//16 cout<<sizeof(node2)<<endl;//16 cout<<sizeof(node3)<<endl;//24 node3 u; printf("%p %p %p %p %p ",&u.a,&u.b,&u.c,&u.d,&u.e); //0x7fffc7584050 0x7fffc7584058 0x7fffc758405a 0x7fffc758405c 0x7fffc7584060 cout<<sizeof(node4)<<endl;//8 cout<<sizeof(node5)<<endl;//4 cout<<sizeof(node6)<<endl;//16 cout<<sizeof(node7)<<endl;//1 cout<<sizeof(node8)<<endl;//2 cout<<sizeof(node9)<<endl;//24 node9 v; printf("%p %p %p %p %p ",&v.a,&v.b,&v.c,&v.d,&v.e); //0x7fffc7584070 0x7fffc7584078 0x7fffc7584079 0x7fffc758407c 0x7fffc7584080 cout<<sizeof(nodea)<<endl;//24 nodea w; printf("%p %p %p %p %p %p ",&w.a,&w.b,&w.c,&w.d,&w.e,&w.f); //0x7fffc7584090 0x7fffc7584098 0x7fffc7584099 0x7fffc758409c 0x7fffc75840a0 0x7fffc75840a1 cout<<sizeof(nodeb)<<endl;//16 nodeb x; printf("%p %p %p %p %p %p ",&x.a,&x.b,&x.c,&x.d,&x.e,&x.f); //0x7ffe4cab4b30 0x7ffe4cab4b38 0x7ffe4cab4b39 0x7ffe4cab4b3a 0x7ffe4cab4b3b 0x7ffe4cab4b3c //struct 元素地址安排:找出成员的最大长度,然后所有成员按顺序和最大成员对齐 //8 //44 //2222 //11111111 //224 //1124 //上面是部分可能的排列,但11411是不会出现的,4要么在最左要么在最右 //所以nodea和nodeb虽然成员元素类型一样,但顺序不一样的话结构体大小也不一样 //nodea //8 char* //11_4 char char int //11_ char char //nodeb //8 char* //11114 char char char char int cout<<"-----------sizeof---------"<<endl; cout<<sizeof(void)<<endl;//1 warning: invalid application of ‘sizeof’ to a void type [-Wpointer-arith] cout<<sizeof(char)<<endl;//1 cout<<sizeof(short)<<endl;//2 cout<<sizeof(int)<<endl;//4 cout<<sizeof(long)<<endl;//8 cout<<sizeof(long int)<<endl;//8 cout<<sizeof(float)<<endl;//4 cout<<sizeof(double)<<endl;//8 cout<<sizeof(long double)<<endl;//16 cout<<sizeof(char*)<<endl;//8 cout<<sizeof(void*)<<endl;//8 char *s1 = "12345";//都指向常量内存区的"12345" //warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] char *s2 = "12345";//都指向常量内存区的"12345" //warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] char a1[] = "12345";//有额外分配内存,可修改 char a2[] = "12345";//有额外分配内存,可修改 char b1[6] = "12345";//有额外分配内存,可修改 char b2[6] = "12345";//有额外分配内存,可修改 const char *c1 = "12345";//都指向常量内存区的"12345" const char *c2 = "12345";//都指向常量内存区的"12345" cout<<(s1==s2)<<" "<<sizeof(s1)<<" "<<sizeof(s2)<<endl;//1 8 8 cout<<(a1==a2)<<" "<<sizeof(a1)<<" "<<sizeof(a2)<<endl;//0 6 6 cout<<(b1==b2)<<" "<<sizeof(b1)<<" "<<sizeof(b2)<<endl;//0 6 6 cout<<(c1==c2)<<" "<<sizeof(c1)<<" "<<sizeof(c2)<<endl;//1 8 8 cout<<(s1==c1)<<endl;//1 cout<<(a1==b1)<<endl;//0 printf("%p ",s1);//0x400e74 printf("%p ",s2);//0x400e74 printf("%p ",a1);//0x7ffe8f1acf40 printf("%p ",a2);//0x7ffe8f1acf50 printf("%p ",b1);//0x7ffe8f1acf60 printf("%p ",b2);//0x7ffe8f1acf70 printf("%p ",c1);//0x400e74 printf("%p ",c2);//0x400e74 printf("%p ",str());//(nil) //p1,p3是const char*类型,p2是char* 类型,p1,p2,*p3可变,*p1,*p2,p3不可变 const char* p1 = "12345"; char const *p2 = "12345";//warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] char* const p3 = "12345"; p1 = NULL; printf("p1:%p ",p1); //*p1 = NULL; //error: assignment of read-only location ‘* p1’ p2 = NULL; printf("p2:%p ",p2); //*p2 = NULL; //error: assignment of read-only location ‘* p2’ //p3 = NULL; //error: assignment of read-only variable ‘p3’ //*p3 = NULL; //warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] //段错误 (核心已转储) 修改了常量指针 //printf("p3:%p ",p3); const char *p4 = "12345"; //*p是const,p可变 p4 = NULL; printf("p4:%p ",p4); //*p4 = NULL; //error: assignment of read-only location ‘* p4’ //const (char *) p5 = "12345";//p是const,*p可变, error: expected primary-expression before ‘const’ char* const p6 = "12345"; //p是const,*p可变 //p6 = NULL; // error: assignment of read-only variable ‘p6’ //*p6 = NULL;//段错误 (核心已转储) 修改了常量指针 //printf("p6:%p ",p6); const char* const p7 = "12345"; //p和*p都是const //p7 = NULL; //error: assignment of read-only variable ‘p7’ //*p7 = NULL; //error: assignment of read-only location ‘*(const char*)p7’ char const * p8 = "12345";// *p是const,p可变 p8 = NULL; printf("p8:%p ",p8); //*p8 = NULL; //error: assignment of read-only location ‘* p8’ //(char*) const p9 = "12345";//p是const,*p可变,error: expected primary-expression before ‘const’ char const* const pa = "12345";// p和*p都是const //pa = NULL; //error: assignment of read-only variable ‘pa’ //*pa = NULL; //error: assignment of read-only location ‘*(const char*)pa’ char a[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; short *b = (short*)a; cout<<hex<<"{"<<b[0]<<","<<b[1]<<","<<b[2]<<","<<b[3]<<"}"<<endl;//{2301,6745,ab89,efcd} //printf("{%x,%x,%x,%x} ",b[0],b[1],b[2],b[3]); int *c = (int*)a; printf("{%x,%x} ",c[0],c[1]);//{67452301,efcdab89} char tmp[10]="12345";//tmp是常量类型,不能修改 char *tmp1; char tmp2[10]="12345"; tmp1 = tmp; printf("%d %p ",sizeof(tmp),tmp);//10 0x7ffe91a345e0 arraySize(tmp);//8 0x7ffe91a345e0 printf("%s %p ",tmp,tmp);//12345 0x7ffe91a345e0 arraySize1(tmp);//8 0x7ffe91a345e0 printf("%s %p ",tmp,tmp);//12345 0x7ffe91a345e0 arraySize2(tmp);//8 0x7ffe91a345e0 printf("%s %p ",tmp,tmp);//12345 0x7ffe91a345e0 //arraySize3(tmp);//error: invalid initialization of non-const reference of type ‘char*&’ from an rvalue of type ‘char*’ char *tmp3[] = {"12345","23456"};//warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] printf("%d %p %p %p %s %s %s ",sizeof(tmp3),tmp3,tmp3[0],tmp3[1],tmp,tmp3[0],tmp3[1]); //16 0x7ffe640d66f0 0x401833 0x40186a 12345 12345 23456 char **tmp4; printf("%p ",tmp4);//(nil) //*tmp4 = "12345";//warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] //段错误 (核心已转储) *tmp4 -> *(nil) tmp4 = tmp3; printf("%p %p %p %c %d ",tmp4,*tmp4,**tmp4,**tmp4,sizeof(tmp4));//0x7fff24f47670 0x4017e3 0x31 1 8 //tmp4是二维指针,值为"一维指针数组"首地址,指向存着一维指针的数组 //*tmp4是一维指针,值为"数组"首地址,指向存着字符串 //**tmp4是字符,值为字符'1' //tmp = tmp1;//error: incompatible types in assignment of ‘char*’ to ‘char [10]’ //tmp2 = tmp;//error: invalid array assignment //tmp4 = tmp1;//error: cannot convert ‘char*’ to ‘char**’ in assignment tmp4 = (char**)tmp1; char tmp5[2][10] = {"12345","23456"}; printf("%d %p %p %p %s %s %s ",sizeof(tmp5),tmp5,tmp5[0],tmp5[1],tmp,tmp5[0],tmp5[1]); //20 0x7ffe72775570 0x7ffe72775570 0x7ffe7277557a 12345 12345 23456 //tmp3 = tmp5;// error: incompatible types in assignment of ‘char [2][10]’ to ‘char* [2]’ char *tmp6[] = {tmp5[1],tmp5[2]};//[]优先级比*高,所以这里相当于(char*)tmp6[],是一个一维数组,元素为char*类型 //tmp3 = {tmp5[1],tmp5[2]};//error: assigning to an array from an initializer list //tmp3 = tmp6;//error: invalid array assignment tmp3不可更改,因为tmp3是数组,元素类型为char* return 0; }
如何理解const char*, char const*, char*const等
上面这些声明意义,及他们的区别你都记住了吗?反正我是记不住,打死也记不住。
听说Bjarne在他的The C++ Programming Language里面给出过一个助记的方法:
把一个声明从右向左读。
char * const cp; ( * 读成 pointer to) cp is a const pointer to char
const char * p; p is a pointer to constchar;
char const * p; 同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。
常见C++面试题及基本知识点总结(一)
对于复杂的定义(函数或数组),通过运算符优先级分析,但运算符优先级不同版本太多,还是自己测一遍自己用的编译器优先级是怎样的比较好