qqjianyue代码工

砌C/C++代码
posts - 6, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2011年1月9日

/* Description of data base entry for a single host.  */
struct hostent
{
  char *h_name;            /* Official name of host.  */
  char **h_aliases;        /* Alias list.  */
  int h_addrtype;        /* Host address type.  */
  int h_length;            /* Length of address.  */
  char **h_addr_list;        /* List of addresses from name server.  */
#if defined __USE_MISC || defined __USE_GNU
# define    h_addr    h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};

/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;            /* Port number.  */
    struct in_addr sin_addr;        /* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
               __SOCKADDR_COMMON_SIZE -
               sizeof (in_port_t) -
               sizeof (struct in_addr)];
  };

/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };

Get ip string:
char* getIpStr(const char* domainName){
    struct hostent *hp;
    struct in_addr in;
    hp=gethostbyname(domainName);
    memcpy(&in.s_addr, hp->h_addr,4);
    return inet_ntoa(in);
}



posted @ 2011-01-09 16:42 Qzi 阅读(377) | 评论 (0)编辑 收藏

2009年1月11日

第一:什么是可变参数
int printf(const char* format, ...);
看到printf的定义大家就知道了,只有一个固定的const char*参数,后面的都是不定长的参数列表了。

第二:自己写一个可变参数函数
1.参数形参方式,跟printf类似,第一个为固定参数,后面的用...代替;
2.包含stdarg.h头文件,因为需要用到几个里面定义的宏;
void va_start(va_list arg_ptr, prev_param);
type va_arg(va_list arg_ptr, type);
void va_end(va_list arg_ptr);
va是variable argument可变参数的意思。
3.函数里面定义一个va_list类型的变量,它是存储参数地址的指针,因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。
4.用va_start宏初始化3中定义的va_list类型变量,
5.用va_arg宏获得下一个参数的值
6.设定结束条件。
例子程序:
 1#include<stdio.h>
 2#include<stdarg.h>        //required by variable argument list
 3
 4void simple_va_function(int start, ){
 5    va_list arg_ptr;
 6    int nArgValue = start;
 7    int nArgCount = 0;        //count of arguments
 8    va_start(arg_ptr, start);    //to obtain beginning address of variable arguments base on the given arguemnt
 9    do{
10        nArgCount++;
11        printf("The %d argument is %d.\n", nArgCount, nArgValue);
12        nArgValue = va_arg(arg_ptr, int);
13    }
while(nArgValue != -1);
14    va_end(arg_ptr);
15    return;
16}

17
18int main(){
19    simple_va_function(1234-1);    //need to set a flag to specify the end of argument list
20    return 0;
21}

第三:可变参数的编译器实现原理,这几个宏的实现。
首先列出stdarg.h里面的宏定义(注意这个宏定义与硬件平台和编译器有关,这里是VC6的宏定义):
typedef char *  va_list;
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap)      ( ap = (va_list)0 )
其中va_list被定为一般指针,有些机器使用void*,有些使用char*,反正都可以啦。
_INTSZEOF(n)是考虑了内存对齐后的变量占用空间,自己考虑一下,代进去小于4字节的类型进去算一下,就知道在这个平台上(32位机),内存对齐到4个字节。
va_start就是求得第一个可变参数的地址
va_arg是求的下一个可变参数的地址存的值
va_end只是简单地将指针置零

第四:小结
1.标准C库的中的三个宏的作用只是用来确定可变参数列表中每个参数的内存地址,编译器是不知道参数的实际数目的。
2.在实际应用的代码中,程序员必须自己考虑确定参数数目的办法
   1)在固定参数设定标志,例如printf的实现,有多少个%号则表明后面多少个参数
   2)多设置一个可变参数标识参数列表结束
3.实现可变参数的要点就是想办法取得每个参数的地址,取得地址的办法由以下几个因素决定:
①函数栈的生长方向
②参数的入栈顺序
③CPU的对齐方式
④内存地址的表达方式,用void*表示一般地址还是char*
结合源代码,我们可以看出va_list的实现是由④决定的,_INTSIZEOF(n)的引入则是由③决定的,他和①②又一起决定了va_start的实现,最后va_end的存在则是良好编程风格的体现,将不再使用的指针设为NULL,这样可以防止以后的误操作。

posted @ 2009-01-11 11:24 Qzi 阅读(891) | 评论 (0)编辑 收藏

2008年10月24日

写得比较乱,小菜一名,都是自己做得不好或者理解不好的题目总结。

/Files/jianyue/cpp.rar

posted @ 2008-10-24 16:29 Qzi 阅读(268) | 评论 (0)编辑 收藏

     摘要: C语言学习之变量存储

C语言中对变量的说明包括两方面的内容:变量类型以及变量的存储类型。变量类型如:int(整形),char(字符型)是用来说明变量所占用的内存空间的大小。变量存储类型用来说明变量的作用范围。

C语言的变量存储类有:自动类、寄存器类、静态类和外部类。  阅读全文

posted @ 2008-10-24 15:20 Qzi 阅读(826) | 评论 (0)编辑 收藏

2008年10月20日

sizeof详解,非常完整
http://career.javaeye.com/blog/194299

特别要注意的是:struct 与 class 的sizeof要考虑内存对齐而消耗的空间

posted @ 2008-10-20 02:34 Qzi 阅读(320) | 评论 (0)编辑 收藏

2008年10月19日

const char与char const相同,都是都表示标识一个char的变量不能改变它的值,例如:
const char a = 'a'; //a变量就只能够是'a'了,不能再改变它的值

const char* p1 = &a;
char* const p2 = &a;
*p1不能改变;
p2不能改变;
主要看待究竟const是否修饰*号(即*号是否在const后面)就行,如果修饰,则代表是*p是常量,如果不修饰则p是常量。
所以char const * p与const char*相同,因为*号在const后面。

注意:常量规定是在编译时候检测的,运行时候是可以改变的,例如上面的*p1为常量,但是可以赋值p1=&b,其中b='b';那么*p1的值也会变成'b'了。

posted @ 2008-10-19 21:48 Qzi 阅读(792) | 评论 (0)编辑 收藏