现在的位置: 首页 > 综合 > 正文

C语言基础

2013年07月16日 ⁄ 综合 ⁄ 共 5161字 ⁄ 字号 评论关闭

C语言  变量

值传递,传递实参给形参,运算完毕不回传,为单向传递。
c语言允许声明的时候没有形参,表示传参自由,但一般为了形象表明所传参数最好写上。
行参也是局部变量,调用时分配空间。
register int a;//表示把变量放在寄存器里
volatile int a;//表示该变量随时可能因为外部原因中断或改变。

局部变量在栈里分配空间, 全局变量在内存分配空间。
静态变量可以让函数保留一些信息供下次使用。为了保留函数运算后的值供下一次调用函数使用,把变量申明为静态局部变量。

1. 全局变量和静态数据放在静态存储区,生命周期为从申请到程序退出。因此局部变量若定义为static,则存储在静态存储区,
    否则存储在函数的栈内,生命周期为本函数内。
2. 全局变量和局部变量的作用域,全局变量为从申请到整个程序结束,局部变量为从申请到本{}范围内。
3. 局部变量对全局变量的屏蔽。若在本函数内定义的变量与全局变量同名,则将全局变量屏蔽,使用时为内部定义的局部变量。
4. 定义为static类型的局部变量,再次进入该函数,可以使用保留的结果。
下面的程序可以帮助理解:
#include<stdio.h>
int a = 1;
void fun()
{
        static int a =3;
        int b = 1;
        printf("%d, %d/n", a, b);
        a++;
        b++;
}

int main()
{
        printf("%d/n", a); /* global a */
        static int a = 2;
        printf("%d/n", a); /* static a in main */
        fun(); /* static a in fun */
        fun(); /* static a in fun */
        return 0;
}

运行结果为:
1     /* 全局变量a */
2     /* 因为定义了main内的局部变量static int a,全局变量a被屏蔽,打印的为main局部变量a */
3,  1  /* 因为定义了fun内的局部变量static int a,全局变量a被屏蔽,打印的为fun内的局部变量a。 b是局部变量,打印为1 */
4,  1  /* 因为static的生命周期为整个程序,再次进入fun是a的值可以被保留,再次调用打印的值编程了3+1=4。
b因为是在栈内,函数退出后空间被释放,再次进入是重新申请的     空间,结果仍为新初始化的值1 */
*************************************************************************************************************************************

c语言 函数

显示声明用于解决函数返回被调用时返回类型不确定的问题,声明的时候行参的类型可以不写,不过最好写上。
头文件用于定义函数,形式如下:(为了避免头文件被重复包含)
————————————

#ifndef pthFILENAME_H

#define pthFILENAME_H 1;
int function(int x,int ...);
……
#else
#endif

———————————

在sanf里除空格能够跳过,其它的符号要象引号内原样输出,函数返回正确输入的个数。

printf返回输出的字符数。
c语言里对于未知返回类型的函数,默认返回int;

静态函数不允许其他文件调用。
递归函数:

所谓递归就是在函数内部调用自己。
最大公约数算法:int maxcd(int a,int b){return a==0||b==0?a+b:a=0?maxcd(b,a%b)}//算法原理就算,如果x是a和b的公约数,且a=kb+c,那么x也是c的公约数。
除非直接想到,否则不要可以使用递归函数。

宏函数:

为了区别其他函数,宏函数用大写字母表示。   
定义宏函数时,为了不在后续调用中改变函数表达式子,一般将参数及表达式用括号括起来,而且调用宏函数时不能进行参数的自加和自减。

如#define MAX(a,b) ((a)>(b)?(a):(b))
tydefine enum bool{true=1,false=0) bool;//c语言里定义bool变量。

宏函数可以用“#参数”实现字符串的拼接,如#define PDS printf(#y":"#m":"#d)
经典算法:汉诺塔。

*****************************************************************************************************************************

c语言 数组
连续存放在内存的一组数据。
int a[n]//n是元素个数,为常量。
a[0], a[1], a[2]…… a[n-1]//为数组元素
a数组名表示第一个元素的地址; *a=a[0]; *a+=1=>a[0]=a[0]+1;
sizeof函数只关心参数类型,并不对参数进行运算。
命令 cc -s filename //-s表示产生汇编代码。

一维数组。
*a=a[0]; *a += 1=>a[0]=a[0]+1;
sizeof函数只关心参数类型,并不对参数进行运算。
命令 cc -s filename //-s表示产生汇编代码。
字符串是一种特殊的数组,以'/0'结束,输入时系统自动生成。其元素不能重新赋值。
%[^/n] //表示连续读取字符直到'/0'为止。
初始化字符数组,可以不加大括号。
字符串系统函数:strcpy(str,str1); strcat(str1,str2); strlen(str); strcmp(str1,str2); strchr(str, char);参见唐浩强教材p384。
字符转换函数:atoi,atof,头文件#include <stdlib.h>
tydefine enum bool{true=1,false=0) bool;//c语言里定义bool变量。
*****************************************************************************************************************************

c语言 结构体struct
封装的雏形,把数据类型封装成新的数据类型。结构体中的类型,称为结构题的成员。
模块化结构成员,类似c语言模块化函数。
------------------------------------------------------------------------------------------------------------------------
typedef struct Person{
    char name[20];
    bool gender;
    int age;
    int weigh;
}person;//定义一个结构体类型struct person,注意末尾加“;”,定义类型的时候
往往也去别名。
------------------------------------------------------------------------------------------------------------------------
结构体变量 定义、初始化或赋值
struct Person p1;
person p2;
person p3={name:"Jack",age:20,gender:true,weigh:55}
------------------------------------------------------------------------------------------------------------------------
结构成员访问
printf("hello,I am %s, I'm a %s,my salary is %g",
   p3.name,(p3.gender?"handsome guy":"beautiful girl"),p3.salary);
------------------------------------------------------------------------------------------------------------------------
关于结构体变量的对齐补齐?
1如上,sizeof(p3)=20+4+4+4=32;
2如若有
typedef struct Person{
    char name[21];
    bool gender;
    int age;
    int weigh;
}person;
则sizeof(p3)=24+4+4+4=36;//对齐
3如若有
typedef struct Person{
    bool gender;
    int age;
    int weigh;
    char name[21];
}person;
则sizeof(p3)=4+4+4+21+3=36;//补齐
------------------------------------------------------------------------------------------------------------------------
         联合体union
不需要同时访问结构体成员多个成员时,可以定义公用体变量。
与结构体区别的是:
1.合体共用最大元素大小的空间,成员的开始地址都一样;
2.初始化只能初始化第一个成员且为占用空间最大的成员,以成员初始化以免出现垃圾数据。

------------------------------------------------------------------------------------------------------------------------

*****************************************************************************************************************************

c语言 指针*p
保存地址变量的变量,不管怎样类型的指针都为四个字节。
为了不让野指针变量指向变量地址不破坏数据,把指针变量初始化成NULL。
指针提供一种绕过变量名,用地址访问变量的成员变量的方法。


数组指针
形参里的数组是指针,一般不写成数组形式而写成指针形式。
数组里,同类型地址相减,表示地址之间相隔的元素。不同类型,不能运算没有意义。
悬挂指针
    由于指针所指变量内存被释放,而指针仍旧指向原先变量的开辟的内存地址,这样的指针就叫
悬挂指针。当其他变量开辟的内存正好是这块内存,就会导致指针对该新变量操作。
当把只读变量附值给指针时可以把指针定义成常量指针。
数组地址和数组第一个元素的地址是同一个物理地址。
物理地址?
数组指针保存数组地址的指针;指针数组是一组指针变量组成的数组。//char (*p) [10]; char * a[10];
二级指针保存的指针的地址。
void*定义的指针,可以存放任何类型的指针。
函数指针定义的方法为   函数返回类型 (*指针名)(参数类型表列)
函数名和数组名都表示入口地址,跟函数指针和数组指针可以同样使用。
*****************************************************************************************************************************
c语言  动态内存
#include <stdlib.h>
void* malloc(字节数);成功返回申请的内存地址,失败返回NULL;空间不自动清零。
void free(地址),释放内存空间,必须是动态申请的内存空间地址。

void* calloc(元素个数,每个元素的字节数),为数组申请空间,会清零
void* realloc(旧的动态内存地址,新的字节数),释放旧空间,申请新空间,会把旧空间中的数据复制到新空间中。空间不自动清零。
内存申请后没有释放,造成内存泄露。
*****************************************************************************************************************************

抱歉!评论已关闭.