/*
* Copyright (C) 1998-2006
panhuachun@hotmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*/
#include
#include
#include
/*
1.语句表达式 和Typeof
GNU C 把包含在括号中的复合语句看做是个表达式,称为语句表达式,他能出
目前所有允许表达式的地方,你能在语句表达式中使用循环、局部变量等,原本
只能在复合语句中使用。.复合语句的最后一个语句应该是个表达式,他的值将成
为这个语句表达式的值。
#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x
利用 typeof 能定义更通用的宏,不必事先知道参数的类型,
typeof(x) 表示 x 的值类型,例如:
*/
#define min(x,y) ({ const typeof(x) _x = (x); const typeof(y) _y = (y); (void) (&_x == &_y);_x
//2.可变参数宏 能看博客上的文章
#define pr_debug(fmt,arg...) printf(fmt,##arg)
#define err(...) fprintf(stderr, __VA_ARGS__)//可变参数宏
#define err1(...) fprintf(stderr, ##__VA_ARGS__)
#define TEST(ARGTERM...) printf("test is "#ARGTERM" \n")
#define PASTE(a, b) a##b
/*
3.零长度数组
GNU C 允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用。
结构的最后一个元素定义为零长度数组,他不占结构的空间。在标准 C 中则需要
定义数组长度为 1,分配时计算对象大小比较复杂。
*/
struct test {
int inode;
char name[0];
};
//5.标号元素
struct print_t
{
void (*print1)(char * is);
void (*print2)(char * is);
} ;
void print_string1(char *is)
{
printf("%s\n",is);
}
void print_string2(char *is)
{
printf("%s\n",is);
}
/*
4.声明的特别属性
GNU C 允许声明函数、变量和类型的特别属性,以便手工的代码优化和更仔细的代
码检查。要指定一个声明的属性,在声明后写
__attribute__ (( ATTRIBUTE ))。
__attribute__能设置函数属性(Function Attribute)、变量属性
(Variable Attribute)和类型属性(Type Attribute)。
其中 ATTRIBUTE 是属性说明,多个属性以逗号分隔。GNU C 支持十几个属性,这
里介绍最常用的:
(1) noreturn
属性 noreturn 用于函数,表示该函数从不返回。这能让编译器生成稍微优化的
代码,最重要的是能消除不必要的警告信息比如未初使化的变量
(2)* format (ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)
属性 format 用于函数,表示该函数使用 printf, scanf 或 strftime 风格的参
数,使用这类函数最容易犯的错误是格式串和参数不匹配,指定 format 属性能
让编译器根据格式串检查参数类型。
(3)* unused
属性 unused 用于函数和变量,表示该函数或变量可能不使用,这个属性能避免
编译器产生警告信息。
(4)* section ("section-name")
属性 section 用于函数和变量,通常编译器将函数放在 .text 节,变量放在
.data 或 .bss 节,使用 section 属性,能让编译器将函数或变量放在指定的节中
(5)aligned (alignment)
该属性规定变量或结构体成员的最小的对齐格式,以字节为单位。例如:
int x __attribute__ ((aligned (16))) = 0;
编译器将以16字节(注意是字节byte不是位bit)对齐的方式分配一个变量。
cleanup,common,nocommon,deprecated,mode,section,shared,tls_model,
transparent_union,unused,vector_size,weak,dllimport,dlexport等
更多请看attribute详解
*/
// 最小字节对齐 1+8+1+1+4 =15个字节 ;attribute 对char 无效
struct aligned_test
{
char a ;
int x[2] ;
char b;
char c;
int d ;
} __attribute__ ((packed));
// 默认排列 4 + 8 + 4(b ,c)+4 = 20个字节 //4字节对其
struct no_aligned_test
{
char a;
int x[2];
char b;
char c;
int d;
};
//8+8+(1+1+4=8) = 24个字节
struct nn_aligned_test
{
char a ;
int x[2];
char b;
char c;
int d ;
} __attribute__ ((aligned (8))) ;
__attribute__ (( noreturn)) void go_out(void)
{
exit(0);
}
main(int argc, char *argv[])
{
const int i1=40;
const int * p1;
int i2=9;
int * pi2;
const int * const p3=&i1;
p1=&i2;
/*
char mystr[]={"xyz"};
char *myp=mystr;
printf("%s\n",mystr);
myp++;
//mystr++//数组名字不能加
printf("%s\n",myp);
*/
char *str[]={"abcdefg","123456"};
char **pp;
pp=str;
printf("%s\n",str[0]);
*pp++; //*(pp++);
//printf("%s\n",*pp++);
printf("%s\n",*pp);
/*
5.标号元素赋值
将结构my_print的
元素 print1初始化为 print_string1,
元素 print2初始化为 print_string2,
这是 GNU C 扩展中最佳的特性之一,当结构的定义变化以至元素的偏移改动时,这种初始化方法仍然
确保已知元素的正确性。对于未出目前初始化中的元素,其初值为 0
*/
struct print_t my_print = {
print1: print_string1,
print2: print_string2,
};
int i=10,j=20;
char *PASTE(str,1) ="string";
err ("i=%d\n", i);
err("hello\n");
err1("i=%d\n", i);
err1("hello\n");
TEST(123);
printf("%d\n",min(i,j));
printf("%s\n",PASTE(str,1));
printf("sizeof(struct test)=%d\n",sizeof(struct test));
printf("sizeof(struct aligned_test)=%d\n",sizeof(struct aligned_test));
printf("sizeof(struct no_aligned_test)=%d\n",sizeof(struct no_aligned_test));
printf("sizeof(struct n_aligned_test)=%d\n",sizeof(struct nn_aligned_test));
my_print.print1("eeeeeeeeeeeeeeeee") ;
/*
6.Case 范围
GNU C 允许在一个 case 标号中指定一个连续范围的值,例如:
case ’0’ ... ’9’:
相当于
case ’0’: case ’1’: case ’2’: case ’3’: case ’4’:
case ’5’: case ’6’: case ’7’: case ’8’: case ’9’:
*/
switch(’5’){
case ’0’ ... ’9’: printf("0-9\n");; break;
case ’a’ ... ’f’: printf("a-f\n"); break;
case ’A’ ... ’F’: printf("A-F\n");break;
}
go_out();
}
阅读(743) | 评论(0) | 转发(0) |