您的位置:首页 > 编程语言 > C语言/C++

C语言学习中遇到的问题与解决方法

2018-01-24 23:53 375 查看
1.static作用

static修饰变量指该变量空间独立于函数中的auto变量或栈变量,static变量空间在内存中的静态区内分配。

(1)修饰局部变量

         局部变量用static修饰时,该变量便存放在静态数据区,生命周期直至整个程序执行结束。虽然其生命周期和存储空间发生了变化,但作用域没变。对于静态局部变量,若没有进行初始化,整型变量系统会自动对其赋值为0,对于字符数组自动赋值为“\0”。

(2)修饰全局变量

     用static对全局变量进行修饰改变了作用域的范围,由原来的整个工程可见变为

本源文件可见

2. extern作用

extern指当前变量或函数不是在本源文件内声明的,是外部变量或外部函数。extern可以修饰变量和函数,该变量或函数在其他地方被定义,在这里声明使用它:多个c源文件的编译是独立的,使用编译器只判断变量名或函数名是否一致;等到链接时,多个源文件编译后的.o文件链接成一个目标文件,若有一个以上源文件对同一个变量进行了初始化则报错。

(1)在任何函数体声明或定义变量时,编译器选择初始化的那个,若没有初始化则

任选其中一个作为定义,但加extern肯定是声明;若不想让其他源文件链接,则需使用static。

在函数体内声明使用其他源文件中定义的变量时必须使用extern,因为在函数体内默认为局部变量。

(2)函数默认是外部的,如果不想让其他源文件链接到,在函数前加static。(注:

为提高程序的可读性,最好不要省略extern。在用extern声明变量时,可以不指定类型。在写程序时要注意外部函数的参数类型、参数个数和返回值类型保持一致。)

3. const作用

(1)关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。

(2)通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。

(3)合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。

4.  volatile作用

volatile修饰的变量表示该变量的值很容易由于外部因素发生改变,请求编译器在每次对变量进行访问时去内存里读取。

5.typedef作用

为一种数据类型定义一个新名字,包括内部数据类型和自定义数据类型。目的为:(1)给变量一个易记且意义明确的新名字;(2)简化复杂类型声明。

6.  枚举

     使用方法:enum_type_name类型是对一个变量取值范围的限定,花括号内为取值范围。enum变量类型可以给其中的常量符号赋值,若不赋值则从被赋初值的那个常量开始依次加1;若都没有赋值,从0开始依次递增1。

     与#define宏的区别:

(1)#define宏常量在预编译阶段进行简单替换,枚举常量在编译时确定其值。

(2)在编译器里,可调试枚举常量,但不能调试宏常量。

(3)枚举可一次定义大量相关常量,而#define宏一次只能定义一个。

7.const的作用

const是C语言的一种关键字,起受保护,防止以外的变动的作用。可以修饰变量,参数,返回值甚至函数体,const可以提高程序的健壮性。

a.const修饰参数。const只能修饰输入参数。

(1)、如果输入参数是指针型的,用const修饰可以防止指针被意外修改。

(2)、如果参数采用值传递的方式,无需const,因为函数自动产生临时变量复制该参数。

(3)、非内部数据类型的参数,需要临时对象复制参数,而临时对象的构造,析构,复制较为费时,因此建议采用前加const的引用方式传递非内部数据类型。而内部数据类型无需引用传递。

b.const修饰函数返回值。

(1)、函数返回const指针,表示该指针不能被改动,只能把该指针赋给const修饰的同类型指针变量。

(2)、函数返回值为值传递,函数会把返回值赋给外部临时变量,用const无意义!不管是内部还是非内部数据类型。

(3)、函数采用引用方式返回的场合不多,只出现在类的赋值函数中,目的是为了实现链式表达。

c.const+成员函数。任何不修改数据成员的函数都应该声明为const类型,如果const成员函数修改了数据成员或者调用了其他函数修改数据成员,编译器都将报错!

8.typedef和#define的区别

可以把typedef看成是一种“封装”类型----在声明之后不能再往里面增加别的东西。它和宏的区别体现在两个方面

a.可以用其他类型说明符对宏类型名进行扩展,但对typedef所定义的类型名却不能这样做。

#define peach int 

unsigned peach i;   没问题

typedef int peach;

unsigned peach i;   语法错误

b.连续几个变量的声明中,用typedef定义的类型能够保证声明中所有的变量均为同一种类型,而用#define定义的类型无法保证

#define int_ptr int *

int_ptr chalk, cheese;

经过宏扩展

int *chalk, cheese;

chalk是一个指针,cheese是一个整型。

typedef int* int_ptr;

int_ptr chalk,cheese;

chalk,cheese都为整型指针

9.运算符分类

C语言一共有34种运算符,10种运算类型:算术运算符(+、-、*、/、%)、关系运算符(>、>=、==、!=、<、<=)、位运算符(>>、<<、==、!=、<、<=)、逻辑运算符(!、||、&&)、条件运算符、(?:)指针运算符(&、*)、赋值运算符(=)、逗号运算符(,)、求字节运算符(sizeof)、强制类型转换运算符((类型名))、其他(下标[]、分量、函数);若按参与运算的对象个数,C语言运算符可分为单目运算符(如!)、双目运算符(如+、-)和三目运算符(如?:)

10.位运算的分类和用法

a. 按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。

例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。

    按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为0000000011111111)。

main(){

int a=9,b=5,c;

c=a&b;

printf("a=%d/nb=%d/nc=%d/n",a,b,c);

}

b. 按位或运算 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。

例如:9|5可写算式如下: 00001001|00000101

00001101 (十进制为13)可见9|5=13

main(){

int a=9,b=5,c;

c=a|b;

printf("a=%d/nb=%d/nc=%d/n",a,b,c);

}

c. 按位异或运算 按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如9^5可写成算式如下: 00001001^00000101 00001100 (十进制为12)

main(){

int a=9;

a=a^15;

printf("a=%d/n",a);

}

d.左移和右移

左移运算符“<<”是双目运算符。其功能是把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0.

右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。但注意:对于有符号数,在右移是,符号位将随同移动,当为正数时,最高位补0;而为负数时,符号位为1,最高位是补0或是补1取决于编译系统的规定。

10.条件运算符和条件表达式的使用

条件运算符为?和:,它是一个三目运算符,即有三个参与运算的量。由条件运算符组成条件表达式的一般形式:表达式1?表达式2:表达式3

求值规则:当表达式1为真,则表达式2作为条件表达式的值,否则以表达式3作为条件表达式的值。

还要注意以下几点:

a.条件运算符的运算优先级低于关系运算符和算术运算符,但高于赋值符。

b.条件运算符“?”和“:”是一对运算符,不能分开单独使用。

c.条件运算符的结合方向是自右至左。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: