100分求解简单C语言题(瞌睡虫请进来下)
To 瞌睡虫:
你好强... 怎么什么东西都懂...
有两个问题想请教你下
1)以下是你的回复, 请举例说明如何实现, 程序代码或者具体实现步骤或者我该买些什么书或查些什么资料?
jixingzhong(瞌睡虫·星辰)
3)如何实现“运行C语言写的DOS程序时不显示DOS窗口”
N 多办法,
比如传入启动参数中定义不显示运行窗口;
或者写成 系统服务
2)我很喜欢编程, 就是很菜, 希望你能说些你的经验, 谢谢!
其他问题:
1)stdcall与cdecl,从网上查了下,是关于压栈,入栈顺序不同。我是C语言初学者
,平常调用函数,都没象他们讲得那么麻烦,谁能简单详细解释下,最好有例子,越
简单越好理解越好。
2)用C语言实现不定参数的函数的例子, 越简单越好。
3)求C语言函数的详细用法的相关书或者介绍
4)free()函数所释放内存的多少?是不是一次用malloc()申请多少内存,用free()所释放的就和malloc()分配时的字节等价?
5)详细介绍下stdout, stdin, stderr, 是不是每个程序执行时, 都会打开这3个文件?
6)缓冲区溢出问题, 比如 char str[8], 我程序该怎么写,防止程序读取的数据超过7个字节呢?(要程序)
8)清空输入缓冲区的问题
网上有人说用fflush(stdin)和rewind(stdin)清除是C语言的一个误区,原因在于标
准中并没有这两个做出定义,而只是特定编译器的特定功能,影响可移植性。我的问
题是,那到底用什么方式清楚缓冲区的内容,最合适呢?
9)如何查看键盘缓冲区的信息?
比如
char str[80];
scanf( "%s ", str);
我在调试时, 怎么看到(stdin)输入的信息呢
10)书上两题程序题
用C语言编程实现求下面两个方程组的a, b的近似解(越近似越好)(两个程序分开写, 不然我怕到时看不懂) "^ "表示平方
1)7.9 = a * (b ^ 70)
47.25 = a * (b ^ 160)
2)80 = a * (b ^ 7.9)
150 = a * (b ^ 38.85)
[解决办法]
1)stdcall与cdecl的最大的区别:stdcall——函数退出时自己负责清除堆栈,cdecl——函数退出时由调用它的函数来清空堆栈。
2)printf和scanf就是最好的例子。
3)这个太多了,百度一下。
4)是的,动态内存分配时实际上会花空间来记录分配了多少字节(因此真正分配的要比实际得到的大一点),因此free时会释放malloc申请的所有内存,而不用你操心。你可以仔细想想,这也是realloc函数能够存在的基础(它怎么知道是大了还是小了?)。
5)stdout, stdin, stderr是三个特殊的FILE指针,并不是每个程序执行时都会打开这3个文件,比如程序只进行一系列操作,运行完了就完了,而不涉及到IO,你可以想象成那些根本不需要#include <stdio.h> 的程序。只有涉及这三个文件的IO操作时才会打开这些文件,只不过我们编写的程序一般都会有这样的IO操作,也就是说一般都会#include <stdio.h> ,因此它们一般都会被打开。
6)这个要靠好的编程习惯了,记得操作数组时一定要有变量来表明你现在指向的是数组第几个元素,在判断中要记得随时和数组长度做比较。另外,对于字符串库函数,避免使用strcpy,strcat等等,尽量使用strncpy、strncat等等,这样可以减少缓冲区溢出的发生。
7)似乎没有7)
8)fflush(stdin)可以清空输入缓冲区,而rewind(stdin)是将文件指针定位到文件开头,似乎并不能清空输入缓冲区。fflush和rewind是ANSI C的标准函数,应该不会影响可移植性。
9)可以通过setbuf或者setvbuf函数来实现。
10)b^70表示b的70次方?可以将上下两式相比,消去a,得到一个关于b的幂的方程。然后对两边取对数(log或log10函数,记得用换底公式),最后可以得到log(b)=x的形式,再将两边作为指数,以e或10为底运算(exp或pow函数),得到b,则a易得。
[解决办法]
555555555
多谢楼上这么体谅 ....
这些问题,
其实都算比较基本的问题,
楼主多看看书,多写写代码, 自然就知道了 ...
[解决办法]
1)
函数调用约定;
函数调用约定是函数调用者和被调用的函数体之间关于参数传递、返回值传递、堆栈清除、寄存器使用的一种约定;
它是需要二进制级别兼容的强约定,函数调用者和函数体如果使用不同的调用约定,将可能造成程序执行错误,必须把它看作是函数声明的一部分;
常见的函数调用约定;
VC6中的函数调用约定;
调用约定 堆栈清除 参数传递
__cdecl 调用者 从右到左,通过堆栈传递
__stdcall 函数体 从右到左,通过堆栈传递
__fastcall 函数体 从右到左,优先使用寄存器(ECX,EDX),然后使用堆栈
thiscall 函数体 this指针默认通过ECX传递,其它参数从右到左入栈
__cdecl是C\C++的默认调用约定; VC的调用约定中并没有thiscall这个关键字,它是类成员函数默认调用约定;
C\C++中的main(或wmain)函数的调用约定必须是__cdecl,不允许更改;
默认调用约定一般能够通过编译器设置进行更改,如果你的代码依赖于调用约定,请明确指出需要使用的调用约定;
Delphi6中的函数调用约定;
调用约定 堆栈清除 参数传递
register 函数体 从左到右,优先使用寄存器(EAX,EDX,ECX),然后使用堆栈
pascal 函数体 从左到右,通过堆栈传递
cdecl 调用者 从右到左,通过堆栈传递(与C\C++默认调用约定兼容)
stdcall 函数体 从右到左,通过堆栈传递(与VC中的__stdcall兼容)
safecall 函数体 从右到左,通过堆栈传递(同stdcall)
Delphi中的默认调用约定是register,它也是我认为最有效率的一种调用方式,而cdecl是我认为综合效率最差的一种调用方式;
VC中的__fastcall调用约定一般比register效率稍差一些;
C++Builder6中的函数调用约定;
调用约定 堆栈清除 参数传递
__fastcall 函数体 从左到右,优先使用寄存器(EAX,EDX,ECX),然后使用堆栈 (兼容Delphi的register)
(register与__fastcall等同)
__pascal 函数体 从左到右,通过堆栈传递
__cdecl 调用者 从右到左,通过堆栈传递(与C\C++默认调用约定兼容)
__stdcall 函数体 从右到左,通过堆栈传递(与VC中的__stdcall兼容)
__msfastcall 函数体 从右到左,优先使用寄存器(ECX,EDX),然后使用堆栈(兼容VC的__fastcall)
常见的函数调用约定中,只有cdecl约定需要调用者来清除堆栈;
C\C++中的函数支持参数数目不定的参数列表,比如printf函数;由于函数体不知道调用者在堆栈中压入了多少参数,
所以函数体不能方便的知道应该怎样清除堆栈,那么最好的办法就是把清除堆栈的责任交给调用者;
这应该就是cdecl调用约定存在的原因吧;
VB一般使用的是stdcall调用约定;(ps:有更强的保证吗)
Windows的API中,一般使用的是stdcall约定;(ps: 有更强的保证吗)
建议在不同语言间的调用中(如DLL)最好采用stdcall调用约定,因为它在语言间兼容性支持最好;
2)
void _printf(char *format, ...)
{
va_list argptr;
va_start (argptr, format);
while (*format)
{
switch (*format)
{
case 's ':
printf( "Printing a string:%s\n ",(char *) va_arg(argptr, char *));
break;
case 'c ':
printf( "Printing a char:%c\n ", (char) va_arg(argptr,int));
break;
case 'd ':
printf( "Printing a integer:%d\n ", (int) va_arg(argptr,int));
break;
}
format++;
}
va_end(argptr);
}
void main()
{
_printf( "sd ", "adfasdf ", 1);
system( "pause ");
}
3)
http://zbdsq.bokee.com/465836.html
http://man.chinaunix.net/develop/c&c++/linux_c/default.htm
你还可以找到电子书,叫 C 函数大全
4)是的free和malloc是配对的,分配多少释放多少,但是在你做了越界
的时候,free报错,比如
char* pc = (char*)malloc(sizeof(char) * 3);
strcpy(pc, "12345 ");
free(pc);
5) 是
stdin, stdout, stderr,这三个文件流默认是用ascii方式打开的
6) 用带n的字符传系列函数,比如 用 strncpy 不用 strcpy 用 strncat 不用 strcat
8) 用 fflush(stdin) 或者 flushall() 就可以了
9)
// 比如你输入 aa 12313 1313 1313
// 那么 s 得到的是aa
// str 则是整个缓冲区的内容
void main()
{
char s[128];
scanf( "%s ", s);
fflush(stdin);
int c = stdin-> _bufsiz;// 这个是缓冲区大小
char* str = stdin-> _ptr; // 这个就是你要的缓冲区内容
system( "pause ");
}
10)