之前一直对数组指针不是很清楚,这次在《C++Primer》中看到了容器用字符串数组做例子,对其中的sizeof计算不太了解,正好写段代码来测试下,看看结果加深自己的印象..
代码如下
#include
#include
#include
#include
using namespace std;
void main()
{
char *words[] = {"stately","plump","buck","mulligan"};
size_t words_size = sizeof(words)/sizeof(char *);
int b = sizeof(words);
int c = sizeof(char *);
list words2(words,words + words_size);
vector a(10,2);
std::cout< getchar();
string sarray[4] = {"quasi","simba","frollo","scar"};
list slist;
slist.insert(slist.end(),sarray,sarray+4);
//string temp = slist.end(); //此处用法错,因为slist.end()是迭代器,类似指针,不能这样转化
list::iterator iter = slist.begin(); //OK
//string temp = iter; //也无法转化,因为是迭代器
//char **p = {"stately","plump","buck","mulligan"}; //此用法错误
char **p = words;
int d = sizeof(p);
int e = sizeof(*p);
int f = sizeof(**p);
}
截图如下
数组指针
words 是指向数组的指针,此处是 char *[4],所以获取的值 b 为16
对于数组而言, char temp[] =”sdfaf”; sizeof(temp) = 6 ,因为还有一个“/0”也在内存中,strlen(temp) = 5, 不计算"/0”。
sizeof计算的是占用内存的大小
指向指针的指针 ,关于**p,*p,p
如图:
虽然**p = words ; 但是可以看到sizeof 后的值是不一样的,因为p是个指针,而words却是个指针数组,虽然作用差不多。
红色字体的结论,迭代器:
虽然slist.begin(),slist.end()都是迭代器,iter也是,但是在调试过程中,监视器内iter是可以显示指向的元素值,但是begin和end 不知道如何正确在监视器内获取值
如图
从图中可以看到,迭代器虽然像个指针,但是在监视器内和指针不一样的是,iter也可以显示值(但是在代码中,是无法通过这个来取值,必须用到解引用符号“*”),而指针在监视器内只能显示地址。而指针带了“*”后(如*words)可以显示值,迭代器用解引用符号*iter(实际上在代码中对于迭代器,*iter才是显示值)却无法正确显示。可能是监视器机制的原因吧,困惑了很久的问题总算有点眉目了。。
sizeof 的一些例子 (转)
最近在论坛里总有人问关于sizeof的问题,并且本人对这个问题也一直没有得到很好的解决,索性今天对它来个较为详细的总结,同时结合strlen进行比较,如果能对大家有点点帮助,这是我最大的欣慰了。
一、好首先看看sizeof和strlen在MSDN上的定义:
首先看一MSDN上如何对sizeof进行定义的:
sizeof Operator sizeof expression The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t. The expression is either an identifier or a type-cast expression (a type specifier enclosed in parentheses). When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment. When applied to a statically dimensioned array, sizeof returns the size of the entire array. The sizeof operator cannot return the size of dynamically allocated arrays or external arrays.
然后再看一下对strlen是如何定义的:
strlen Get the length of a string. Routine Required Header: strlen <string.h> size_t strlen( const char *string ); Parameter string:Null-terminated string Libraries All versions of the C run-time libraries. Return Value Each of these functions returns the number of characters in string, excluding the terminal NULL. No return value is reserved to indicate an error. Remarks Each of these functions returns the number of characters in string, not including the terminating null character. wcslen is a wide-character version of strlen; the argument of wcslen is a wide-character string. wcslen and strlen behave identically otherwise.
二、由几个例子说开去。
第一个例子:
char* ss = "0123456789"; sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针 sizeof(*ss) 结果 1 ===》*ss是第一个字符 char ss[] = "0123456789"; sizeof(ss) 结果 11 ===》ss是数组,计算到/0位置,因此是10+1 sizeof(*ss) 结果 1 ===》*ss是第一个字符 char ss[100] = "0123456789"; sizeof(ss) 结果是100 ===》ss表示在内存中的大小 100×1 strlen(ss) 结果是10 ===》strlen是个函数内部实现是用一个循环计算到/0为止之前 int ss[100] = "0123456789"; sizeof(ss) 结果 400 ===》ss表示再内存中的大小 100×4 strlen(ss) 错误 ===》strlen的参数只能是char* 且必须是以''/0''结尾的 char q[]="abc"; char p[]="a/n"; sizeof(q),sizeof(p),strlen(q),strlen(p); 结果是 4 3 3 2
第二个例子:
class X { int i; int j; char k; }; X x; cout<<sizeof(X)<<endl; 结果 12 ===》内存补齐 cout<<sizeof(x)<<endl; 结果 12 同上
第三个例子:
char szPath[MAX_PATH]
如果在函数内这样定义,那么sizeof(szPath)将会是MAX_PATH,但是将szPath作为虚参声明时(void fun(char szPath[MAX_PATH])),sizeof(szPath)却会是4(指针大小)
三、sizeof深入理解。
short f(); printf("%d/n", sizeof(f()));输出的结果是sizeof(short),即2。
char str[20]="0123456789"; int a=strlen(str); //a=10; int b=sizeof(str); //而b=20;
fun(char [8]) fun(char [])都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小, 需要这样做:进入函数后用memcpy拷贝出来,长度由另一个形参传进去
fun(unsiged char *p1, int len) { unsigned char* buf = new unsigned char[len+1] memcpy(buf, p1, len); }有关内容见: C++ PRIMER?
四、结束语
sizeof使用场合。
void *malloc(size_t size), size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。
void * memset(void * s,int c,sizeof(s))