第一篇:c语言中可变参数函数设计方案
c语言中可变参数函数的设计
c语言中可变参数函数的设计
c语言中可变参数函数的设计
-----最近想好好学学这个, 先把网上搜集得资料贴上.========================
参数可变函数的实现(上)CSDN Blog推出文章指数概念,文章指数是对Blog文章综合评分后推算出的,综合评分项分别是该文章的点击量,回复次数,被网摘收录数量,文章长度和文章类型;满分100,每月更新一次。
此文献给如我一般还在探索C语言之路的朋友们。
注:本文中测试程序的编译环境为win2000和VC6.0 缘起:
作为一个程序员,我没有写过参数可变的函数,我相信大部分朋友也没有涉及过,或者我的境界层次太低了。那么缘何我要去揭这一层面纱呢?因为好奇!
我是个思维具有极大惰性的人,曾经识得参数可变函数,也懒得去深究,但是它的三点(函数声明时参数列表中的“…”)却深刻的映入/ 20 了我的记忆里,而且是带着若干个闪耀的问号。可是就在昨天,在拜读某君的高论时,它再一次出现了。我的资质真的是不太够,因为某君在谈到它时只是给出了
破题:
但凡所谓“实现”都是从没有到有的过程,但是我只是想去解惑它的实现,因为它原本就是好端端的正为成千上万的程序员们服务。
还是从我们熟悉的printf说起:
如果你是个C语言的程序员,无论你是初学者还是高高手,对于printf都不会陌生,甚至你已经用了无数次了。我已经说过我是个有极大惰性的人,所以每次用printf都是照本宣科,规规矩矩的按教科书上说的做,从来没有问过一个为什么,这就是所谓的“熟视无睹”吧。
其实,printf函数是一个典型的参数可变的函数。在保证它的第一个参数是字符串的条件下,你可以输任意数量任意合法类型的参数。只要你在第一个字符串参数中使用了对应的格式化字符串,你就可以输出正确的值。这难道不是件很有趣的事吗?那它是怎么做到的?
1,首先,怎么得到参数的值。对于一般的函数,我们可以通过参数对应在参数列表里的标识符来得到。但是参数可变函数那些可变的参数是没有参数标识符的,它只有“…”,所以通过标识符来得到是不可能的,我们只有另辟途径。/ 20
我们知道函数调用时都会分配栈空间,而函数调用机制中的栈结构如下图所示:
|......|
------------------
| 参数2 |
------------------
| 参数1 |
------------------
| 返回地址 |
------------------
|调用函数运行状态|
------------------
可见,参数是连续存储在栈里面的,那么也就是说,我们只要得到可变参数的前一个参数的地址,就可以通过指针访问到那些可变参数。但是怎么样得到可变参数的前一个参数的地址呢?不知道你注意到没有,参数可变函数在可变参数之前必有一个参数是固定的,并使用标识符,而且通常被声明为char*类型,printf函数也不例外。这样的话,我们就可以通过这个参数对应的标识符来得到地址,从而访问其他参数变得可能。我们可以写一个测试程序来试一下: / 20
#include
void va_test(char* fmt,...);//参数可变的函数声明
void main(){
int a=1,c=55;
char b='b';
va_test(“",a,b,c);//用四个参数做测试
}
void va_test(char* fmt,...)//参数可变的函数定义,注意第一个参数为char* fmt {
char *p=NULL;/ 20
p=(char *)&fmt;//注意不是指向fmt,而是指向&fmt,并且强制转化为char *,以便一个一个字节访问
for(int i = 0;i<16;i++)//16是通过计算的值(参数个数*4个字节),只是为了测试,暂且将就一下
{
printf(”%.4d “,*p);//输出p指针指向地址的值
p++;} }
编译运行的结果为
0056 0000 0066 0000 | 0001 0000 0000 0000 | 0098 0000 0000 0000 | 0055 0000 0000 0000
由运行结果可见,通过这样方式可以逐一获得可变参数的值。
至于为什么通常被声明为char*类型,我们慢慢看来。
2,怎样确定参数类型和数量 / 20
通过上述的方式,我们首先解决了取得可变参数值的问题,但是对于一个参数,值很重要,其类型同样举足轻重,而对于一个函数来讲参数个数也非常重要,否则就会产生了一系列的麻烦来。通过访问存储参数的栈空间,我们并不能得到关于类型的任何信息和参数个数的任何信息。我想你应该想到了——使用char *参数。Printf函数就是这样实现的,它把后面的可变参数类型都放到了char *指向的字符数组里,并通过%来标识以便与其它的字符相区别,从而确定了参数类型也确定了参数个数。其实,用何种方式来到达这样的效果取决于函数的实现。比如说,定义一个函数,预知它的可变参数类型都是int,那么固定参数完全可以用int类型来替换char*类型,因为只要得到参数个数就可以了。
3,言归正传
我想到了这里,大概的轮廓已经呈现出来了。本来想就此作罢的(我的惰性使然),但是一想到如果不具实用性便可能是一堆废物,枉费我打了这么些字,决定还是继续下去。
我是比较抵制用那些不明所以的宏定义的,所以在上面的阐述里一点都没有涉及定义在
好了,我们来看一下那些宏定义。
打开
1)typedef char * va_list;
2)#define _INTSIZEOF(n)((sizeof(n)+ sizeof(int)1))
3)#define va_start(ap,v)(ap =(va_list)&v + _INTSIZEOF(v))
4)#define va_arg(ap,t)(*(t *)((ap += _INTSIZEOF(t))sizeof(type)))
其中,argp的类型是char *。
如果你想用va_arg从可变参数列表中提取出函数指针类型的参数,例如
int(*)(),则va_arg(argp, int(*)())被扩展为:
(*(int(*)()*)(((argp)+= sizeof(int(*)()))-sizeof(int(*)())))
显然,(int(*)()*)是无意义的。
解决这个问题的办法是将函数指针用typedef定义成一个独立的数据类型,例如:
typedef int(*funcptr)(); / 20
这时候再调用va_arg(argp, funcptr)将被扩展为:
(*(funcptr *)(((argp)+= sizeof(funcptr))-sizeof(funcptr)))
这样就可以通过编译检查了。
问题:可变长参数的获取
有这样一个具有可变长参数的函数,其中有下列代码用来获取类型为float的实参:
va_arg(argp, float);
这样做可以吗?
答案与分析:
不可以。在可变长参数中,应用的是”加宽“原则。也就是float类型被扩展成double;char, short被扩展成int。因此,如果你要去可变长参数列表中原来为float类型的参数,需要用va_arg(argp, double)。对char和short类型的则用va_arg(argp, int)。
问题:定义可变长参数的一个限制
为什么我的编译器不允许我定义如下的函数,也就是可变长参数,但是没有任何的固定参数?
int f(...)
{ / 20
...}
答案与分析:
不可以。这是ANSI C 所要求的,你至少得定义一个固定参数。
这个参数将被传递给va_start(),然后用va_arg()和va_end()来确定所有实际调用时可变长参数的类型和值。
第一篇
C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为:
int printf(const char* format,...);
它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(用三个点“…”做参数占位符),实际调用时可以有以下的形式:
printf(”%d“,i);printf(”%s“,s);printf(”the number is %d ,string is:%s“, i, s);
一个简单的可变参数的C函数
先看例子程序。该函数至少有一个整数参数,其后占位符…,表示后面参数的个数不定。在这个例子里,所有的输入参数必须都是整/ 20 数,函数的功能只是打印所有参数的值。函数代码如下:
//示例代码1:可变参数函数的使用 #include ”stdio.h“ #include ”stdarg.h“ void simple_va_fun(int start,...){ va_list arg_ptr;int nArgValue =start;int nArgCout=”0“;//可变参数的数目
va_start(arg_ptr,start);//以固定参数的地址为起点确定变参的内存起始地址。do { ++nArgCout;printf(”the %d th arg: %d",nArgCout,nArgValue);//输出各参数的值
nArgValue = va_arg(arg_ptr,int);//得到下一个可变参数的值
} while(nArgValue!=-1);return;} int main(int argc, char* argv[]){ simple_va_fun(100,-1);simple_va_fun(100,200,-1);return 0;}
下面解释一下这些代码。从这个函数的实现可以看到,我们使用可变参数应该有以下步骤: / 20
⑴由于在程序中将用到以下这些宏: 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 / 20
第二篇:C语言中的输入输出函数总结
putchar():把变量中的一个字符常量输出到显示器屏幕上;getchar();从键盘上输入一个字符常量,此常量就是该函数的值;printf();把键盘中的各类数据,加以格式控制输出到显示器屏幕上;scanf();从键盘上输入各类数据,并存放到程序变量中;puts():把数组变量中的一个字符串常量输出到显示器屏幕上;gets():从键盘上输入一个字符串常量并放到程序的数组中.sscanf();从一个字符串中提取各类数据。putchar()输出一个字符
getchar()输入流中获取一个字符 例如:
char c = getchar();putchar(c);格式化输入输出scanf()和printf()是最有用的,所以重点讲一下。printf(): 一般形式: printf(“格式控制”.输出列表);eg : printf(“a=%d,b=%f,c=%cn”,a,b,c);1;格式控制.格式控制是用双引号括起来的字符串,也称“转换控制字符串”,它包含以下两部分信息.格式说明:由“%”和格式字符组成,如%d,%f,%c,他的作用是把输出数据转换为指定格式输出,格式的说明总是由“%”字符开始的.普通字符:需要原样输出的字符,或者是一些有特殊含义的字符,如n,t。2;输出列表
就是需要输出的一些数据,也可以是表达式,如果在函数中需要输出多个变量或表达式,则要用逗号隔开.一些特殊字符的输出:
单引号,双引号,和反斜杠的输出在前面加转义字符”” 如:”’” , “”” , “”
%的输出用两个连在一起的%%,即printf(“%%”);
常用的格式说明如下: 格式字符
d 以十进制形式输出带符号整数(正数不输出符号)o 以八进制形式输出无符号整数(不输出前缀O)x 以十六进制形式输出无符号整数(不输出前缀OX)u 以十进制形式输出无符号整数 f 以小数形式输出单精度实数 lf 以小数形式输出双精度实数
e 以指数形式输出单、双精度实数
g 以%f%e中较短的输出宽度输出单、双精度实数 c 输出单个字符 s 输出字符串
这里强调一下:网上很多文章都说f 和lf是一样的,即不管单精度,双精度浮点数,都可以用f, 但我在POJ上做过测试,输出Double时用f确实也可以,但读入时,用f就报WA,所以大家如果对Double进行读写的话,都用lf吧。
说到Double,再啰嗦一句,建议大家要用到浮点数时都用Double,不要用float,因为在很多情况下,float精度不够会导致WA。
特殊:
对64位整数的输入输出,在POJ上的C++环境下(即VC),64位整数是: __int64(注意int前面是两个下划线)输入输出格式为”%I64d”.在G++环境下(即Dev C++)64位整数是 long long 输入输出格式为”%lld”.输出宽度
用十进制整数来表示输出的最少位数。注意若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。
精度
精度格式符以“.”开头,后跟十进制整数。意义是:如果输出数字,则表示小数的位数;如果输出的是字符,则表示输出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。
标志格式字符
-结果左对齐,右边填空格
+ 输出符号(正号或负号)空格输出值为正时冠以空格,为负时冠以负号 例如:
double c=24212345.24232;printf(“%020.4”);表示输出精确到小数点后4位,输出占20位,若有空余的位补0.scanf:
scanf的很多用法都是和printf对应的,故不再赘述。
说一下scanf一个特别好用的地方,就是可以滤去一些不想要的东西。举例说明如下:
比如输入为日期 yyyy-mm-dd,就可以这样写: int year,moth,day;scanf(“%d-%d-%d”,&year,&moth,&day);再比如:
scanf(“%3d %*3d %2d”,&m,&n);输入113 118 69回车(系统将113赋予m,将69赋予n,因为*号表示跳过它相应的数据所以118不赋予任何变量)puts()用的不多,且基本都能用printf()代替,故不再多说。gets()是从输入流中获取一行字符串放入字符数组中: char in[100];gets(in);大家可能最容易出错的地方就是字符串的输入,所以强调一下: 能进行字符,字符串输入的有:
getchar(), scanf(“%c”);scanf(“%s”), gets()
其中getchar()和 scanf(“%c”)的功能是一样的。
需要注意的是,这两个函数读入的是输入流中当前位置的字符,比如:
scanf(“%d”,&n);c = getchar();假设输入 67/(假设“/”代表回车),则第一个scanf读入一个整数67后,当前输入流的位置是67之后,即指向回车符,所以第二个getchar()读入的就是一个回车符了,即 c = ‘n’。
同样,gets()也是从当前位置读入一行字符串。比如:
scanf(“%d”,&n);gets(str);此时读入字符数组中的字符串就是“n” 了
所以通常在用scanf读入一个非字符串的类型之后,如果要读入字符,或字符数组,都用一个额外的getchar()把回车符读掉,若后面跟的不止一个回车符,可能还有多余的空格的话,就用gets()读掉。
和以上不同的是,scanf(“%s”)读入的时候是会忽略掉空格,回车和制表符的。并且以空格,回车和制表符作为字符串结束的标志。
经常会有这样的题,输入第一行是一个整数,接下来每行的第一个是一个字符,用来表示某种操作,后面再跟一些数据,比如: 4 A 100 2 B 23 A 23 89 B 34
像这种输入就需要小心,读入字符时不要读成回车符。为了防止意外,我一般是这样处理这类输入的: char model[2];Scanf(“%d”,&n);for(„,„,„){
scanf(“%s”,model);
if(model[0] == ‘A’){ } else{ } } sscanf(): sscanf()经常用来分解字符串,功能非常强大,但很多功能都需要正则表达式的知识,所以就介绍一下最简单的几种用法,大家如果想了解更多的话,自己去网上找吧。1.char str[100],str1[100],str2[100];gets(str);sscanf(str,”%s%s”,str1,str2);
将读入的一整行字符串按空格,制表符或回车符分割成两个字符串。2 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
sscanf(“123456 ”, “%4s”, str);
对于C++的输入输出就不再详细的讲了,因为cin,cout的速度实在太慢,不推荐使用,我一般都是到万不得已时才用。
比如当你要读入字符串到string 对象中时,就只能用cin了,这时候还有一个常见的问题,就是如何将一整行字符串读入一个string 中,这就要用到getline函数了。用法为: getline(cin, str);第一个参数就是标准输入流cin,第二个参数是接收读入数据的string对象,本来还有第三个参数,是结束符的标志,但通常用它默认的就可以了,所以不用管。
注意区分这个getline和cin.getline的区别: cin.getline的用法如下: char str[20];cin.getline(str,20);表示从读入的一行字符串中,取最多20各字符放入字符数组str中,注意此处的str是字符数组,而上面的str是string对象。
另外需要注意的是,千万不要把cout和printf混用,因为cout是带缓冲的而printf不带,所以会使得输出的数据顺序混乱。
第三篇:对于C语言中的scanf函数的使用问题总结
Scanf函数总结
对于C语言中的scanf函数的小结
对于scanf函数的作用大家应该都知道吧。在任何一本C语言的教材中都有过介绍,它的一般形式是(格式控制,地址表列)
我今天想说说使用这个scanf函数的时候,应该注意哪些问题吧。
1.scanf函数中的格式控制应该是变量名的地址,而不是变量名,例如a和b为整形变量,如果写成scanf(“%d%d”,a,b);就会出错的,应该将这个,a,b改成&a,&b;(表示地址)2我们都知道C语言中的字符串是存放到字符数组中的,如果我们定义了一个字符数组,如char a[20];我们想把字符串输入到这个字符数组中通常有两种方式,第一种.逐个字符输入,采用for循环的形式。第二种,直接输入字符串的形式,用格式控制符%s.第一种我们这样输入,for(i=0;i<=19;i++){ } 第二种我们用这种方式输入 Scanf(“%s”,a);注意第二种这种形式,我们没有加&,这是为什么呢,这是 Scanf(“%c”,&a[i]);
Scanf函数总结
因为,C语言中把这个数组名当做该数组的起始地址。但是这种数组仅限于字符数组,不要企图,利用数值型数组的名。来整体输入,一个数值型的数组,这就是大错误了,比如这样写是不正确的 Int a[10];Scanf(“%d”,a);数值型数组的输入只能采用上面的第一种方法。3对于指针问题,大家需要注意一点,指针就是地址,这是在任何条件下都成立的,(请允许我极端一点),比方看下面的例子。Char *p;Char a[20];P=a;For(i=0;i<20;i++,p++){ } 这是一个采用指针变量输入数据的例子,这里的指针变量p在for循环之前就指向了这个数组a,也就是指向了数组的首元素,也就是是说指针变量p里存放的是,数组首元素的地址,所以在用这个scanf函数进行输出时,指针变量的前方就不用再加取地址符号了。Scanf(“%c”,p);
Scanf函数总结
4.这个问题是整个scanf函数使用过程中最容易出错的一个地方。就是关于用scanf函数在用“%c”格式声明输入字符的时候,是最容易出错的一个地方。一点一点进行,下面请看一个简单的例子: 看下面的一个程序,(1)
#include
} 我们想要输入三个整数,输入的时候我们要注意了,这里的scanf函数中的格式控制是三个连续的%d,除了格式声明以外中间没有任何其他的字符,这个时候我们输入数据应该加入空格,否则执行不了。1 2 3(1,2之间有空格,2,3之间有空格,(具体原因会在例题2中阐明)加入其他符号也是不可以的)
(2)经过第一道的例题,似乎让我明白了这样的一个规律,如果中间都是除了格式声明以外中间没有任何其他的字符,int a,b,c;scanf(“%d%d%d”,&a,&b,&c);printf(“%d%d%dn”,a,b,c);return 0;
Scanf函数总结
那我就可以用空格,来隔开我的数据了。看看下面的例题 #include
} 我的输入还是仿照上面,进行截图如下所示 char a,b,c;scanf(“%c%c%c”,&a,&b,&c);printf(“%c%c%cn”,a,b,c);return 0;
我们发现输出并不是我们想象的那样,而是出现了错误,下面我们来解释一下原因,因为我们原来输入的位数值型的数据,所以我们要区分数值的个数,以及位数,比方我想输入
Scanf函数总结 234 456这三个数,我要是连续的把这8个数输入进去,计算机也无法区分,这到底是几个数,所以我们用空格加以区分,这样计算机遇到空格就知道这个数值型的数已经输入完毕了(这是例题1中我们为什么加空格的原因),但是为什么在例题2中我还是这样做,就不可以了呢,这是因为我们现在输入的是字符型数据,而且字符型数据不是像数值型数据那样,有几位数字,字符型的数据只有一位,所以你输入一位数据他就给一个变量,所以不需要像数值型的数据那样隔开了,所以我们直接输入三个连续的字母asd就可以了,就不用空格分开了,如果我们输入a空格s空格d,那么他就会默认的把前三个字符送给三个变量了,也就是a空格s(因为空格也是一个字符)。(3)下面大家看一下这道例题。
//下面程序很简单,就是输入两个数和一个运算符号,#include“stdio.h” void main(){
int;float z,x,y;char cc;printf(“please enter date:n”);scanf(“%f%c%f”,&x,&cc,&y);
Scanf函数总结
} if(cc=='+')z=x+y;if(cc=='-')z=x-y;if(cc=='*')z=x*y;if(cc=='/')z=x/y;printf(“%fn”,z);我们连续输入三个1+2 结果输出3,截图如下
这里要注意的是,输入1之后不能有空格,因为下面是一个字符型数据,输入字符型数据之后,就可以有空格了,因为
Scanf函数总结
后面是一个数值型数据。(所以按照这种方式输入也可以 1+ 2)(4),如果在“格式控制字符串中”除了格式声明还有其它字符,则在输入数据的时候,在对应的位置上应该输入与这些字符相同的字符。#include
} 我们在输入数据的时候应该这样输入,1,2,3 我要讲的内容就要讲完了,下面和大家说说在输入这个数据的时候,尽量加入,分隔,scanf(“%d,%d,%d”,&a,&b,&c);这样不容易出错,如果什么符号也不用直接这样的话scanf(“%d%d%d”,&a,&b,&c);大家一定要注意我上面说的三个例子。int a,b,c;scanf(“%d,%d,%d”,&a,&b,&c);printf(“%d%d%dn”,a,b,c);return 0;7
第四篇:浅析英语语言中的性别歧视
浅析英语语言中的性别歧视
摘要:性别歧视是现代社会一个被广泛关注的问题。语言性别歧视也是性别歧视中很重要的一部分,并且语言歧视也得到了很多社会语言学家的重视与关注。语言是一面能够反映社会文化与人们心理活动的镜子。因此从社会语言学角度去分析英语语言中的性别歧视以及其成因是很有必要的。
关键词:社会语言学;性别歧视;英语语言
Abstract: Sexism is an important issue in the whole society.Sexism language is a part of sexism which has attracted social linguiticians and psychologists’ attention.Language is a mirror of society which reflects people’s thought and culture.It is meaningful to study the phenomenon and reasons of sexist language from the perspective of social linguistics.Key words: social linguistics;sexism;English language 引言
语言一直以来都是社会的一面镜子,反映着社会中人们的思想以及社会基本的价值观。在二十世纪早期,性别不同而导致的语言差异开始引起学者的关注。但是语言性别歧视却直到二十世纪六十年代才开始被研究。语言性别歧视是指从形式、意义以及语言的其他方面对于女性的歧视。语言是社会的产物,反应了特定时期社会的文化、习俗以及思想模式。因此,语言性别歧视也同样反应了整个社会的对于女性的歧视的价值观。社会中男女不平等现象也反应了社会的发展进程与发展中出现的问题。因此,语言性别歧视的研究对于社会的发展以及社会整体价值观的形成有着很关键的意义。
著名语言学家罗宾·莱考夫在语言特征以及使用方面有所研究,并且她指出女性语言包括描述女性的语言以及女性使用的语言,这些语言在功能上就反应了对于女性身份的歧视。1922年,丹麦语言学家奥托·叶斯帕森从词汇以及句法方面来描述了语言上的性别不同。二十世纪六十年代末期,许多学者开始尝试从社会语言学角度分析女性语言。十年后,许多大学也开设了性别语言与行为课程。许多著名学者在二十世纪80年代将语言性别歧视进行了更深层次的研究。语言性别歧视已经成为了学者们广泛研究的课题之一。
一、语言性别歧视的表现以及成因 1.语言性别歧视的表现
语言性别歧视首先体现在词语的形成以及使用方面。男性和女性是生来平等的,并且彼此都需要互相尊重。在英语中,词语的使用方面分为男性词语和女性词语。一些词语只能用来形容男性而不能用于形容女性。并且一些只用于形容女性的词语是对女性有歧视的。从词语的形成上来说,英语中的许多既可以描述女性又可以男性的词汇都是以男性词汇作为词根的。相反的,只能描绘女性的词语都是从男性词语中变化来的。比如prince-princess,host-hostess,hero-heroine等。还有一种词语,描述女性的词语是专门被标记出的,而男性词语却没有任何标记。例如,ambassador可以同时表示男性大使和女性大使,但是ambassadress却只能用来描述女性大使。同样的例子还有poet和poetess。这些现象都可以体现出人们将男性语言作为标准和社会的主体语言,而女性词汇则是男性词汇的从属或者演变。
在英语中,当我们不确定性别或不必要确定性别的时候,我们通常都用he来指代任何人。并且man这个词也可以代表某一类特定的人,比如mankind,human,spokesman,congressman等。这个现象也体现了男性在社会中的主导地位。同样,很多描绘女性的词语可以反映出女性在家庭和社会中的地位。例如,housewife和earth-mother这两个词就可以表现出女性的生活是以洗衣做饭等家务为中心的。Secretary,nurse,stenographer这些词语可以体现出女性拥有自己的职业但是收入水平非常低,如果有男性从事护士或秘书职业,我们一定会特意标记出male nurse和male secretary。人们通常会把高收入职业同男性联系在一起,例如医生、律师等。但是如果女性从事这种行业,人们就会特意标记处woman doctor和woman doctor。这些词语的分类就体现出人们意识里认为男性就应该从事高收入以及挑战性的工作,而女性只能从事低收入以及社会地位较低的工作。
在词语的顺序方面也能体现出语言性别歧视。在英语中,当我们需要同时提到男性和女性时,我们通常会说“ladies and gentlemen”,“bride and groom”,西方人认为“女士优先”是他们的理解。但是在这种情况下,人们认为女性是弱势的性别,是需要被照顾的。大多数的情况,人们更习惯把男性词语放在女性词语之前,来表现女性的从属地位,例如man and woman, male and female, husband and wife, Adam and Eve等。这种语言习惯也体现出了社会在语言方面对于女性的歧视。
从社会语言学的角度看,语言是作为一种表达思想的工具,并且是随着人类社会的发展而发展的。从语义学的研究角度看,有很多词语是赞扬男性却贬低女性的。男性词语通常是褒义词而女性词语通常是贬义词。例如,wench这个词语最早是用来形容乡村姑娘,但是现在却用来形容妓女。根据统计,英语中有超过500个词可以表示妓女,但是只有65个词可以用来表示男妓。
这种类型的歧视还有很多。例如bachelor和spinster都可以形容未婚者,但是bachelor用来形容男性未婚者,未婚的原因是因为男性很独立并且享受单身状态。但是spinster用来形容很难找到结婚对象的女性未婚者。我们可以发现这些词语都反映了男性和女性社会地位的不同。
2.语言性别歧视的成因
语言是文化的一部分并且能够反映社会整体文化。语言是被文化影响的,但是同时他也反映了文化中的民族特征。语言也可以表现出人们的思想,生活方式以及思维模式。所以语言中的性别歧视也体现了社会中的男性女性不平等的现象。这种现象是由特定的社会价值观和思维模式决定的。语言是没有感情色彩的,但是语言使用者会根据他们的价值观以及观点去给语言加上颜色。语言中的性别歧视不是一天就形成的。
社会环境是影响语言性别歧视形成的因素之一。语言是社会团体在环境中习得的。性别歧视语言进入恶性循环是由于西方社会传统思想观念造成的,对于女性的歧视似乎已经变成了文化的一部分。西方社会对女性的能力、价值观和行为都是有偏见的,而这种偏见就形成了固定的价值观和文化模式。这种性别歧视的社会成见是不公平的,他反映了社会的稳定发展是建立在牺牲女性利益的基础上的。这就意味着女性在政治、社会、教育以及经济方面都是不平等的。
从历史的发展方面看,在西方社会,女性的社会地位是低于男性的。在语言的发展过程中,女性语言被认为应该是礼貌、保守、服从以及温柔的。而相反的,男性语言就更直接、勇敢和坚持。在西方,宗教也是影响语言的重大因素。在圣经中,女性就属于从属地位。上帝首先创造了男性亚当,而当亚当需要帮助的时候,上帝才创造了女性夏娃,夏娃也是由亚当的一根肋骨创造的。这也就意为着,女性是从男性从产生出来的。因此语言也把男性语言放在了首位。
二、避免性别歧视语言的措施
性别歧视语言在污染着我们的语言环境并且影响了我们的交流,甚至会导致矛盾和冲突。所以在一些正式场合需要规避性别歧视语言,使人与人之间的交流更加的有效。如果我们都在避免使用性别歧视语言,人们之间交流会更有效,表达会更清楚,语言也会变得更优美。更重要的是,避免使用性别歧视语言可以促使社会中的性别平等。西方国家在避免使用性别歧视语言方面给予了高度的关注。
当没有必要指明性别的时候,我们应该避免使用性别形容词,例如lady doctor, female lawyer等。性别形容词会暗示人们这样的工作职能由男性或女性来担任。这也是一种性别歧视。我们也应该避免使用Mrs.和Miss,而使用Ms,当我们不知道一位女性的婚姻状况时,我们最好使用Ms。在正式场合我们也应避免使用性别歧视语言,可以使用一些委婉语来表达一些可能会贬低女性的词语,这样可以避免交流中的尴尬。
英语中的一些以男性词语为词缀的复合词是用来表示职业的,我们可以使用一些中性词来避免在职业称谓方面的性别歧视语言,例如“消防员”,我们可以用firefighter而不是fireman。同样的例子还有news reporter和 newsman,police officer 和 policeman。
三、结论
性别歧视语言不论是在语言学还是在整个社会中都是一个重要的议题。这方面的研究吸引着越来越多的学者。跟男性相比,女性的社会地位是略低的。语言并不能影响女性的社会地位,因为性别歧视是整个社会的问题,他反映着歧视女性的思想已经在人们心中根深蒂固,成为了历史文化的一部分。我们只有从根源处消除人们对于女性歧视的这一思想,性别歧视语言现象才有可能被规避。人们应该意识到,给及女性平等的社会地位,真正实现两性平等才是最重要的。
参考文献: 白解红著.性别语言文化与语用研究[M].长沙:湖南教育出版社,2000 ,9122 3 杨永林著.社会语言学---功能性别称谓篇[M].上海:上海外语教育出版社,2004 ,201122 5 赵蓉晖著.语言与性别---口语的社会语言学研究[M].上海:上海外语教育出版社,2003 ,41-53
第五篇:浅谈英语语言中的性别歧视
陈 贺
(宿州学院 外国语学院,安徽 宿州 234000)
摘 要:从英语语言出发,分析其中的性别歧视现象:视男性用语为主体,女性用语为变体或附属;两性词语在词义上不对称;词汇排序上遵循“男先女后”的原则。接着从劳动性别分工、宗教思想、性别角色社会化三个角度对之进行原因解读。这为当前的性别语言研究提供一定的参考和启示。
关键词:性别;劳动分工;宗教;角色社会化
中图分类号:H0-05 文献标识码:A 文章编号:1673-2596(2011)09-0209-03 性别歧视是以性别为基础而产生的一种歧视现象,它可以表现为男性对女性的歧视,也可以表现为女性对男性的歧视。《朗曼英语词典》定义性别歧视为:“以性别为基础的歧视,尤其是男性对女性的偏见。”《美国传统词典》关于“性别歧视”的解释是:“一类性别成员对另一类性别成员,尤其是男性对女性的歧视。”因此,“性别歧视”通常是对女性的歧视,是社会对女性的偏见[1]1。语言是人们交流的重要工具,是人类思想的重要载体,折射了社会的文化习俗与价值观念。通过语言,可以管窥到人们的性别观念。几千年来,英语国家人们一直生活在父权制体系的桎梏之下,对女性怀有深深的歧视。这一性别态度,在英语语言中有着深刻的印证。那么,本文将揭示英语语言中的性别歧视现象,并对之进行原因探讨。
一、英语语言中的性别歧视
(一)以男性为规范
以男性为规范是语言性别歧视的重要表现之一[1]1。表现在具体语言事实上,即语言视男性用语为主体,将女性用语当作变体或附属[2]。这一特征在英语语言中具有鲜明的体现。
(二)词义上的不对称
其次,与男性相比,英语中与女性相关的贬义词数量众多。据Dale Spencer统计,英语中表达“性生活放荡”的词语,至少有220个是与女性相关,而只有20个左右与男性有关。另据研究,英语中表示“在性生活上乱七八糟的女子”的词多达320个,几乎所有关于女性的词都有具有贬义,而一部分关于男性的词则含有“哪个男子不风流的”容忍之意。
再次,男女词义演变上不对称。在长期的语言交际过程中,男性词语向褒义方向演变,而女性词语则有恶化的趋势。King(国王)、lord(老爷)、master(主人)、father(父亲),在现代英语中,只要把他们的首字母大写,就可以分别用来指“上帝”、“基督”、“主或神”。与男性褒化相对,女性词语往往增加了贬义。Tart一词原指一种小糕饼,后用作亲昵的称呼年轻女子,后来演变为“富于性感的女子”,随后又转化为“对道德不甚介意,作风随便的女子”,而现在又指“在街上拉客的女子”。
(三)语序上的歧视
二、英语中性别歧视产生的原因
语言依赖于社会,是人类社会的产物。不同的社会形态,会产生不同的语言体系。语言的形成与一定的社会文化、风俗习惯、价值观念等,有着密切的关系。因此,英语语言中的性别歧视现象,与英美国家男女不平等的社会现实不无关联。而这种不平等的社会现实,与以下三个层面紧密相关:
(一)劳动性别分工
马克思主义女性主义认为男女不平等源自劳动性别分工[3]67。劳动性别分工是人类最主要的社会分工形式,以生理性和社会性别为基础,社教化将男性和女性分别规范在以性别特质界定的工作岗位[3]68。依照性别分配劳动是人类最早的劳动分工方式,它是人类寻找到的最有效的组织社会生活的方法[4]。在西方农业社会里,劳动性别分工模式主要与性别天然差异和当时的生产力发展水平有关:
首先,在某种程度来讲,劳动性别分工是自然秩序的结果[5]。根据达尔文理论,男性与女性具有一定的生理差异,两性各有独特的身体特征。总体而言,在体格方面,男性身材高大,肌肉发达,身体健壮;女性则身材较小,身体比较纤弱。在性格方面,男性精力旺盛,富有冒险精神;女性则比较文静、温柔、随和。由于这些差异,男性似乎更加适合从事与生产有关的劳动,如养殖、农耕等。而女性则适宜从事与人的再生产有关的劳动,如生育、抚育和家务劳动等。
其次,劳动性别分工形式与生产力的发展水平有直接的关系。在原始社会,生产力水平低下,男性与女性必须一起劳动,才能维持生活:女性采摘水果和种子,男性狩猎打鱼。由于当时劳动工具落后,采摘是人们主要的生活来源。于是,在一定时期内,人类社会是母系氏族社会。当人类步入农业社会后,生产力水平有了极大改善,社会的主要经济支柱转为农耕等体力劳动。由于身体上的差异,男性身体更加强壮,更适合从事这些劳动。于是,人类社会逐渐形成了新的劳动性别分工,男性主要从事农业生产等,女性则局限在家庭范围之内。
因此,在西方农业社会劳动性别分工模式里,男性是社会生产的主体。在家庭和公共空间的划分过程中,财产关系成为决定性别秩序的基本决定因素[6]。于是,长期以来,在经济上占主导地位的男性主宰着社会的一切,垄断了政治、经济、法律等公共领域;女性则处于从属地位,被禁锢在家庭范围内。这一社会特征反映在语言层面上,表现为语言中存在大量的歧视现象。
(二)宗教思想
基督教是西方文化的基石,在西方国家文明发展中起到举足轻重的作用,对社会意识形态的形成具有至关重要的意义。但是,基督教教义以男性为主体,到处充斥着对女性的排斥和歧视。在这种宗教思想体系下,男性有着无与伦比的社会地位,他们是按照神权来进行统治,按照神权来规范女性的一切[7]22。在《圣经》中,上帝创造的第一个人类是男性。上帝赋予他无限的权利,制造了世界万物,按照他的意愿命名,归他统治。为了不让他感到孤独,上帝又取其一根肋骨,创造了一个女性,来帮助他,陪伴他。于是,女性往往被看作是男性的附属品。因此,在社会关系中,男性支配社会的方方面面,而女性只能处于从属的地位:
你们作妻子的,当服从自己的丈夫,如同顺服主。因为丈夫是妻子的头,如同基督是教会的头,他又是教会全体的救主。教会怎样顺服基督,妻子也要怎样凡事顺服丈夫。(《以弗所书》第五章)
而且,女性在《圣经》中常被看作万恶之源。在伊甸园中,夏娃受到蛇的诱惑,偷吃了智慧树上的苹果,并引诱亚当也偷吃了禁果。于是,他们被上帝驱赶出伊甸园,被罚永远生活在苦难之中。因此,人们认为夏娃对人类的堕落负有不可推卸的责任。同时,在《圣经》中,无论是《旧约》还是《新约》,女性常常被忽略,鲜被提及。希伯来历史上涌现出许多杰出的优秀女性,但《圣经》对她们的记载极其简略。例如:女先知米利安,与摩西、亚伦有着同等重要的地位,不仅是女性的领导者,而且还曾经救过摩西,在以色列人走出埃及的过程中起到了无可替代的作用。但是,《圣经》对其描写很少。
与之相比,男性则几乎垄断了《圣经》的所有章节。《圣经》中几乎所有重要的人物都是男性。上帝称为我们的“父亲”,上帝的的后代是儿子耶稣。引领犹太人走出埃及的摩西,犹太人的祖先亚伯拉罕,以及耶稣的十三个门徒,全部都是男性。而且,《圣经》对其中的男性描写非常详尽,不吝笔墨。
总之,《圣经》是一本站在男性立场上,为男性书写的宗教典籍。作为基督教的重要经典,《圣经》影响广泛,其所散播的性别观念渗透到社会的方方面面,使得西方社会奠定了男尊女卑的格调,使得英语语言存在严重的性别歧视色彩。
(三)性别角色社会化
性别角色社会化指个体在社会生活中逐渐学会按照自己的性别角色规范行事的过程[6]76。每个人一出生甚至在出生前,就可能被身边的人们按照社会性别的固定模式来对待和教育。儿童从父母、教师、同辈、媒体、社会等多方面得到性别角色的信息,并受其影响,从中学习到怎样做符合社会规范的“男孩”或“女孩”,“男人”或“女人”。而且,性别角色社会化是一个持续的过程,会贯穿于每个人的一生。
性别角色社会化是自动的无意识的过程,但同时又是每个人积极参与的过程。在性别角色形成过程中,人们在很大程度上是不会意识到文化如何影响两性,并对不遵从社会期望者进行惩罚[8]169。但是,性别角色社会化并不是一个完全被动的过程。在社会性别期望的驱使下,每个人会不由自主地按照社会期望进行性别角色社会化。根据心理学家的说法,“每个人不是被动的接受性别角色社会化,而是按照他对自我、社会期望、行为规范的理解,积极的参与这一个过程”[8]169。
同时,在性别角色社会化过程中,一系列因素,如生产方式、政治制度、社会等级划分等,会影响到性别角色的形成[9]。换句话说,社会性别角色的形成,会受一定社会背景的影响,如:语言、媒体、文学、宗教、教育机构、家庭等。每一个人都会参照他的生长环境,如家庭、教育材料等,来逐渐形成适当的性别角色。
几千年来,英美国家是典型的父权制社会。男性垄断着社会的政治、经济、文化等公共领域,女性的社会活动范围则局限在家庭。在当时的社会意识形态下,女性与男性相比天生具有缺陷,是不完整的人。而且,女性是“人类堕落”和“人类原罪”的根源。
于是,在这样的社会环境下,女性一出生就被灌输相应的性别观念,并逐步的进行性别角色社会化。她们渐渐的接受其性别角色定位,认为女性是低卑的,一生应依附于男性,并遵从相应的道德规范,承担起家庭范围内的社会职责。这使得女性认同社会中的性别不平等,对语言中性别歧视现象熟视无睹,从而在一定程度上使得英语语言中的性别歧视一直延续下去。
三、结语
语言的产生离不开一定的社会环境。因此,英语语言中的性别歧视不仅仅是一种语言现象,它是英美国家男女不平等的社会现实的反映。随着三次妇女运动的高涨,英美国家女权主义者积极投身到语言改革与规划活动中来,英语中的性别歧视现象得到一定改观。但是,由于历史、文化、社会等因素,英语中的性别歧视并未完全消除。只有进一步深化性别研究,提高女性社会地位,完全实现男女平等,才能使语言真正的平等。