C和指针第一章

要从逻辑上删除一段代码,最好的办法就是使用#if指令:

#if 0

    statement

#end if

问题1:把声明放在头文件中,并在需要时用#include指令把它们包含于源文件中,这种做法有什么好处?
答:声明只需要编写一次,对以后的维护和修改更容易,声明一次消除了多份拷贝中出现写法不一致的机会。
问题2:使用#define指令给字面值常量取名有什么好处?
答:修改方便,可以赋予特殊含义便于理解。
问题3:strcpy和strncpy的用法:
答:
strcpy():以源串中的'/0'为拷贝结束标志,直到遇到该NULL为止,然后将NULL拷贝上。
strncpy():以第三个参数N为拷贝结束标志,如果source的长度小于N,则剩余的字符全都用NULL填充,如果Source的长度大于N,则从source中截取前N个字符,拷贝过去。
问题4:c语言并不执行数组下标的有效性检查。为什么?
答:c语言中下标检查开销太大,作用于指针的下标引用有效性既依赖于该指针当时正好指向什么内容,也依赖于下标的值。

编程题:
编写一个程序,从标准输入读取几行输入。每行输入都要打印到标准输出上,前面要加上行号。在编写这个程序时要试图让程序能够处理的输入行的长度没有限制。

#include <stdio.h>
#include <stdlib.h>
int main() {
 char ch;
 int i = 1;//哨兵
 int line = 1;
 while ((ch = getchar()) != EOF) {
  if (i == 1) {
   printf("%d.", line++);
   i = 0;
  }
  putchar(ch);
  if (ch == '\n') {
   i = 1;
  }
 }
 system("pause");
 return 0;
}


编写一个程序,从标准输入读取一些字符,并把它们写到标准输出上。它同时应该计算checksum值,并写在字符的后面。

#include <stdio.h>
#include <stdlib.h>
int main() {
 char ch;
 char checksum = -1;
 while ((ch = getchar()) != EOF && ch!='\n'){
  putchar(ch);
  checksum += ch;
 }
 printf("%d", checksum);
 system("PAUSE");
 return 0;
}


编写一个程序,一行行地读取输入行,直到到达文件尾,算出每行输入行的长度,然后把最长的那一行打印出来。为了简单起见,可以假定所有的输入行均不超过1000个字符。

问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1001
int main() {
	char input[MAX_LEN];   //保存输入的字符
	char longest[MAX_LEN];  //保存最长字符
	int len;     			//哨兵的作用
	int longest_len = -1;
	while(gets(input) !=NULL) {
		len = strlen(input);
		if(len>longest_len) {
			strcpy(longest,iput);  //如果输入字符的长度大于最长的,如果把输入的字符赋给longest数组
		}
	}
	if(longest_len>=0) { //存在最长字符串
		puts(longest);
	}
	return 0;
}




书中的源程序:
/*
 书中涉及的源程序
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COLS 20 /*所能处理的最大列号*/
#define MAX_INPUT 1000/*每个输入行的最大长度

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


*/#include "fristDemo_h.h"
/************************************************************************/
/* 读取列标号,如果超出范围则不予理会                                                               
/************************************************************************/
int read_column_numbers(int colunms[], int max) {
 int num = 0;
 int ch;
 while (num < max && scanf_s("%d", &colunms[num]) == 1 && colunms[num] >=0) {
  num += 1;
 }
 if (num % 2 != 0) {/*确认已经读取的标号为偶数个,因为它们是以对的形式出现的*/
  puts("Last column number is not paired");
  exit(EXIT_FAILURE);
 }
 while ((ch = getchar()) != EOF && ch != '\n');/*丢弃该行中包含最后一个数字的那部分内容*/
 return num;
}
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';
 }


}

int main() {
 int n_columns;/*进行处理的列标号*/
 int columns[MAX_COLS];/*需要处理的列数*/
 char input[MAX_INPUT];/*容纳输入行的数组*/
 char output[MAX_INPUT];/*容纳输出行的数组*/
 n_columns = read_column_numbers(columns, MAX_COLS);/*读取该串列标号*/
 while (gets(input) != NULL) {
  printf("Original input : %s\n", input);
  rearrange(output, input, n_columns, columns);
  printf("Rearranged line:%s\n", output);
 }
 return 0;
}


则程序输出如下:Original input:abcdefghijklmnopqrstuvwxyz
Rearranged Line:efghijklmnopqrstuvwxyz
Original input:Hello there,how are you?
Rearranged Line:o there,how are
Original input:I am fine,thanks.
Rearranged Line:fine,thanks.
Original input:See you!
Rearrayged Line:you!
Original input:Bye



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值