(一)printf
问题:
double i = 1;
int j = 2;
printf("i = %d, j = %d/n", i , j);
那么得到的结果是:
i = 0, j = 1072693248
具体原理参照:
http://blog.csdn.net/Ididcan/archive/2011/06/12/6539800.aspx
测试代码如下:
#include "stdio.h " #include "stdlib.h " void myprintf(char* fmt, ...) //一个简单的类似于printf的实现,//参数必须都是int 类型 { char* pArg=NULL; //等价于原来的va_list char c; pArg = (char*) &fmt; //注意不要写成p = fmt !!因为这里要对//参数取址,而不是取值 pArg += sizeof(fmt); //等价于原来的va_start,这里就是取得第一参数的首地址 do { c =*fmt; if (c != '%'){ putchar(c); //照原样输出字符 } else{ char c; int i; //按格式字符输出数据 switch(*++fmt) { case 'c': c = *((char*)pArg); printf("%c",c); pArg += sizeof(char); break; case 'd': i = *((int*)pArg); printf( "%d",i); pArg += sizeof(int); break; case 'l': if(*(fmt+1)=='f'){ double d = *((double*)pArg); printf("%lf",d); ++fmt; pArg += sizeof(double); } break; case 'x': printf( "%#x",*((int*)pArg)); pArg += sizeof(int); break; default: break; } //pArg += sizeof(int); //等价于原来的va_arg } ++fmt; }while (*fmt != '/0'); pArg = NULL; //等价于va_end return; } int main(int argc, char* argv[]) { double i = 1; int j = 2; int* pint = (int*)&i; printf("%d/n",*pint); printf("%d/n",*++pint); myprintf( "the first test: i = %d /n",i,j); myprintf( "the secend test: i = %d; j = %d; /n",i,j); return 0; }
运行结果:
0
1072693248
the first test: i = 0
the secend test: i = 0; j = 1072693248;
Press any key to continue . . .
(二)strlen
strlen 是以'/0'为结尾的,另外'/0'在c/c++中条件判断是等同于false
int myStrlen(const char* str){ int l = 0; while(*str++) ++l; return l; } int main(int argc, char* argv[]) { /*double i = 1; int j = 2; int* pint = (int*)&i; printf("i = %d, j = %d/n", i , j); printf("%d/n",*pint); printf("%d/n",*++pint); myprintf( "the first test: i = %d /n",i,j); myprintf( "the secend test: i = %d; j = %d; /n",i,j); return 0;*/ printf("%d/n",strlen("123/0123")); printf("%d/n",myStrlen("123/0123")); printf("%d/n",strlen("123/0 123")); printf("%d/n",myStrlen("123/0 123")); }
(三)sizeof
问题
int i = 10;
sizeof(++i);
printf("i = %d/n", i);
运行结果为10;
原因是sizeof是运算符,那么在执行过程中直接将i等同于4,因此不对i进行操作,故i的值并没有改变。
此外,在看如下代码
int i = 0;
double j = 0;
printf("sizeof(i+j) = %d/n",sizeof(i+j));
printf("sizeof(j+i) = %d/n",sizeof(j+i));
运行结果:
sizeof(i+j) = 8
sizeof(j+i) = 8
Press any key to continue . . .
说明只要根据括号内的表达式能够得到类型,那么就可以对该类型进行转换。i+j向上转换为double型,因此为8;
以上代码都是在vs2010环境下运行
有关sizeof 和 strlen的问题可以参考:
http://www.vckbase.com/document/viewdoc/?id=1054
文章内容如下:(转载)
一、好首先看看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))