Chinaunix首页 | 论坛 | 博客
  • 博客访问: 846730
  • 博文数量: 190
  • 博客积分: 7021
  • 博客等级: 少将
  • 技术积分: 1752
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-17 19:26
文章分类

全部博文(190)

文章存档

2014年(9)

2011年(32)

2010年(149)

我的朋友

分类:

2010-09-13 20:35:43

在C语言中,常用的标准输入/输出函数有:printf()函数,scanf()函数,putchar()函数,getchar()函数,puts()函数,gets()函数。

字符常量'x'和字符串常量”x“虽然搜只有一个字符,但是在内存中的情况是不相同的,其中,'x'在内存中占一个字节,”x“在内存中占有两个字节,x和\0。

如果格式控制传中有非格式字符则输入时也要输入该非格式字符。如语句scanf("a=%d,b=%d",&a,&b);,字符'a','=',','以及b都属于非格式字符,在输入时,应该鸳鸯并按照位置输入。例如输入为"a=123,b=456",函数会把123赋值给变量a,把456赋值给变量b。但是如果输入为“123,456”的话,时钟没有输入非格式字符,所以变量a和变量b都不会被赋值,系统给其一个默认值,而这个默认值往往不是所期望的值。

运算符的结合性:
 左结合:二元算术运算符就是左结合的
 右结合:最典型的右结合则是赋值运算”=“

逻辑与运算符的求职顺序是自左向右的。且运算符"&&"和"||"的优先级低于关系运算符,而且,逻辑表达式求职时是严格按照从左到右的顺寻对子表达式分别求值的,这样就会引起”短路“计算。即双目逻辑运算符首先计算出左侧运算对象的值,然后计算右侧运算对象的值。如果逻辑表达式的值可由左侧运算对象单独推导出来,则不会再ijsuan右侧运算对象的值。

跳转结构:
C语言中提供了三种实现跳转结构的语句:break语句,continue语句和goto语句
BREAK:是程序跳出switch语句而执行其后的语句;
       还可以用与while,do...while,for循环语句中,是程序终止循环而执行循环后面的语        句
break语句不能用于循环语句和switch语句外的任何语句中,并且,在多层循环中,一个break语句只能向外跳一层
CONTINUE:continue语句用于for,while,do...while循环体重,作用是终止本次循环,就是跳过循环体中尚未完成的语句,接着进行下一次时候执行循环的判断。
GOTO:无条件专项语句

return语句的使用原则:
    函数的返回值是通过return
    如果北调函数是无返回值的,那么函数体内可以有return语句,也可以没有。但是如果被调函数是有返回值的,那么函数体内就必须包含return语句
    一个函数中可以包含有多个return语句,执行到第一条return语句时,函数都将返回到主调函数中,伺候的其他语句则不会继续执行

C语言中的参数传递机制:
    C语言中的参数传递机制采用的是一种被称为“按值传递”的方式,当主调函数调用被调函数时,系统会把实参的值赋给形参,而且这个过程是绝对单向的,也就是说值能且仅能从实参传给形参,反过来则不行
形参仅仅是实参的一个副本,即两者并不共享同一储存单元,因此,形参的任何改变对于实参都没有实际意义,

C语言中允许函数之间进行嵌套调用,但是并不允许函数的嵌套定义。也就是说一个函数内不能包含另外一个函数的定义。

递归过程调用的总结:
》递归过程的实现就是要自己调用自己
》递归调用的过程总是层层向下的,而退出时的次序则刚好相反
》主程序首次调用递归过程为外部调用
》递归过程每次递归调用自己都属于内部调用
》一个递归调用的函数,每次函数返回的地址都各不相同
以上的递归内容可以通过一个函数看出:

#include "stdio.h"

void func1(int a)
{
    if (a < 4)
    {
        printf("%d\n",a);
        func1(a + 1);
    }
}

void func2(int a)
{
    if (a < 4)
    {
        func2(a + 1);
        printf("%d\n", a);
    }
}

void main()
{
    func1(0);
    func2(1);
}

字符串的反转函数:

//字符串的反转

void reverse(char s[], int l, int h)
{
    if (l > h) return;
    else
    {
        char t;
        reverse(s, l + 1, h - 1);
        t = s[l];
        s[l]=s[h];
        s[h]=t;
    }
}


变量的存储类型:
变量作用域的不同归根结底是由于变量存储类型的不同而造成的。所谓存储类型就是指变量占用内存空间的方式,它也被称为“存储方式”
》静态存储
》动态存数
    静态存储的变量通常是在变量定义时就为其分配固定的存储单元并一直保持不变,直至整个程序结束,前面所说的全局变量就属于这种存储方式。而动态存储则更为常见,采用动态存储方式的变量在程序的执行过程中,仅当需要时才临时性地分配存储单元,并且在使用完毕之后,动态存储的变量也会被立即释放

静态局部变量:
有些时候,程序员可能希望函数中的局部两边栽函数调用结束后不消失而保留原址,也就是希望占用的存储单元不被释放,而在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值;
  》静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放
  》静态局部变量是在编译时赋值的,即只赋值一次
  》如果定义局部变量是不赋初始值,则对静态局部变量来说,编译时会自动赋初值0
  》虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的,这一点与全局变量不同

extern变量:
》关键字extern在源文件中扩展变量的作用域
》关键字extern实现变量的跨文件访问

内部函数:
    变量有作用域,函数也有,金光函数本质上说是全局的,但可以限定函数能否被别的文件所引用。当一个源程序有多个原文件组成时,C语言根据函数能够被其他源文件中的函数调用,将函数分为内部函数和外部函数。
    如果一个函数只能被本文件中其他函数所调用,则称为内部函数。内部函数为称为静态函数。在定义内部函数时需要在函数名和函数类型前面加static关键字

数组类型的参数
以数组作为参数:
    数组可以作为函数的参数来使用。这时,函数调用的实参列表里出现的数组参数只是一个无下标,此时,传递给函数的值实际上只是数组元素的起始地址。当数组以不带下表的数组名的形式被传进函数时,函数体内就可以使用带下标的形参来存储数组元素。
    函数所操作的是原始数组,而非其副本。数组名作为实参来使用时被传递的实际值就是“地址”,如果传递的是地址,那么操作的就是原值。

避免数组被修改:
    将数组用作参数的时候,由于传递的是数组的首地址,因此在函数体中操作的是数组本身,而非其副本,这样数组元素就有可能被修改。但是有些时候我们不希望数组在其他函数体中被修改。则可以使用关键字const

二维数组转置:


int i = 0;
int j = 0;
int tmp = 0;

for (i = 0; i < 4; i++)
{
     for (; j < 4; j++)
    {
        tmp = a[i][j];
        a[i][j] = a[j][i];
        a[j][i] = tmp;
    }
    
j = i + 1;
}


字符串的处理--大小写转换函数
extern char *strlwr(char *s);
extern char *strupr(char *s);
转换参数s中出现的大,小写字母,返回值指向字符串s的指针


//在text数组中找到word出现的次数

printf("please input the word which you want to count.\n");
gets(word);

int length = strlen(word);
int i = 0;
while(text[i] != '\0')
{
    strncpy(temp, text + i, length);
    if (strcmp(temp, word) == 0)
    {
         sum++;
         i += length;
    }
    i++;
}


求字符串指数的问题:

#include "stdio.h"
#include "string.h"

char s[100000]

void main()
{
    int i,j,m,n;
    while (gets(s) && strcmp(s, "."))
    {
        m = n = strlen(s);
        for (i = 2; i <=n; i++)
        {
            while(n%i == 0)
            {
                n /= i;
                for (j=0;j<m-m/i && s[j] == s[j+m/i];j++)

                    ;
                if (j == m-m/i)
                {
                    m /= i;
                }
            }
        }
        printf("%d\n",strlen(s)/m);
    }
}

直接插入法排序:

#include "stdio.h"
#define SIZE 8

void main()
{
    int a[SIZE] = {99,16,30,5,81,65,12,20};
    int i,j,k
    for (i = 1; i< SIZE; i++)
    {
        k = *(a + i);
        j = i - 1;
        while(j >= 0 && k > *(a + j))
        {
             *(a+j+1) = *(a+j);
             j--;
         }
         *(a + j + 1) = k;
    }

    for (i = 0; i < SIZE; i++)
        pritnf("%d", *(a + i));
}


“#”和“##”运算符
   井号"#"在C语言中也是一种运算符,编译器仅允许"#"运算符出现在带参数的宏的替换文本中,将跟在其后的参数转换成一个字符串常量。
ps:

#define PF_INT(i) printf(#i"=%d\n",i)

void main()
{
    int x = 100;
    PF_INT(x);
}

预处理器处理后处处语句将变成:
     printf("x""=%d\n",x);
因为c语言中两个相邻的字符串常量会合并,所以上面的语句相当于:
    printf("x=%d\n",x);

##运算符:
   ”##“也是一种运算符,是将两个运算对象连接到一起,也只能出现在带参宏定义的替换文本中。也可以是认为将两个运算对对象”粘“在一起。
阅读(1091) | 评论(0) | 转发(0) |
0

上一篇:英文简历用语

下一篇:Linux知识

给主人留下些什么吧!~~