strlen sizeof详尽分析
来源:互联网 发布:flyme 彻底清除数据 编辑:程序博客网 时间:2024/05/06 11:22
1 char *a="qwert";
cout<<a+2<<endl;
输出 ert 如果cout后面带的是地址,那么输出从这个地址开始的字符串!
实战例子)
1)
char *aa = new char[22];
cout << sizeof(aa) << endl;//结果 4 ===》aa是指针
char a1[6] = { '1', '2', '3', '4', '5', '6' };
char a2[] = { '1', '2', '3', '4', '5', '6' };
cout << sizeof(a1) << endl;//结果 6 ===》非常量字符串,只有6,不是7,不包含\0
cout << sizeof(a2) << endl;//结果 6 ===》非常量字符串,只有6,不是7,不包含\0
cout << strlen(a1) << endl;//结果 19 ===》函数strlen读到\0才会结束,a1字符串没有\0,所以结果无法预计
cout << strlen(a2) << endl;//结果 35 ===》函数strlen读到\0才会结束,a2字符串没有\0,所以结果无法预计
char str3[] = "abcse\0fgkij";
cout << "strlen(str3)=" << strlen(str3) << endl; //结果 5 ===》 str3的'\0'会被解释为结束符
char *s1 = "zclzcl";
char s2[] = "cxlcxl";
cout << strlen(&s1[4]) << endl;//结果 2 ===》从字符串倒数开始计时读整个字符串,直到遇到\0常量字符串的标示符停止
cout << sizeof(s1) << endl;//结果 4 ===》s1是指向字符串常量的字符指针
cout << sizeof(s2) << endl;//结果 7 ===》常量字符串包含最后的\0标示符
cout << strlen(s1) << endl;//结果 6 ===》函数strlen读到\0才会结束
cout << strlen(s2) << endl;//结果 6 ===》函数strlen读到\0才会结束
//sizeof只有在输入为char *s="zcl"或者char *s=new char时,s为sizeof参数就会作为指针,32位系统就是4个字节。
1) 看运算符的优先级
int *p[5]; []优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。 是指针数组, 有 5 个成员,每个成员都是一个指针,共有5 个指针
int (*p)[5]; 小括号优先,所以 是 1个指针,用来指向 有5个元素的数组。
--------
一般来说
int (*p)[n]; 是数组指针(也称行指针)
()优先级高,说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
----
int *p[n]; 指针数组
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1是错误的,这样赋值也是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。。
2)
void f(char*x){
x++;
*x = 'a';
}
int main(int argc, char**argv){
char str[sizeof("hello")];
strcpy(str, "hello");
f(str);
std::cout << str;//hallo
system("pause");
return EXIT_SUCCESS;
}
void f() 函数输入的str 数组作为函数的输入变为指针,指向“hello”的第一个字符h, 因为f函数输入的是指针,那么x++,也就是str++之后,修改了“hello”第二个数组地址的字符为a,所以将cout<<str输出时输出整个修改后的字符串为hallo。
3)
char arr[10]="hello";
cout<<strlen(arr)<<endl;//5 只关心实际存储内容,到\0停止
cout<<sizeof(arr)<<endl;//10 关心数组的分配的空间大小和类型
char *parr=new char[10];
cout<<strlen(parr)<<endl;//14
cout<<sizeof(parr)<<endl;//4 parr是一个指针
cout<<sizeof(*parr)<<endl;//1
程序定义了一个字符指针parr ,它指向一个分配了10个字节的空间的字符数组,由于没有进行初始化,根据strlen原理,它无法确定字符串的终止位置,所以该值为一个随机值,本例中输出14,;parr为一个指针,sizeof自然输出4个字节。*parr为指向字符串第一个字符的空间大小,sizeof在编译时既可确定为1,即char型所占空间大小。
char cvar[20]="enock";
int ivar[20]={1,2,3};
char *cp=new char[5];
printf("%d\n",sizeof(cvar));//20
printf("%d\n",sizeof(ivar));//80
printf("%d\n",sizeof(cp));//4 ,cp是指针变量
(1)需要注意的是参数传递时,静态数组参数会弱化为指针,因为不可能在调用栈上去分配一个数组。所以
void fun(char cvar[]){
printf("%d\n",sizeof(cvar));
}
fun(cvar);//4 32位机指针变量占4个字节
(2)字面值字符串是const char[]类型,即静态数组类型
printf("%d\n",sizeof("enock"));//6,注意结尾'\0'
(3)sizeof(结构体对象),需要注意字节对齐,这跟编译器相关。
(4)在使用数组时,大多数情况下数组会自动转换为指向第一个元素的指针,不将数组转换为指针的情况有:数组用作取地址(&)操作符的操作数或sizeof的操作数,或用数组对数组的引用进行初始化时,不会将数组转换为指针,如下:(注意 1、这里是sizeof,不是strlen; 2、这里输入函数的数组用*a和a[]都是可以的!!!)
void fun1(int a[]){
std::cout << sizeof(a) << std::endl;
}
void fun2(int(&a)[5]){//数组的引用
std::cout << sizeof(a) << std::endl;
}
int main(int argc, char** argv){
std::cout << "sizeof int=" << sizeof(int) << std::endl; //4
int a[5];
std::cout << sizeof(a) << std::endl;//20
fun1(a);//4
fun2(a);//20
int(*p)[5] = &a;//p是5维数组的指针 p是指针,*p自然就是数组啦
std::cout << sizeof(p) << std::endl;//4
std::cout << sizeof(*p) << std::endl;//20
system("pause");
return 0;
}
2) int *a[2][3] 共占用48个字节
第二题选D,不解释,2*3*sizeof(int*)=48(64位机器上是8字节一个指针)
经验)
1 strlen只能用char*作为参数,而且必须是以“\0”结尾的,例如char a[5]="hello"就会出错,没有空间存放'\0'。
2 http://blog.csdn.net/xhu_eternalcc/article/details/22588133
3 char a[6] = "123456";//error "123456" char型实际上有7个字节,包括最后的'\0'
char a1[6] = {'1','2','3','4','5','6'}; //正确 不包含结束符
4 sizeof只有在输入为char *s="zcl"或者char *s=new char时,s为sizeof参数就会作为指针,32位系统就是4个字节。
5 剑指offer T48
void swap(char *a, char *b)
{
char tmp = *a;
*a = *b;
*b = tmp;
}
void main()
{
char *p = "hello";
swap(p, p + 2);//因为传入swap函数的p是一个存于常量区的字符串的指针copy,在swap函数内部,通过这个指针copy来解引用修改在常量区字符串“hello”的值当然是不可能的,自然会报错!!可以将p写成数组形式就可以,比如char p[]="hello", 因为此时字符串存在栈区,通过指针p就可以修改了!!这也是字符串指针和字符串本质区别char *p和char p[]!!
1 char pData[] = "i am a student."; char *pData = "i am a student.";
后者字符串如果为指针型表示,则此字符串为const类型,不可以更改此字符串内容,但是前者数组的形式可以。
比如char *func(char *pData) 此函数的指针输入参数只能选择前者char pData[] = "i am a student."; 选择后者作为参数会出错!!
所以可以有char str[]={'a','b','c'}; 但不可以有 char *str={'a','b','c'}//没有这种写法,不符合语法形式。{}代表数组,但是char *str只能代表常量字符串!!
但是这样是可以的char *a2[] = { "abc","cde" } 代表a2是一个数组,里面每一项是一个常量字符串!!!
- strlen sizeof详尽分析
- sizeof分析(与strlen的区别)
- strlen和sizeof的实现原理分析
- 实例分析sizeof与strlen的用法
- 1.11sizeof和strlen简要分析
- strlen, sizeof
- sizeof strlen
- sizeof && strlen
- sizeof strlen
- sizeof && strlen
- strlen sizeof
- sizeof strlen
- sizeof strlen
- sizeof strlen
- sizeof & strlen
- sizeof、strlen
- strlen sizeof
- sizeof strlen
- 笔记(機器學習技法):Random Forest
- servlet 读取resource的文件
- 设计模式课堂小笔记
- Unity3D之Input输入事件总结
- mysql-mha
- strlen sizeof详尽分析
- 经典DP——数字三角形
- 析构函数
- AlertDialog学习篇
- 二叉树前序、中序、后序遍历非递归写法的透彻解析
- Csting Left Mid Right
- Ajax获取图片的两种方式
- <job_demo><Qt>自绘仪表类控件
- POJ