《如何攻破C语言学习、笔试与机试的难点.docx》由会员分享,可在线阅读,更多相关《如何攻破C语言学习、笔试与机试的难点.docx(104页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、C语言编程中的几个基本概念1.1 #includev 与# include”1. # include0和# include有什么区别?这个题目考查大家的基础能力,#include用来包含开发环境提供的库,#include”用来包含.c/.cpp文件所在目录下的头文件。注意:有些开发环境可以在当前目 录下面自动收索(包含子目录),有些开发环境需要指定明确的文件路径名。1.2 switch()1. switch(c)语句中 c 可以是 int, long, char, float, unsigned int 类 型?其实这个题H很基础,c应该是整型或者可以隐式转换为整型的数据,很明显不能是实型 (
2、float、double)。所以这个命题是错误的。1.3 constl.8nst有什么用途?虽然const很常用,但是我相信有很多人仍然答不上来。(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要 对它进行初始化,因为以后就没有机会再去改变它了;(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二 者同时指定为const;(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改 变其值;(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的 成员变量;(5)对
3、于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左 值”。1.4 #ifndef/#define/#endif 1. 头文件中的 #ifndef/#define/#endif 干什么用?其实#ifndef、#define, #endif这些在u-boot、linux内核文件中经常见到,在这么大型的 程序中大量使用,可见它的作用不可小觑。这些条件预编译多用于对代码的编译控制,增加代码的可裁剪性,通过宏定义可以轻松的对 代码进行裁剪。#ifndef/#define/#endif最主要的作用是防止头文件被重复定义。1.5 全局变和局部变全局变量和局部变量在内存中是否有区别
4、?如果有,是什么区别?全局变量储存在静态数据库,局部变量在堆栈。其实,由于计算机没有通用数据寄存器, 则函数的参数、局部变量和返I可值只能保存在堆栈中。提示:局部变量太大可能导致栈溢出, 所以建议把较大数组放在main函数外,防止产生栈溢出。思考:如程序清单1.1所示。会出现怎样的情况?程序清单1.1大数组放在main函数中导致堆栈溢出int main(int argc, char *argv)(int iArray1024 * 1024;return 0;第:节数据存储与变量2.1变量的声明与定义如程序清单2. 1所示会不会报错?为什么?如果不会报错,又是输出什么结果?程序清单2.1变量的声
5、明与定义#includestatic int a ;static int b ;int main( int argc , char *argv)(printf( d %d nM , a , b0);return 0 ;static inta = 8 ;static intb 4;这个程序是不会报错的,并且连警告都不会出现。输出的结果是:8 0static int a,这句程序是声明全局变量a;static int b,这句程序是声明全局数组变量b,并且是不完全声明,也就 组下标。static int a = 8,这里才是定义全局变量a,static int b4,这里是定义全局变量b2.2 局
6、部变量与全局变的较1. 请问如程序清单2. 2所示输出什么?程序清单2. 2局部变量与全局变量#includestatic int a = 8 ;int main( int argc , char *argv)printf( n%d nM , a );return 0 ;)C语言规定,局部变量在自己的可见范围内会“挡住”同名的全局变量,让同名的全局变量临时不可见。即在J 见范围内不能访问同名的全局变量。因此本程序输出为:4。2.3 char、int、float、double 的数据存储1. 请问如程序清单2. 3所示,i和j输出什么?程序清单2. 3数据存储float i = 3 ;int j
7、 = * (int*) (&i);printf( ni = %f nM , i );printf ( 0 j = %#x nn , j );i是毋庸置疑是:3.000000。但是j呢? 3.000000?答案是否定的,j是输出:0x4040 0000.有人会问了,难道j 瞎说,j输出0x4040 0000是有依据,是一个定值!由于i是float数据类型,而j是int数据类型。理论上说,j是取了 i的地址然后再去地址,应该得到的就是ifr 问题的关键就是float数据类型的存储方式和int数据类型不一样,float是占用4个字节(32位),但是float存储 数法存储,最高位是存储数符(负数的数
8、符是0,正数的数符是1);接下来8位是存储阶码;剩下的23位是存储局 i=3.000000,那么3.000000( 10进制)=11 (2进制)=v:shape id=_x0000J1027 style=WlDTH: 40.5pt; HEK equationxml= 121.1 (二进制)。数据在电脑中存储都是二进制,这个应该都没 这里的数符为:0 ,阶码为:E - 127= 1 ,那么阶码为:E= 128即为:1000 0000 (2进制),尾数为:100 000000 0000。那么存储形式就是:0100 0000 0100 0000 0000 0000 0000 0000o这个数据转换成
9、16进制就是(图2.1数据存储方式char、int、float, double的存储方式如图2. l所示。提问:如果i= -3.5的话,请问j输出多少?i = -3.500000j = 0xc0600000这个希望读者自行分析。再问:如果如程序清单2. 4所示。程序清单2. 4数据存储double i = 3 ;int j = * (int*) (&i);printf ( i = %lf nn , i );printf ( n j = %#x nn , j );这样的话,j又输出多少呢?提示:double( 8个字节(64位)的存储方式是:最高位存储数符,接下来11位存储阶码,剩下52位存储尾
10、数是不是得不到你想要的结果? double是8个字节,int是4个字节。一定别忘记了这个。用这个方法也同时可以马 式!2.4 容易忽略char的范围1. 如程序清单2. 5所示,假设&b=0x12ff54,请问三个输出分别为多少?程序清单2. 5 char的范围unsignedint b = 0xl2ff60 ;printf (n ( (int) (&b)+1 )= %#x nn , ( (int) (&b)+1 );printf (n * ( (int*) ( (int) (&b)+1 ) ) = %#x nn , *( (int*) ( (int) (&b)+1 );printf (n *
11、( (char*) ( (int) (&b)+1 ) ) = %#x nH , *( (char*) ( (int) (&b)+1 );很显然,&b是取无符号整型b变量的地址,那么(int)(&b)是强制转换为整型变量,那么力口1即为0x12ff54+1 = ( 以(int)(&b)+1 )0x12ff55o图2. 3指针加1取字符型数据由于(int)(&b)+1 )是整型数据类型,通过(足*)(。明(&功+1)转化为了整型指针类型,说明要占4个字节,即: 0x12ff56、0x12ff57, 0x12ff58,再去地址*( (int *)( (int) (&b)+1 )得到存储在这4个字节中
12、的数据。但是很遗 我们并不知道存储的是什么,所以我们只能写出0x*0012ff。*表示存储在0x12ff58中的数据。如图2. 2所示。图2. 2指针加1取整型数据以此类推,*( (char *)( (int) (&b)+1 ) ) = Oxff.如图2. 3所示。但是,*( (char*)( (int) (&b)+1 )输出的却是:Oxff ff ff ff !问题出现了,为什么*( (char*)(int) (&b)+1 )不是Oxff,而是Oxff ff ff ff? char型数据应该占用1个字节,为什 ff ff ff?使用d输出,printf (n *( (char*) ( (in
13、t) (&b)+1 ) ) = %d nH , ( (char*) ( (int) (&b)+1 );结果为1? ? ?问题出在signed char的范围是:128127,这样肯定无法储存Oxff,出现溢出。所以将printf (n *( (char*) ( (int) (&b)+1 ) ) = %#x nM , ( (char*) ( (int) (&b)+1 );改成printf (n *( (unsigned char*) ( (int) (&b)+1 ) ) = %#x n” ,*( (unsigned char*) ( (int) (&b)+1 );就可以输出Oxff,因为unsi
14、gned char的范围是:0255(0xff)。1.iDa(34.04 KB,卜,载次数:23)图2.1数据存储方式char | | | | | | | |-| 8位(1 个字节)M llllllllllllllllllllllllllET 32 位(4 个字节) X :由画皿皿画面面工版位字节) double:| | 1I位 |52位|:64位(8个字节)符号位 阶码位尾数2.ipg(25.49 KB,卜载次数:20)图2.2指针加1取整型数据int4个字节3.ipa(17.13KB.下载次数:17)图2.3指针加1取字符型数据第三节 数学算法解决C语言问题3.1N!结果中0的个数1.99
15、!结果中后面有多少个0?谁跟你说过高数没用?数学是C语言的支撑,没有数学建模的支撑就没有那么经 典的C语言算法!如果你能一个一个乘出来我算你狠!我也佩服你!0也就意味着乘积是10的倍数,有10的地方就有5.有5就不担心没2. 10以内能被5 整除的只有5,但是能被2整除多的去了。所以就简化成了这个数只要有一个因子 5就一定对应一个0.所以可以得出下面结论:当0 n = 5时,f(n!) = k + f(k!),其中 k = n / 5 (取整)。如程序清单3. 1所示。程序清单3. 1求N!中0的个数 #includeint fun (int iValue)(int iSum = 0;whil
16、e(iValue / 5 != 0)(iSum += (iValue / 5 );iValue /= 5;return iSum;)int main( int argc , char *argv )(int iNumberz iZoreNumber;scanf( %d, &iNumber);iZoreNumber = fun(iNumber);printf ( n%dnn, iZoreNumber);return 0;)所以99!后面有多少个0的答案是:99 / 5 = 19 , 19/5 = 3;3/5 = 0.也就是:19 + 3 + 0 = 22.这里延伸为N!呢,一样的,万变不离其宗!
17、3.2N!结果中的位数1. 请问N!结果中有几位数?数学!还是数学,数学真的博大精深,如果大学没有好好学数学,会成为你一辈 子的遗憾。我们先假设:N! = 10 *A,我们知道10*ri0*2 (不含102)之间是2位数, 10.21。3(不含 1(T3)之间是3位数,以此类推,(A+1)(不含 10、(A+1)则是(A+1)位数,那就是说,我们只要求出A,即可知道N!有几位数。A=loglO(N!),N! = 1*2*3*N,那么 A= Iogl0(l)+logl0(2)+loglO(N).这样好计算了吧!程序如程序清单6. 2所示。程序清单6.2求N!结果中的位数#include #inc
18、lude int main(int argcz char *argv)int iNumber z i = 0 ;double sum = 0 ;printf (请输入 iNumber : n );scanf ( n%dn , &iNumber );for ( i = 1 ; i ( iNumber + 1 ) ; i+) sum += loglO (i);printf ( n N!有告d位 n”, (int) sum + 1 );return 0;我们看下调试结果:请输入 iNumber : 10N!有7位请按任意键继续.第四节关键字、运算符与语句1.1 static1.如程序清单4.1所示,
19、请问输出i、j的结果?程序清单4.1 static #include static int j ;void funi(void)(static int i = 0 ;i + + ;printf(Mi = %d , i );void fun2(void)j = 0 ;j + + ;printf (M j = %d nM z j );)int main(int argc, char *argv)(int k = 0 ;for( k = 0 ; k 10 ; k+ )funl ();fur)2 ();printf(Mn n);return 0;答案:i = 1j = 1i = 2j = 1i=3j=
20、1i=4j=1i=5j=1i=6j=1i=7j=1i=8j=1i=9j=1i = 10 j = 1请按任意键继续.很多人傻了,为什么呢?是啊,为什么呢? !由于被static修饰的变量总存在内存静态区,所以运行这个函数结束,这个静态变量的值也不会被销毁,函数 候仍然能使用这个值。有人就问啊,为什么j 一直是1啊。因为每次调用fun2()这个函数,j都被强行置。了。static的作用:(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其4 时仍维持上次的值;(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问
21、;(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块P(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员11.2for循环的深究1. 如程序清单4. 2所示,输出结果是什么?程序清单4. 2 for循环#include int main(int argc, char *argv)(int i = 0 ;for( i = 0 ,printf (First = %d , i );printf(nSecond
22、 = %d M z i ) , i 10 ;i+ , printf(Third = %d , i )(printf(nFourth = %d nM , i);return 0;这个题目主要考察对for循环的理解。我们先来看看运行程序会输出什么?First =0Second=0Fourth=0Third =1Second=1Fourth=1Third =2Second=2Fourth=2Third =3Second=3Fourth=3Third =4Second=4Fourth=4Third =5Second=5Fourth=5Third =6Second=6Fourth=6Third =7Se
23、cond=7Fourth=7Third =8Second=8Fourth=8Third =9Second=9Fourth=9Third = 10 Second = 10请按任意键继续.从输出我们就可以知道程序到底是什么运行:首先i = 0 ,所以输出:Rrst = 0 ;接着输出:Second = 0 ; i 10成立,则输出:Fourth = 0。就此完成 接着i+ ,此时i= 1,输出:Third = 1 ;接着输出:Second = 1 ;i 10成立,则输出:Fourth = 1 推。1.3 尺sizeof1. 如程序清单4.3所示,sizeof(a),sizeof(b)分别是多少?程
24、序清单4. 3 sizeof#include int main(int argc, char *argv)char a23;short b2 3;printf( nsizeof(a) = %d nn , sizeof ( a );printf( sizeof(b) = %d nn , sizeof ( b );return 0;)这个题目比较简单,由于char是1个字节、short是2个字节,所以本题答案是:sizeof (a) = 6sizeof(b) = 12请按任意键继续. . .好的,再来看看如程序清单4.4所示,sizeof(a),sizeof(b)分别是多少?程序清单4. 4 si
25、zeofinclude int main(int argc, char *argv)(char *a 2 3;short *b23;printf( nsizeof(a) = %d nn , sizeof( a );printf( sizeof (b) = %d nn , sizeof( b );return 0;是数组指针呢,还是指针数组呢?这里涉及*和和优先级的问题。我告诉大家的是这两个数组存放的都是指针什么,在后续章节会详细解释,然而指针变量所占的字节数为4字节,所以答案:sizeof(a) = 2424sizeof(b)=请按任意键继续.1.4 +i 和 i+1.或许大家都知道,+ +
26、i是先执行i自加再赋值,但是i+ +是先赋值再自加,但是还有隐藏在后面的东西呢 int i = 0 ;int iNumber = 0 ;iNumber = (+i) + (+i) + (+i);C-Free编译输出是:7,有的编译器输出是:9。这两个答案都是对的,编译器不同所不同。7 = 2+2+3; 9=3+3, 答案是7的先执行(+i)+(+i)再执行+(+i),但是答案是9的是一起执行。这只是前奏,先看几个让你目瞪口呆的例子。编译环境是VS2010。int i = 0 ;int iNumber = 0 ;iNumber = (i+) + (+i) + (+i);printf( niNum
27、ber = %d nn , iNumber );这里输出是:4! 4= 1 + 1 + 2。int i = 0 ;int iNumber = 0 ;iNumber = (+i) + (i+) + (+i);printf ( MiNumber = %d nn , iNumber );这里输出是:4! 4=1 + 1 + 2o int i = 0 ;int iNumber = 0 ;iNumber = (+i)+ (+i) + (i+);printf ( iNumber = %d nn , iNumber ) ;这里输出是:6! 6=2+2+2o这里至少能说明两个问题,其一,先执行前面两个,再执行
28、第三个;其二,。+ + )这个i的自加是最后执行! int i = 0 ;int iNumber = 0 ;iNumber = (+i) + (i+) + (+i) + (+i) + (i+);printf ( niNumber = %d nn , iNumber );这个会是多少? !答案是:10! 10=1 + 1 + 2+3+3!不同的编译器或许会存在不同的答案,希望读者自行进行验证。1.5 scanf()函数的输入1. 如程序清单4.5所示,运行程序,当显示Enter Dividend:,输入的是a,按下Enter之后程序会怎么运彳: 程序清单4. 5 scanf()函数的输入#inc
29、ludeint main(void)float fDividend,fDivisorz fResult;printf(MEnter Dividend:H);scanf(H%f nz &fDividend);printf(HEnter Divisor:n);scanf(H%fnz &fDivisor);fResult=fDividend/fDivisor;printf(Result is: %fnM,fResult);return 0;这个问题有人会说,肯定是显示Enter Divisor:要我输入除数咯。是这样吗?答案是:如果你在日iter Dividend:之后输入非数字,按下Enter之后
30、显示的不是Enter Divisor:要你输入除数 此就运行结束,显示一个不确定答案,这个答案每一次都会变。如果你在Enter Divisor:之后输入非数字,按 显示的不是Reslut的结果,而是程序到此就运行结束,显示一个不确定答案,这个答案每一次都会变。由于scanf。使用了f,当输入数字的时候,scanf()将缓冲区中的数字读入fDividend,并清空缓冲区。由于我 数字,因此scanf。在读入失败的同时并不会清空缓冲区。最后的的结果是,我们不需要再输入其他字符,scant 读取缓冲区,每次都失败,每次都不会清空缓冲区。当执行下一条scanf()函数读取除数时,由于缓冲区中有数 等待
31、用户输入,而是直接从缓冲区中取走数据。那么防止输入非数字的程序应该怎样呢?#include int main( int argc , char *argv)floatfDividend , fDivisor , fResult ;int iRet ;char cTmpl 256 ;printf( Enter Dividend nn ) ; iRet = scanf( n%fn , &fDividend );if ( 1 = iRet ) (printf ( Enter Divisor nH );iRet = scanf(, &fDivisor );if ( 1= iRet ) (fResult
32、 = fDividend / fDivisor ;printf ( Result is %f nM , fResult ); else(printf ( nInput error ,not a number! nn ) ; gets(cTmpl);return 1 ; elseprintf ( HInput error , not a number! n);gets(cTmpl);return 1 ;return 0 ;1.6 scanf()函数的返回值1. 如程序清单4. 6所示,请问输出会是什么?程序清单4. 6 scanf()函数的返回值int a z b ;printf ( nn ,
33、scanf(n%d%dn , &a , &b);输出输入这个函数的返回值? !答案是:2。只要你合法输入,不管你输入什么,输出都是2。那么我们就要深 这个函数。scanf()的返回值是成功赋值的变量数量。1.7const作用下的变量1. 阅读如程序清单4. 7所示,想想会输出什么?为什么?程序清单4. 7 const作用下的变量constint iNumber =10 ;printf (n iNumber = %d n , iNumber);int *ptr = (int *) (&iNumber);*ptr = 100 ;printf (n iNumber = %d nu , iNumber
34、);8nst的作用在第四章已经详细讲了,这里就不再累赘,答案是:10,10。这里补充一个知识点:const int * p指针变量p可变,而p指向的数据元素不能变int* const p指针变量p不可变,而p指向的数据元素可变const int* const p指针变量p不可变,而p指向的数据元素亦不能变1.8*ptr+、*(ptr+), *+ptr、*(+ptr), +(*ptr)、(*ptr)+的纠缠不清1.如程序清单4. 8所示程序,输出什么?程序清单4. 8 *ptr+int iArray3 = 1 , 11 , 22);int *ptr = iArray ;printf ( n*pt
35、r+ = %d nn , *ptr+ );printf ( M*ptr = nH , *ptr );纠结啊,是先算* ptr还是ptr+;还是纠结啊,ptr是地址加1还是偏移一个数组元素!这里考查了两个知识点,其一:*与+ +的优先级问题;其二,数组i+ +和+ + i的问题。*和+ +都是优先级为2, 算符,自右向左结合。所以这里的*ptr+ +和*(ptr+ + )是等效的。首先ptr是数组首元素的地址,所以ptr+ +是偏移一个数组元素的地址。那么ptr+ +运算完成之后,此时的ptr是由 所以第二个输出*ptr= 11。如图4. 1所示。那么倒回来看第一个输出,ptr+ +是在执行完成
36、*ptr+ +之后再执行的, =1 O如程序清单4. 9所示程序,输出会是什么?程序清单4.9 *+ptrint iArray3 = 1 , 11 , 22);int *ptr= iArray ;printf ( n* +ptr = %d nn , * + +ptr );printf ( M*ptr = %d nn , *ptr );这个解释和上面解释差不多,就是+ + ptr和ptr+ +的差别,所以这里的两个输出都是:11。同样的道理,*+ + p 是等效。再如程序清单4. 10所示,输出又会是什么?程序清单4. 10 (*ptr) +int iArray3 = 1 , 11 , 22);
37、int *ptr = iArray ;printf ( n(*ptr)+ = %d n” , (*ptr)+ );printf( n*ptr = %d nn , *ptr );这个的输出是:1,2。原因请读者分析。4.ipa(94.96 KB,卜.载次数:11)图 4.1 ptr+ +1 11 22ptr ptr+ptr指向的是数组元素a0 = 1的地址,ptr+指向的是数组元素a1 = 11的地址第五节 C语言中的细节1.1 “零值”比较1. 写出float x与零值”比较的if语句。首先要知道float是有精度的,不能直接与0相比较或者两数相减与。相比较。float能保留几 位小数格案是6
38、位。既然如此,那么就应该这么写:if(x 0.000001) & (x = (Y) ? (X) : (Y)2. 宏定义两个数相加请问如程序清单5. 1输出什么?程序清单5.1宏定义两数相加#define DOUBLE(x) x+xint main(int argc, char* argv)(int iNumber = 0 ;printf(n%dnn , 10*DOUBLE(10);return 0;)其实这个程序非常简单,学习C语言一周就应该理解是什么意思,但是一般会出错的的地 方都在细节。其实这个程序输出是110。可能有人会问,不是10先DOUBLE嘛,然后乘以10,不是200嘛。是啊,想法
39、是好的,我想 这个程序的“原意”也应该是这样,但是就是由于优先级的问题,打破了我们的愿望。如果 要得到200,那么就应该是这样宏定义:#define DOUBLRx) (x)+(x)。我想,无论我加 多少层括号都不算违法吧。1.3 递归运算1. 如程序清单5. 2所示,输出什么?程序清单5. 2递归运算#include int func(int a)if (a=0)return a;)printf(为dn,func(a+/2);return a;int main(int argc, char *argv)(printf(H%dn,func(7);return 0;)答案:0, 2, 4, 8这
40、里把7送进去,那么func(a+/2),先执行7/2= 3,然后a+= 8,此时返回3;接着把3送进 去,func(a+/2),先执行3/2=1,然后a+ = 4,此时返回1 ;接着把1送进去,func(a+/2), 先执行1/2=0,然后a+ = 2,此时返回0;接着把。送进去,此时直接返回0,递归结束。递归最容易忽略的细节是,由于递归次数过多,容易导致堆栈溢出。1.4 让人忽略的贪心法1. 如程序清单5. 3所示,程序输出什么?程序清单5. 3贪心法int k = 8 ;int i = 10 ;int j = 10 ;k *= i+j ;printf(n%d nM , k);贪心法,就是一
41、次性能尽可能多得吃运算符,那么这里k* = i+ +j,加上括号之后就是这样: k= k* (i+ + ) + j);这样的话就很简单可以得出答案为:160。1.5 性能优化1 .对如程序清单5. 4所示进行性能优化,使得效率提高。程序清单5. 4性能优化int iValuel;int iValue2;iValuel = 1234/16;iValue2 = 1234%32;对于嵌入式进行除法是很消耗效率的,能使用移位完成最好使用移位完成。iValuel = 1234 4;iValue2 = 1234 - ( (1234 5) 5);1234/ 16= 77; 1234% 32= 18。而十进制
42、:1234转化成二进制:0100 1101 0010.1234 4= 0000 01001101,转化为十进制即为:77; 1234 5= 0000 0010 0110, (1234 5) 5)即为0100 1100 0000,转化为十进制即为:1120, 1234 - 1216 = 18。第六节数组与指针1.1 数组、数组元素、指针的大小1.如程序清单6 1所示,程序输出什么?程序清单6. 1数组、数组元素、指针的大小#include int main(int argc, char *argv) (int *p ;printf(nsizeof(p)=%dnn,sizeof(p);printf
43、 (11 sizeof (*p)=%dnM,sizeof (*p);int a100;printf(sizeof(a)=%dnn,sizeof(a);printf(sizeof (a100)=%dn,sizeof(a100);printf(nsizeof(&a)=%dnM,sizeof(&a);printf(nsizeof(&a0)=%dn,sizeof(&a0);return 0; p是指针,任何数据类型的指针都是占4字节;*p是一个指针指向的int数据,int型数据占用4字节;a是数组,除了 sizeof(a)和&a之外,当a出现在表达式中时,编译器会将a生成一个指向a0的指针,而这里 数组的大小。答案:sizeof(p)=4sizeof(*p)=4sizeof(a)=400sizeof (a 100)=sizeof (&a)= 4sizeof(&a0)= 4请按任意键继续.1.2 广东省的省政府和广州市的市政府都在广州1. 如程序清单6. 2所示,如果ptr = Ox 1000 0000 ,那么剩下三个输出是多少?程序清单6. 2数组首地址与数组首元素地址int iArray3 =1,2,3;int *ptr = iArray ;printf(nptr=