C和指针之快速上手

/*
一份标准的格式
函数
{
}
循环{
}
( 左右各一个空格, 逗号后面一个空格 ) 
运算符前后各一个空格

缩进
参数超过两个就另起一行回车缩进一次,第二行仍超过函数名就跟函数名对齐 
变量声明完后统一对齐,后面的注释统一对齐
//基本很少用 
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_INPUT 1000 
#define MAX_COLS 20

int  read_column_numbers( int columns[], int max );
void rearrange( char *output, char const *input,
     int n_columns, int const columns[] );

int main( void )
{
    int  n_columns;          /* 需要处理的列标号 */ 
    int  columns[MAX_COLS];  /* 需要处理的列数 */ 
    char input[MAX_INPUT];   /* 容纳输入行的数组 */ 
    char output[MAX_INPUT];  /* 容纳输出行的数组 */ 

    /*
    **读取改列串标号
    */
    n_columns = read_column_numbers( columns, MAX_COLS );
    
    /*
    **读取、处理和打印剩余的输入行
    */
    while( NULL != gets( input ) ){
        printf( "Original input:%s\n", input );
        rearrange( output, input, n_columns, columns );
        printf( "Rearrange line:%s\n", output );
    } 
    
    return EXIT_SUCCESS;
}

/*
**读取列标号,如果超出规定范围则不予理会
*/ 
int read_column_numbers( int columns[], int max )
{
    int num = 0;
    int ch;
    
    /*
    **取得列标号,如果所读取的数小于0则停止
    */
    while( num < max && scanf( "%d", &columns[num] ) == 1
        && columns[num] >= 0 )
            num += 1;
     
    /*
    **确认读取的标号为偶数个,因为它们是以对的形式出现的
    */
    if( num %2 != 0 ){
        puts( "Last column number is not paired." );
        exit( EXIT_FAILURE );
    } 
    
    /*
    **丢弃该行中包含的最后一个数字的那部分内容。
    */
    while( EOF != (ch = getchar() ) && ch != '\n' ) 
        ;
    
    return num;
} 


/*
**处理输入行,将指定列的字符连接在一起,输出行以NULL结尾
*/ 
void rearrange( char *output, char const *input,
     int n_columns, int const columns[] )
{
    int col;         /* columns数组的下标 */ 
    int output_col;  /* 输出列计算器 */ 
    int len;         /* 输入行的长度 */ 
    
    len = strlen( input );
    output_col = 0;
    
    /*
    **处理每对列标号
    */
    for( col = 0; col < n_columns; col += 2 ){
        int nchars = columns[col + 1] - columns[col] + 1;
        
        /*
        **如果输入行结束或输出行数组已满,就结束任务
        */ 
        if( columns[col] >= len ||
                output_col == MAX_INPUT - 1 )
            break; 
            
        /*
        **如果输出行数据空间不够,只复制可以容纳的数据
        */ 
        if( output_col + nchars >MAX_INPUT - 1 )
            nchars = MAX_INPUT - output_col -1;
            
        /*
        **复制相关的数据
        */ 
        strncpy( output + output_col, input + columns[col],
            nchars );
        output_col += nchars;      
    } 
    
    output[output_col] = '\0';
} 

2 总结:

2.1 注释:第1个/*和第1个*/之间都被看为注释,不管里面有多少/*

C语言中最好不用/**/注释掉一段代码,最好从逻辑上删除

#if 0
    statements
#endif 

最好给每段代码的作用注释,这样方便维护。

2.2 函数原型:main()函数前的函数声明。在这些函数被调用时,编译器能对它们进行准确性检查。

2.3 传参:C语言中,数组参数以引用的方式进行传递——传址调用不论加没加&,这是数组名做参数的效果,ps:如果不是数组名做参数,而是数组参数中出现了下标引用,也就是实际参数是数组的某个特定元素,就不是传址调用了),而标量(数组下标选择的某一个数组元素也是标量)和常量是按值传递。在函数中对标量参数的任何修改都会在函数返回时丢失,所以,被调用函数无法修改调用函数以传值形式传递给它的参数。(除非加上了&)

2.4 NUL和NULL:NUL字节指字节模式全为0的字节,类似'\0'的字符常量;

              NULL指一个值为0的指针。

             它们都是整型值,值也相同,但含义不同。

2.5 关于返回值:如果返回值是多个字符,则用数组存储。

2.6 声明变量但是不初始化的话,它的初始值将是一个不可预料的值,也就是垃圾。

2.7

for( 初始部分; 测试部分; 调整部分 ){
    statements
}

初始部分:循环开始前执行一次

测试部分:每次循环执行前执行一次

调整部分:每次循环执行完执行一次

2.8

strncpy( 目标字符串+偏移地址, 起始字符串+偏移地址, 复制的字符数); 
strcpy( 目标字符串+偏移地址, 起始字符串+偏移地址 );
strcat( 目标字符串, 起始字符串 ); /* 第2个字符串参数添加到第1个参数末尾 */

2.9

printf函数执行格式化输出

scanf函数执行格式化输入

getchar执行非格式化字符输入

putchar执行非格式化字符输出

3 提示警告

scanf函数的标量前添加&字符

使用数组下标注意越界

猜你喜欢

转载自www.cnblogs.com/sunzD/p/12531311.html