c语言位运算的一个问题。

乱夏 2014-04-15 06:52:19
#include <stdio.h>
#include <stdlib.h>
unsigned int invert( unsigned int x , int p , int n );

int main()
{

printf("%u",invert( 0U , 31 , 32));

//bitset<32> s(0xffffffffU);
//printf("%u", *(unsigned *)&s);
system("pause");
return 0;

}

unsigned int invert( unsigned int x , int p , int n)
{
unsigned int r;
r = (~(~0U << n) << ( p + 1 - n));

//printf("r = %x\n",r);


unsigned s = r & x;
//printf("s = %x \n",s);

x = x | r;

x = x & (~s);

return x ;

}

这个是K&R上的2.7那题,我自己写的。
我编译运行之后结果竟然是0.
然后我就开始调试,断点设置在25行,最终在20行那里发现了一个问题。
我watch单个变量r的时候,r是0,有图:
如果就这样一直运行下去,最后的结果是0;
但是,我又watch了整个
r = (~(~0U << n) << ( p + 1 - n));

结果就变成了0Xffffffff,有图:
然后再watch单个变量r,就看到r变成了0xffffffff,有图的:
最后输出的结果也是0xffffffff。
如果我不watch整个r的赋值表达式,就不会产生正确的结果。
想请教一下各位大神,这个是因为什么啊?
我用的ide是codeblock,编译器是mingw的GCC,版本就是cb12.11自带的mingw
...全文
339 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
c0py_ninj4 2014-04-23
  • 打赏
  • 举报
回复
学习到了,汇编好强大啊。可我不怎么看的很清楚,呜呜呜。。。。
均陵鼠侠 2014-04-22
  • 打赏
  • 举报
回复
引用 17 楼 halfword1982 的回复:
针对32位系统,当算术左移位数大于31时,C标准中对该移位操作是未定义的。

unsigned in i = 1;
int n = 32;
i <<= n;
上述C代码在Intel x86、PowerPC、ARM架构CPU下对应的汇编指令和移位执行说明如下:

;;Intel
;;将寄存器eax中的值左移,移动位数为寄存器cl中的值,结果存在eax中
;;仅取寄存器cl最低5 bits的值作为移位数
;;当cl寄存器中的值为32时,该操作等价于shl    eax, 0,即移位操作无效
shl    eax,cl

;;PowerPC
;;将寄存器RS中的值左移,移动位数为寄存器RB中的值,结果存在RA中
;;仅取寄存器RB的高6 bits作为移位数,当移位数为32-63时,移位结果为0
slw  RA,RS,RB

;;ARM
;;将寄存器Rm中的值左移,移动位数为寄存器Rm中的值,结果存在Rd中
;;仅取Rs的最低8 bits作为移位数,当移位数大于31时,移位结果为0
LSL  Rd, Rm, Rs
可以看到,对于C标准中未定义的操作,不同架构CPU有不同的实现和限制,导致计算结果不同。
C标准中哪里来的“算术左移”?
FancyMouse 2014-04-22
  • 打赏
  • 举报
回复
引用 16 楼 sholber 的回复:
[quote=引用 9 楼 halfword1982 的回复:] 这个问题的关键在于n的值为32,对于32位系统,算术左移位数的合法值为0-31,超过该范围时,移位操作的结果在C标准中是未定义的,完全取决于芯片厂家的实现。 Intel对于算术左移指令有如下的规定: SAL/SAR/SHL/SHR—Shift The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). 借用楼上的代码,地址0040104F处的shl指令即对应(~0U << n)的计算,寄存器cl中的值为n=32,取最低5 bits的值为0,所以该指令执行后,eax中的值依然为0xffffffff

20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
完全取决于芯片厂家是什么意思?[/quote] 其实这应该是undefined behavior而不是implementation-defined。标准规定这是UB是考虑到编译器可以对于这类操作做constant folding,这个fold的结果可以和目标cpu的指令效果不同。
hw7be 2014-04-22
  • 打赏
  • 举报
回复
针对32位系统,当算术左移位数大于31时,C标准中对该移位操作是未定义的。

unsigned in i = 1;
int n = 32;
i <<= n;
上述C代码在Intel x86、PowerPC、ARM架构CPU下对应的汇编指令和移位执行说明如下:

;;Intel
;;将寄存器eax中的值左移,移动位数为寄存器cl中的值,结果存在eax中
;;仅取寄存器cl最低5 bits的值作为移位数
;;当cl寄存器中的值为32时,该操作等价于shl    eax, 0,即移位操作无效
shl    eax,cl

;;PowerPC
;;将寄存器RS中的值左移,移动位数为寄存器RB中的值,结果存在RA中
;;仅取寄存器RB的高6 bits作为移位数,当移位数为32-63时,移位结果为0
slw  RA,RS,RB

;;ARM
;;将寄存器Rm中的值左移,移动位数为寄存器Rm中的值,结果存在Rd中
;;仅取Rs的最低8 bits作为移位数,当移位数大于31时,移位结果为0
LSL  Rd, Rm, Rs
可以看到,对于C标准中未定义的操作,不同架构CPU有不同的实现和限制,导致计算结果不同。
均陵鼠侠 2014-04-20
  • 打赏
  • 举报
回复
引用 9 楼 halfword1982 的回复:
这个问题的关键在于n的值为32,对于32位系统,算术左移位数的合法值为0-31,超过该范围时,移位操作的结果在C标准中是未定义的,完全取决于芯片厂家的实现。 Intel对于算术左移指令有如下的规定: SAL/SAR/SHL/SHR—Shift The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). 借用楼上的代码,地址0040104F处的shl指令即对应(~0U << n)的计算,寄存器cl中的值为n=32,取最低5 bits的值为0,所以该指令执行后,eax中的值依然为0xffffffff

20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
完全取决于芯片厂家是什么意思?
均陵鼠侠 2014-04-18
  • 打赏
  • 举报
回复
引用 9 楼 halfword1982 的回复:
这个问题的关键在于n的值为32,对于32位系统,算术左移位数的合法值为0-31,超过该范围时,移位操作的结果在C标准中是未定义的,完全取决于芯片厂家的实现。 Intel对于算术左移指令有如下的规定: SAL/SAR/SHL/SHR—Shift The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). 借用楼上的代码,地址0040104F处的shl指令即对应(~0U << n)的计算,寄存器cl中的值为n=32,取最低5 bits的值为0,所以该指令执行后,eax中的值依然为0xffffffff

20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
不够严谨。 你能告诉我
char c = 1;
int i = sizeof (int) * CHAR_BIT - 1;
c = c << i;
是未定义的吗?为什么?
赵4老师 2014-04-18
  • 打赏
  • 举报
回复
电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
均陵鼠侠 2014-04-18
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
[quote=引用 4 楼 luanxia77 的回复:] 楼上,你这个算什么。。。。?
人间正道是沧桑, 编程正道是汇编。[/quote] 学C要靠汇编,那你说
(char)1<<1LL
的结果是啥类型,并用汇编证明。
hw7be 2014-04-18
  • 打赏
  • 举报
回复
引用 13 楼 sholber 的回复:
不够严谨。 你能告诉我
char c = 1;
int i = sizeof (int) * CHAR_BIT - 1;
c = c << i;
是未定义的吗?为什么?
上述移位操作是否为未定义取决于char类型的符号定义。如果char为signed char,移位计算前,其类型提升为signed int,移位操作的结果(数值结果,正值)超过了signed int的范围,该操作为未定义的;如果char为unsigned char,则该操作的定义是确定的。
一根烂笔头 2014-04-18
  • 打赏
  • 举报
回复

//32bits反转:
x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;

/*circle left shift :y = (x << n) | (x >> (32 - n));
circle right shift:y = (x >> n) | (x << (32 - n));
由循环移位,第4,5句优化为:*/
x = (x << 24) | ((x & 0xFF00) << 8) | 
	((x >> 8) & 0xFF00) | (x >> 24);

//32b,4字节反转:
y = x & 0x00FF00FF;
(y >> 8) | (y << 24) | (((x << 8) | (x >> 24)) & 0x00FF00FF);
乱夏 2014-04-17
  • 打赏
  • 举报
回复
引用 9 楼 halfword1982 的回复:
这个问题的关键在于n的值为32,对于32位系统,算术左移位数的合法值为0-31,超过该范围时,移位操作的结果在C标准中是未定义的,完全取决于芯片厂家的实现。 Intel对于算术左移指令有如下的规定: SAL/SAR/SHL/SHR—Shift The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). 借用楼上的代码,地址0040104F处的shl指令即对应(~0U << n)的计算,寄存器cl中的值为n=32,取最低5 bits的值为0,所以该指令执行后,eax中的值依然为0xffffffff

20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
真的很感谢。
hw7be 2014-04-16
  • 打赏
  • 举报
回复
这个问题的关键在于n的值为32,对于32位系统,算术左移位数的合法值为0-31,超过该范围时,移位操作的结果在C标准中是未定义的,完全取决于芯片厂家的实现。 Intel对于算术左移指令有如下的规定: SAL/SAR/SHL/SHR—Shift The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). 借用楼上的代码,地址0040104F处的shl指令即对应(~0U << n)的计算,寄存器cl中的值为n=32,取最低5 bits的值为0,所以该指令执行后,eax中的值依然为0xffffffff

20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
乱夏 2014-04-16
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
16:
17:   unsigned int invert( unsigned int x , int p , int n)
18:   {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,48h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
19:       unsigned int r;
20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
21:
22:       //printf("r = %x\n",r);
23:
24:
25:       unsigned s = r & x;
00401061   mov         ecx,dword ptr [ebp-4]
00401064   and         ecx,dword ptr [ebp+8]
00401067   mov         dword ptr [ebp-8],ecx
26:       //printf("s = %x \n",s);
27:
28:       x = x | r;
0040106A   mov         edx,dword ptr [ebp+8]
0040106D   or          edx,dword ptr [ebp-4]
00401070   mov         dword ptr [ebp+8],edx
29:
30:       x = x & (~s);
00401073   mov         eax,dword ptr [ebp-8]
00401076   not         eax
00401078   mov         ecx,dword ptr [ebp+8]
0040107B   and         ecx,eax
0040107D   mov         dword ptr [ebp+8],ecx
31:
32:       return x ;
00401080   mov         eax,dword ptr [ebp+8]
33:
34:   }
00401083   pop         edi
00401084   pop         esi
00401085   pop         ebx
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret
16:
17:   unsigned int invert( unsigned int x , int p , int n)
18:   {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,48h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
19:       unsigned int r;
20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
21:
22:       //printf("r = %x\n",r);
23:
24:
25:       unsigned s = r & x;
00401061   mov         ecx,dword ptr [ebp-4]
00401064   and         ecx,dword ptr [ebp+8]
00401067   mov         dword ptr [ebp-8],ecx
26:       //printf("s = %x \n",s);
27:
28:       x = x | r;
0040106A   mov         edx,dword ptr [ebp+8]
0040106D   or          edx,dword ptr [ebp-4]
00401070   mov         dword ptr [ebp+8],edx
29:
30:       x = x & (~s);
00401073   mov         eax,dword ptr [ebp-8]
00401076   not         eax
00401078   mov         ecx,dword ptr [ebp+8]
0040107B   and         ecx,eax
0040107D   mov         dword ptr [ebp+8],ecx
31:
32:       return x ;
00401080   mov         eax,dword ptr [ebp+8]
33:
34:   }
00401083   pop         edi
00401084   pop         esi
00401085   pop         ebx
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret
我刚刚对着汇编代码一行一行的运行了一下, 就在这一行 dword ptr [ebp-4],eax的时候,eax是0xffffffff,但是我看r的内存地址的时候,赋值并没有成功,但是我在watch整个表达式之后又再,再watch变量r,r的内存就是fffffff了。感觉不知道为什么?
乱夏 2014-04-16
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
16:
17:   unsigned int invert( unsigned int x , int p , int n)
18:   {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,48h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
19:       unsigned int r;
20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
21:
22:       //printf("r = %x\n",r);
23:
24:
25:       unsigned s = r & x;
00401061   mov         ecx,dword ptr [ebp-4]
00401064   and         ecx,dword ptr [ebp+8]
00401067   mov         dword ptr [ebp-8],ecx
26:       //printf("s = %x \n",s);
27:
28:       x = x | r;
0040106A   mov         edx,dword ptr [ebp+8]
0040106D   or          edx,dword ptr [ebp-4]
00401070   mov         dword ptr [ebp+8],edx
29:
30:       x = x & (~s);
00401073   mov         eax,dword ptr [ebp-8]
00401076   not         eax
00401078   mov         ecx,dword ptr [ebp+8]
0040107B   and         ecx,eax
0040107D   mov         dword ptr [ebp+8],ecx
31:
32:       return x ;
00401080   mov         eax,dword ptr [ebp+8]
33:
34:   }
00401083   pop         edi
00401084   pop         esi
00401085   pop         ebx
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret
16:
17:   unsigned int invert( unsigned int x , int p , int n)
18:   {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,48h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
19:       unsigned int r;
20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
21:
22:       //printf("r = %x\n",r);
23:
24:
25:       unsigned s = r & x;
00401061   mov         ecx,dword ptr [ebp-4]
00401064   and         ecx,dword ptr [ebp+8]
00401067   mov         dword ptr [ebp-8],ecx
26:       //printf("s = %x \n",s);
27:
28:       x = x | r;
0040106A   mov         edx,dword ptr [ebp+8]
0040106D   or          edx,dword ptr [ebp-4]
00401070   mov         dword ptr [ebp+8],edx
29:
30:       x = x & (~s);
00401073   mov         eax,dword ptr [ebp-8]
00401076   not         eax
00401078   mov         ecx,dword ptr [ebp+8]
0040107B   and         ecx,eax
0040107D   mov         dword ptr [ebp+8],ecx
31:
32:       return x ;
00401080   mov         eax,dword ptr [ebp+8]
33:
34:   }
00401083   pop         edi
00401084   pop         esi
00401085   pop         ebx
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret
谢谢。。。。 我先去看一下win32的基本汇编指令。。。
赵4老师 2014-04-16
  • 打赏
  • 举报
回复
16:
17:   unsigned int invert( unsigned int x , int p , int n)
18:   {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,48h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
19:       unsigned int r;
20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
21:
22:       //printf("r = %x\n",r);
23:
24:
25:       unsigned s = r & x;
00401061   mov         ecx,dword ptr [ebp-4]
00401064   and         ecx,dword ptr [ebp+8]
00401067   mov         dword ptr [ebp-8],ecx
26:       //printf("s = %x \n",s);
27:
28:       x = x | r;
0040106A   mov         edx,dword ptr [ebp+8]
0040106D   or          edx,dword ptr [ebp-4]
00401070   mov         dword ptr [ebp+8],edx
29:
30:       x = x & (~s);
00401073   mov         eax,dword ptr [ebp-8]
00401076   not         eax
00401078   mov         ecx,dword ptr [ebp+8]
0040107B   and         ecx,eax
0040107D   mov         dword ptr [ebp+8],ecx
31:
32:       return x ;
00401080   mov         eax,dword ptr [ebp+8]
33:
34:   }
00401083   pop         edi
00401084   pop         esi
00401085   pop         ebx
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret
16:
17:   unsigned int invert( unsigned int x , int p , int n)
18:   {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,48h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
19:       unsigned int r;
20:       r = (~(~0U << n) << ( p + 1 - n));
00401049   or          eax,0FFh
0040104C   mov         ecx,dword ptr [ebp+10h]
0040104F   shl         eax,cl
00401051   not         eax
00401053   mov         ecx,dword ptr [ebp+0Ch]
00401056   add         ecx,1
00401059   sub         ecx,dword ptr [ebp+10h]
0040105C   shl         eax,cl
0040105E   mov         dword ptr [ebp-4],eax
21:
22:       //printf("r = %x\n",r);
23:
24:
25:       unsigned s = r & x;
00401061   mov         ecx,dword ptr [ebp-4]
00401064   and         ecx,dword ptr [ebp+8]
00401067   mov         dword ptr [ebp-8],ecx
26:       //printf("s = %x \n",s);
27:
28:       x = x | r;
0040106A   mov         edx,dword ptr [ebp+8]
0040106D   or          edx,dword ptr [ebp-4]
00401070   mov         dword ptr [ebp+8],edx
29:
30:       x = x & (~s);
00401073   mov         eax,dword ptr [ebp-8]
00401076   not         eax
00401078   mov         ecx,dword ptr [ebp+8]
0040107B   and         ecx,eax
0040107D   mov         dword ptr [ebp+8],ecx
31:
32:       return x ;
00401080   mov         eax,dword ptr [ebp+8]
33:
34:   }
00401083   pop         edi
00401084   pop         esi
00401085   pop         ebx
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret
赵4老师 2014-04-16
  • 打赏
  • 举报
回复
引用 4 楼 luanxia77 的回复:
楼上,你这个算什么。。。。?
人间正道是沧桑, 编程正道是汇编。
乱夏 2014-04-16
  • 打赏
  • 举报
回复
楼上,你这个算什么。。。。?
赵4老师 2014-04-16
  • 打赏
  • 举报
回复
bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
乱夏 2014-04-15
  • 打赏
  • 举报
回复
刚刚到ubuntu下测试了一下也是这样的。
乱夏 2014-04-15
  • 打赏
  • 举报
回复
刚刚用windows测试了一下也是这样的情况。现在换linux试试看。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧