首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

看到几奇怪的C语言代码,小弟不太懂,熟悉C语言的同志帮帮忙解决办法

2012-03-31 
看到几奇怪的C语言代码,小弟不太懂,熟悉C语言的同志帮帮忙char **audio_codec_listNULL // 一个*是指针,

看到几奇怪的C语言代码,小弟不太懂,熟悉C语言的同志帮帮忙
char **audio_codec_list=NULL; // 一个*是指针,两个*是什么意思?
////
  if(mask&INITED_DEMUXER){
  inited_flags&=~INITED_DEMUXER;//这句不太懂是什么意思?
  current_module="free_demuxer";
  if(mpctx->demuxer){
mpctx->stream=mpctx->demuxer->stream;
free_demuxer(mpctx->demuxer);
  }
  mpctx->demuxer=NULL;
  }
/////
void load_per_file_config (m_config_t* conf, const char *const file)///定义函数,两个const什么意思?

/////
static unsigned int c_localcount_notsc()
{
  struct timeval tv;
  unsigned limit=~0; ///对0求非,啥意思?
  limit/=1000000;
  gettimeofday(&tv, 0);
  return limit*tv.tv_usec;
}
////
static inline void dbgprintf(char* fmt, ...)////...是什么参数?
////
static void c_longcount_tsc(long long* z)
{
  __asm__ __volatile__
(
"pushl %%ebx\n\t"
"movl %%eax, %%ebx\n\t"
"rdtsc\n\t"
"movl %%eax, 0(%%ebx)\n\t"
"movl %%edx, 4(%%ebx)\n\t"
"popl %%ebx\n\t"
::"a"(z) ///C中内嵌汇编,AT&T格式,但不明白什么意思?
:"edx"
);
}


[解决办法]
char **audio_codec_list=NULL; // 一个*是指针,两个*是什么意思?
=========》指向指针的指针,就是说这个变量是一个指针,这个指针指向的是一个指针变量。


const char *const file)///定义函数,两个const什么意思? 
==========》 2个const,第一个const修饰的是char*,表示的是这个指针不可修改,第二个修饰的是const char*指向的内容,表示指向的内容不可以修改。
[解决办法]
char **audio_codec_list=NULL; // 一个*是指针,两个*是什么意思? 
//二级指针,也就是指针的指针,指针指向的又是一指针

void load_per_file_config (m_config_t* conf, const char *const file)///定义函数,两个const什么意思? 
//第一个const修饰指针指向的内容,第二个const修饰指针本身

unsigned limit=~0; ///对0求非,啥意思? 
//各位区非,0变1,1变0

static inline void dbgprintf(char* fmt, ...)////...是什么参数?
//可变参数,参数的个数随意添加,只要满足函数内部要求

::"a"(z) ///C中内嵌汇编,AT&T格式,但不明白什么意思?
//AT&T汇编的内容,规定还多着呢,在gcc内联汇编中也有介绍
[解决办法]
规定一个sizeof(int)是2,但是在我的电脑上怎么是4啊?
//这个和目标机器字长有关系,不能定的
[解决办法]
最后一项纠正一下,::"a"(z)是gcc为在内联汇编中方便访问C程序的变量而引入的,形式为__asm__("asm statements" : outputs : inputs : registers-modified); ,具体参考编译器的文档
[解决办法]
给你贴一段别人写有关内联汇编基本语法的文字

内嵌汇编语法如下: 
__asm__(汇编语句模板: 输出部分: 输入部分: 破坏描述部分) 
共四个部分:汇编语句模板,输出部分,输入部分,破坏描述部分,各部分使用“:”格开,汇编语句模板必不可少,其他三部分可选,如果使用了后面的部分,而前面部分为空,也需要用“:”格开,相应部分内容为空。例如: 
__asm__ __volatile__("cli": : :"memory") 

1、汇编语句模板 
汇编语句模板由汇编语句序列组成,语句之间使用“;”、“\n”或“\n\t”分开。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多10个,名称如下:%0,%1,…,%9。指令中使用占位符表示的操作数,总被视为long型(4个字节),但对其施加的操作根据指令可以是字或者字节,当把操作数当作字或者字节使用时,默认为低字或者低字节。对字节操作可以显式的指明是低字节还是次字节。方法是在%和序号之间插入一个字母,“b”代表低字节,“h”代表高字节,例如:%h1。 

2、输出部分 
输出部分描述输出操作数,不同的操作数描述符之间用逗号格开,每个操作数描述符由限定字符串和C 语言变量组成。每个输出操作数的限定字符串必须包含“=”表示他是一个输出操作数。 
例: 
__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x) ) 
描述符字符串表示对该变量的限制条件,这样GCC 就可以根据这些条件决定如何分配寄存器,如何产生必要的代码处理指令操作数与C表达式或C变量之间的联系。 

3、输入部分 
输入部分描述输入操作数,不同的操作数描述符之间使用逗号格开,每个操作数描述符由限定字符串和C语言表达式或者C语言变量组成。 
例1 : 
__asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt)); 
例二(bitops.h): 
Static __inline__ void __set_bit(int nr, volatile void * addr) 


__asm__( 
"btsl %1,%0" 
:"=m" (ADDR) 
:"Ir" (nr)); 


后例功能是将(*addr)的第nr位设为1。第一个占位符%0与C 语言变量ADDR对应,第二个占位符%1与C语言变量nr对应。因此上面的汇编语句代码与下面的伪代码等价:btsl nr, ADDR,该指令的两个操作数不能全是内存变量,因此将nr的限定字符串指定为“Ir”,将nr 与立即数或者寄存器相关联,这样两个操作数中只有ADDR为内存变量。 

4、限制字符 
4.1、限制字符列表 
限制字符有很多种,有些是与特定体系结构相关,此处仅列出常用的限定字符和i386中可能用到的一些常用的限定符。它们的作用是指示编译器如何处理其后的C语言变量与指令操作数之间的关系。 

分类 限定符 描述 
通用寄存器 “a” 将输入变量放入eax 
这里有一个问题:假设eax已经被使用,那怎么办? 
其实很简单:因为GCC 知道eax 已经被使用,它在这段汇编代码 
的起始处插入一条语句pushl %eax,将eax 内容保存到堆栈,然 
后在这段代码结束处再增加一条语句popl %eax,恢复eax的内容 
“b” 将输入变量放入ebx 
“c” 将输入变量放入ecx 
“d” 将输入变量放入edx 
“s” 将输入变量放入esi 
“d” 将输入变量放入edi 
“q” 将输入变量放入eax,ebx,ecx,edx中的一个 
“r” 将输入变量放入通用寄存器,也就是eax,ebx,ecx, 
edx,esi,edi中的一个 
“A” 把eax和edx合成一个64 位的寄存器(use long longs) 

内存 “m” 内存变量 
“o” 操作数为内存变量,但是其寻址方式是偏移量类型, 
也即是基址寻址,或者是基址加变址寻址 
“V” 操作数为内存变量,但寻址方式不是偏移量类型 
“ ” 操作数为内存变量,但寻址方式为自动增量 
“p” 操作数是一个合法的内存地址(指针) 

寄存器或内存 “g” 将输入变量放入eax,ebx,ecx,edx中的一个 
或者作为内存变量 
“X” 操作数可以是任何类型 

立即数 
“I” 0-31之间的立即数(用于32位移位指令) 
“J” 0-63之间的立即数(用于64位移位指令) 
“N” 0-255之间的立即数(用于out指令) 
“i” 立即数 
“n” 立即数,有些系统不支持除字以外的立即数, 
这些系统应该使用“n”而不是“i” 

匹配 “ 0 ”, 表示用它限制的操作数与某个指定的操作数匹配, 
“1” ... 也即该操作数就是指定的那个操作数,例如“0” 
“9” 去描述“%1”操作数,那么“%1”引用的其实就 
是“%0”操作数,注意作为限定符字母的0-9 与 
指令中的“%0”-“%9”的区别,前者描述操作数, 
后者代表操作数。 
& 该输出操作数不能使用过和输入操作数相同的寄存器 

操作数类型 “=” 操作数在指令中是只写的(输出操作数) 
“+” 操作数在指令中是读写类型的(输入输出操作数) 

浮点数 “f” 浮点寄存器 
“t” 第一个浮点寄存器 
“u” 第二个浮点寄存器 
“G” 标准的80387浮点常数 
% 该操作数可以和下一个操作数交换位置 
例如addl的两个操作数可以交换顺序 
(当然两个操作数都不能是立即数) 
# 部分注释,从该字符到其后的逗号之间所有字母被忽略 
* 表示如果选用寄存器,则其后的字母被忽略 

5、破坏描述部分 
破坏描述符用于通知编译器我们使用了哪些寄存器或内存,由逗号格开的字符串组成,每个字符串描述一种情况,一般是寄存器名;除寄存器外还有“memory”。例如:“%eax”,“%ebx”,“memory”等。
[解决办法]

探讨
我跑去面试的时候,问我sizeof(int)是多少,我说4,结果错了,郁闷,我明明测试是4嘛

[解决办法]
探讨
引用:
我跑去面试的时候,问我sizeof(int)是多少,我说4,结果错了,郁闷,我明明测试是4嘛


32位机是4,16位是2
sizeof(char)永远是1,sizeof(指针)永远是4

[解决办法]
探讨
引用:
我跑去面试的时候,问我sizeof(int)是多少,我说4,结果错了,郁闷,我明明测试是4嘛


32位机是4,16位是2
sizeof(char)永远是1,sizeof(指针)永远是4

[解决办法]
char **audio_codec_list=NULL; //指向char类型指针变量的指针。 
const char *const file//一个指向固定内容的固定de不可修改的指针。
[解决办法]
探讨
我跑去面试的时候,问我sizeof(int)是多少,我说4,结果错了,郁闷,我明明测试是4嘛

[解决办法]
unsigned limit=~0; ///对0求非,啥意思? 

在嵌入式里面由于目标机器的字长是不固定的 因此必须对0取反 来获取 0xfffff这样的数值
[解决办法]
探讨
我跑去面试的时候,问我sizeof(int)是多少,我说4,结果错了,郁闷,我明明测试是4嘛

[解决办法]
unsigned limit=~0; ///对0求非,啥意思? 这样的写发可移植性很好把所有位都变1


[解决办法]
指针变量的值的当然是地址,在32位机器上地址总线当然是32位的,也就是说内存地址都是32位=4字节。所以sizeof(指针)的值为4.可以预见在以后的64位机器上sizeof(指针)的值为8.
[解决办法]
inited_flags&=~INITED_DEMUXER;//这句不太懂是什么意思? 

是想将inited_flags 某位置0,其他位不变:

此处INITED_DEMUXER是个宏定义,表示一个二进制数据,例如00001000
inited_flags&=~INITED_DEMUXER相当于
inited_flags = inited_flags & (~INITED_DEMUXER)
即:inited_flags & 11110111 
目的:将inited_flags 某位(例子中从右往左第4位)置0(也叫复位,清空等),并保持其他位不变

热点排行