藤本月季品种图片:magic C

来源:百度文库 编辑:九乡新闻网 时间:2024/04/25 10:06:56
Copyright(c) 2011 fym                        All Rights ReservedPermission is granted to copy, distribute or/and modify this documentunder the terms of GUN Free Documentation License. Version 0.1 is published by fym0121@163.com1、 /*    main.c   */   #define AA  (3)   void hello();   int main()   {     printf("in main.c   AA = %d\n",AA);     hello();     return 0;   }    /*   hello.c   */   #define AA   (5)   void hello()   {     printf("in hello.c    AA = %d\n",AA);   }   /*  end  */   $gcc -c hello.c   $gcc -c main.c   $gcc hello.o main.o   $./a.out    答案:??? 2、#include   int main()   {     const int a = 3;     int *p = (int *)&a;     *p = 100;    printf("i = %d\n",*p);    return 0;   } 答案:??? 3、#include    extern int a;   int main()   {      a = 3;      return 0;   } 答案:??? 4、#inclue    int a;   a = 3;   int main()   {       return 0;   }  答案:??? 5、//在x86上做实验      #include      #include      int main()      {         unsigned int a = 345;         printf("ntohl(a) = %d\n",ntohl(a));         printf("htonl(a) = %d\n",htonl(a));         printf("ntohl(ntohl(a)) = %d\n",ntohl(ntohl(a)));        //注意:这两个都是ntohl()          return 0;       } 答案:???分析:不管是ntohl 还是 htonl 上面的两个输出是一样的。a明明是主机序,为什么前两个输出一样呢 ?如果用16进制打出来的话这两个应该按字节倒着来到,因为从名字上来看,这两个应该是不同的函数。我开始也迷惑,思考了一会终于弄明白了,我是被他们的名字弄给忽悠了。不管是ntohl 还是 htonl  ,在x86即:小端系统上,他们的行为应该是一样的,都是将一个整数的高低字节进行颠倒。可能有人会迷惑,让我们看一下这个例子,a定义为int型345,我们把a传给ntohl,ntohl会认为这是一个网络序的,你需要把它转成主机序的,所以在x86上,它的高低字节颠倒了;我们把a传给htonl,htonl会认为这是主机序的,你需要把它转成网络序的,所以在x86上,它的高低字节也颠倒了。最终的结果是ntohl(a) 和 htonl(a) 得到相同的结果。说到底,nothl() 和 htonl() 在x86上的行为是:将一个整数的高低字节颠倒。ntohl 和 htonl 不管在x86还是在powerpc上,他们的行为都是一样的。为此我下了一个glibc的源码包(google glibc 就可以找到下载地址,记住:不要用baidu,下老外的东西还是用google来的方便快捷),用sourceinsight打开,找到了这两个函数定义的地方#ifdef __OPTIMIZE__
/* We can optimize calls to the conversion functions.  Either nothing has
   to be done or we are using directly the byte-swapping functions which
   often can be inlined.  */
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
   so these functions are all just identity.  */
# define ntohl(x) (x)
# define ntohs(x) (x)
# define htonl(x) (x)
# define htons(x) (x)
# else
#  if __BYTE_ORDER == __LITTLE_ENDIAN
#   define ntohl(x) __bswap_32 (x)
#   define ntohs(x) __bswap_16 (x)
#   define htonl(x) __bswap_32 (x)
#   define htons(x) __bswap_16 (x)
#  endif
# endif
#endif 另外在htonl.c 中uint32_t
htonl (x)
     uint32_t x;
{
#if BYTE_ORDER == BIG_ENDIAN
  return x;
#elif BYTE_ORDER == LITTLE_ENDIAN
  return __bswap_32 (x);
#else
# error "What kind of system is this?"
#endif
}
weak_alias (htonl, ntohl)
注意最下面一个定义 weak_alias(htonl,ntohl) , weak_alias被定义成一个宏,当有几个参数没看明白#  define weak_alias(name, aliasname) _weak_alias (name, aliasname)
#  define _weak_alias(name, aliasname) \
  extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));这此我最大的收获是对htonl 和 ntohl有了一个崭新的认识,另外一个就是下到了c库函数的源码包,我在这里分享了链接  6、   #include          int main()         {            char * a = NULL;            strlen(a);            return 0;          } 比较         #include          int main()         {            char * a = NULL;            int b = strlen(a);            return 0;         }这两个有什么区别? 7、const#include   //软限制
int main()
{
  char str1[] = "hello\n";
  char str2[] = "world\n";
  const char * p;
  p = str1;       //p的值可以改变
  printf("%s",p);
  p = str2;
  printf("%s",p);
}#include
int main()
{
  char str[] = "hello\n";
  const char *p = str;
  *p = '1';                             //FAULT
  return 0;
}#include
int main()
{
  const char str[] = "hello\n";
  char *p = str;
  *p = '1';                                //OK
  *str = '1'                               //FAULT
  return 0;
}分析:const char *p;意思为:将指针P限定为只读属性,即:不可以通过指针P改变指针P所指向的内容。但有两点:1、指针p本身的值可以改变,如 p = str;  2、指针p指向的内容也可以改变,但不可以通过指针p去改变,如:         char str[] = "hello";         const char * p = str;         *p = '2';                    //FAULT        str[3] = '2';                //OKconst char *p ,const限定的是*p;你不可以通过p指针去改变它所指向的地址内容,通过*p可以引用地址的内容,不可以改变地址的内容,这是为了避免当用指针去引用某个地址内容时,意外地改变了这个地址所存放的值。*P失去了做左值的机会,但其他指针并没有失去,他们依然可以改变p所指向的内容。 8、#include                  //硬限制
int main()
{
  char *str = "hello\n";
  char *p = str;
  *p = '1';                            //FAULT
  return 0 ;
}#include              //指针与数组的区别
int main()
{
  char *p1 = "123";
  char *p2 = "123";
  char *p3 = "456";
  char str1[] = "123";
  char str2[] = "456";
  printf("the address of p1    = 0x%x\n",p1);
  printf("the address of p2   ?= 0x%x\n",p2);
  printf("the address of p2    = 0x%x\n",p3);
  printf("the address of str1 ?= 0x%x\n",str1);
  printf("the address of str2  = 0x%x\n",str2);
  return 0;
} 分析:char*p = "123" 与 char str[] = "123" 的主要区别在于字符串"123"所存放的地址,第一个字符串存放在常量区,第二个字符串存放在栈区。常量区里的内容当然不可以被改变,不管指针有没有被const限定,字符串"123"永远是不会被改变的;而第二个字符串可以被改变,可以看一下上面程序的输出内容,指针与数组的地址值是不一样的。也许你还可以惊奇地发现p1 和 p2 的地址值是一样的,为什么,值一样就更能说明p1所指向的字符串本身是不可以被改变的。 9、int  A = "A"printf("A = %d\n",A);   //??? A == 65