/*--------------------------------------------------------------------------------------
专业:计算机原理与应用
姓名:姚明
学号:04051
日期:2007.12.3
说明:C语言上机实验1~6程序设计
---------------------------------------------------------------------------------------*/
//------------------------------------------------------------
//
// 实验2 基本数据类型和运算程序设计
//
//------------------------------------------------------------
#include <stdio.h>
#define PI 3.14159;
void main(void)
{
int k,p; /* for task 1*/
int c; /* for task 2*/
int x,y,z,w; /* for task 3*/
float r, s; /* for task 4*/
unsigned short i,m,n,_result; /* for task 5*/
char a; /* for task 6*/
/*task 1*/
/*输入整数k、p,将整数k的高字节作为结果的低字节,
整数p的高字节作为结果的高字节,拼成一个新的整数,
然后输出;*/
printf("input int k,p:");
scanf("%x%x",&k,&p);
int newint = (p&0xff00)|(k&0xff00)>>8;
printf("new int = %x\n\n",newint);
getchar();
/*task 2*/
/*输入字符c。如果c是大写字母,
则将c转换成对应的小写,否则c的值不变,
最后输出c;*/
printf("input a character:");
c = getchar();
c >= 'A' && c <= 'Z'? putchar(c + 'a'- 'A'): putchar(c);
putchar('\n');
putchar('\n');
/*task 3*/
/*输入整数x、y、z,输出其中最小值;*/
printf("input x, y, z:");
scanf("%d%d%d", &x, &y, &z);
w = x < y?x:y;
w = w < z?w:z;
printf("min = %d\n\n",w);
/*task 4*/
/*输入圆的半径值r,计算并输出圆的面积
s=∏r2(∏=3.14159);*/
printf("input the radius r:");
scanf("%f", &r);
s = r * r * PI;
printf("The acreage is %.2f\n\n",s);
/*task 5*/
/* 输入无符号短整数
i,m,n(0 <= m<= 15, 1 <= n<= 16-m),
取出i从第m位开始向左的n位
(m从右至左编号为0~15),
并使其向左端(第15位)靠齐;*/
printf("input i, m, n(0 <= m <= 15, 1 <= n <= 16 - m):");
scanf("%hu%hu%hu", &i, &m, &n);
_result = i << 16 - m - n & ~0xffff >> m + n;
printf("The result is %hu\n\n", _result);
getchar();
/*task 6*/
/*输入一个字符,如果是数字(0~9)
则输出该数字代表的整数(8位)的反码,
否则原样输出。(反码用十六进制数表示,
例如,整数0的反码为0xff,整数1的反码为0xfe,
整数9的反码0xf6。)*/
printf("input a charater:");
a = getchar();
a >= '0' && a <= '9'?printf("%hx",~a - '0'):putchar(a);
printf("\n\n");
getchar();
}
//------------------------------------------------------------
//
// 实验3 C程序流程控制实验
//
//------------------------------------------------------------
#include <stdio.h>
void main()
{
int c; /* 每行的元素值(循环中生成), 初值为1 */
int n; /* 显示的行数 */
int i, j; /* 循环控制 */
/* 输入行数,显示13行以内为佳 */
do
{
printf("Input n=");
scanf("%d",&n);
} while(n <= 0 || n > 13);
for(i = 0; i < n; i++)
{
for(j = 0; j < n - i; j++) /* 输入每行前的空格 */
printf("%3c", ' ');
c=1; /* 每行开始输出前都将c重置为1 */
for(j = 0; j <= i; j++)
{
printf("%-3d", c);
printf("%-3c", ' ');
c = c * (i - j) / (j + 1); /* 核心: 递推公式 */
}
printf("\n");
}
}
运行结果(VC):
=======================================================================
Input n=10↙
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
=======================================================================
/* 编写一个程序,将用户输入的任意正整数逆转,例如,输入1234,输出4321。*/
#include <stdio.h>
void main()
{
int num,_result=0;
printf("enter number:");
scanf("%d",&num);
while(num)
{
_result=_result*10;
_result= num%10+_result;
num/=10;
}
printf("%d\n",_result);
}
/* 验证歌德巴赫猜想:任何充分大(>=4)的偶数都可以用两个素数之和表示,
将4到100中的所有偶数分别用两个素数之和的形式表示。(例如:4=2+2,100=3+97)*/
#include <stdio.h>
int IsPrime(int n);
void main()
{
for(int i=4;i<=100;i+=2)
{
int x=0;
for(x=2;x<i;x++)
{
if(IsPrime(x)&&IsPrime(i-x))
{
printf("%d = %d + %d\n",i,x,i-x);
break;
}
}
}
}
int IsPrime(int n)
{
int i;
if (n == 1 || n == 2 || n == 3 || n == 5)
return 1;
else if (n % 2)
{
for (i = 3; i <= n / 2 + 1; i += 2)
{
if (n % i == 0) return 0;
}
return 1;
}
else
{
return 0;
}
}
/*计算两个数的最大公约数*/
#include <stdio.h>
unsigned int gcd(unsigned int,unsigned int);
void main()
{
int x,y;
printf("Enter 2 num:");
scanf("%d%d",&x,&y);
printf("common divisor:%d\n",gcd(x,y));
}
unsigned int gcd(unsigned int x,unsigned int y) // common divisor
{
unsigned int i,j,t;
if(x==0)
return y;
if(y==0)
return x;
for(i=0;0==(x&1);x>>=1,++i);
for(j=0;0==(y&1);y>>=1,++j);
if(j<i)
i=j;
for(;;)
{
if(x<y)
t=y,y=x,x=t;
if(0==(x-=y))
return y<<i;
for(;0==(x&1);x>>=1);
}
}
/* 输出所输入的正文。输出时将连续的多个空格字符和横向制表符缩减为一个空格字符,
空行删去不输出(空行是指仅由空格字符、横向制表符和行结束符组成的行)*/
#include <stdio.h>
int main()
{
int ch, flag1 =0, flag2 = 0;
while((ch=getchar())!=EOF)
switch(ch){
case '\n':
if(flag2) {
flag1=flag2=0;
putchar(ch);
}
break;
case ' ':
case '\t':
flag1=1;
break;
default:
if(flag1){
putchar(' ');
flag1=0;
}
putchar(ch);
flag2=1;
continue;
}
return 0;
}
//------------------------------------------------------------
//
// 实验4 C函数程序设计
//
//------------------------------------------------------------
#include <stdio.h>
int factorial(int n); //计算阶乘
double reckon(int n); //公式函数
void main()
{
int num;
printf("Enter num:");
scanf("%d",&num);
printf("out:%f\n",reckon(num));
}
int factorial(int n)
{
long _result;
if(n>1)
_result=factorial(n-1)*n;
else _result=1;
return(_result);
}
double reckon(int n)
{
double sum=0;
for(int i=1;i<n;i++)
{
double ret = factorial(i);
sum += 1/ret;
}
return sum;
}
//------------------------------------------------------------
//
// 实验5 数组程序设计
//
//------------------------------------------------------------
/* 用rand函数模拟掷双骰子,计算投掷出的两个值的和。在程序中把这两个骰子各掷3600次,
用一维数组记录每一种可能值的出现次数,以表格格式打印出结果,判断算出的和是否合理。*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
void main()
{
int rands[13];int num1,num2;int i;
memset(rands,0,sizeof(int)*13);
/* Seed the random-number generator with current time so that
* the numbers will be different every time we run.
*/
srand( (unsigned)time( NULL ) );
for(i = 1; i < 3600; i++ )
{
num1 = rand()%6;
num2 = rand()%6;
num1==0?num1=6:num1;
num2==0?num2=6:num2;
rands[num1+num2]++;
}
printf("-------------------------------------------------------------------------------\n");
printf("number:\t");
for(i=2; i<13; i++)
{
printf("%d\t",i);
}
printf("\ntimes:\t");
for(i=2; i<13; i++)
{
printf("%d\t",rands[i]);
}
printf("\n-------------------------------------------------------------------------------\n");
}
/* 定义函数stncat(s,t,n),从串t中至多取 n个字符添加到 s的尾部,在主函数中输入两个字符串和一个整数n,
调用函数stncat按要求连接成一个字符串,输出连接后的结果字符串。*/
#include <stdio.h>
char * strncat(char*,const char *,int);
void main()
{
char string[80] = "This is the initial string!";
char suffix[] = " extra text to add to the string...";
/* Combine strings with no more than 19 characters of suffix: */
printf( "Before: %s\n", string );
strncat( string, suffix, 19 );
printf( "After: %s\n", string );
}
char * strncat(char *dest,const char *source,int count)
{
char *p = dest;
while (*p) p++;
while (count-- && (*p++ = *source++));
*p = '\0';
return(dest);
}
/* 找出二维数组b[3][3]的“鞍点”(即行上为最大,列上为最小的元素)
及其位置(行、列下标),如果不存在鞍点也输出相应信息。*/
#include<stdio.h>
#define N 3
#define M 3
void main()
{
int a[N][M],i,j,k,max=0,xmax,ymax,found=0,flag=1;
printf("Input the array(%d numbers):\n",N*M);
for( i=0;i<N;i++ )
{
for( j=0;j<M;j++ )
{
printf("array[%d][%d]=",i,j);
scanf("%d",&a[i][j]);
}
}
for( i=0;i<N;i++ )
{
for( j=0;j<M;j++ )
{
if( max<a[i][j] )
{
max=a[i][j];
}
}
for( j=0;j<M;j++ )
{
if(max==a[i][j])
{
xmax=j;
for( k=0;k<N;k++ )
{
if( max>a[k][xmax] )
flag=0;
}
if( flag==1 )
{
ymax = i;
printf("%d is the andian.\n",max);
printf("pt: x=%d\ty=%d\n",xmax+1,ymax+1);
found++;
}
}
}
}
if( found==0 )
printf("andian not found!\n");
}
/* 八皇后问题,在8*8方格国际象棋盘上放置8个皇后,任意两个皇后不能位于同一行、
同一列或同一斜线(正斜线或反斜线)上,输出所有可能的放法。*/
#include <stdio.h>
#include "math.h"
void paichu(char (*a)[8],int i,int j);
void main()
{
int i,j,k,n;
char a[8][8];
for(k=0;k<8;++k)
{
n=0;
for(i=0;i<8;++i)
for(j=0;j<8;++j)
a[i][j]='*';
for(i=0;i<8;++i)
for(j=0;j<8;++j)
{
if(i==0 && j<k) continue;
else if(a[i][j]=='*' && (fabs(j-k)<i+5))
{
paichu(a,i,j);
a[i][j]='*';
}
}
for(i=0;i<8;++i)
for(j=0;j<8;++j)
if(a[i][j]=='*') ++n;
if(n!=8) continue;
for(i=0;i<8;++i)
{
for(j=0;j<8;++j)
printf("%c",a[i][j]);
printf("\n");
}
printf("\n");
getchar();
}
}
void paichu(char (*a)[8],int i,int j)
{
int k,n,i1,i2,j1,j2;
if(i>j) n=j;
else n=i;
for(k=0;k<8;++k)
{
*(*(a+k)+j)='o';
*(*(a+i)+k)='o';
}
i1=i-n;
j1=j-n;
while(i1<8 && j1<8)
{
*(*(a+i1)+j1)='o';
++i1;
++j1;
}
if(i+j<8) i2=0;
else i2=i-7+j;
j2=j+i-i2;
while(i2<8 && j2>=0)
{
*(*(a+i2)+j2)='o';
++i2;
--j2;
}
}
//------------------------------------------------------------
//
// 实验6 指针程序设计
//
//------------------------------------------------------------
1.2 运行下面的程序之前,先给出你自己认为的结果,再看看运行结果是否和你想的一样,试着解释程序输出的结果。
#include <stdio.h>
#include <stdlib.h>
void f(char s[100])
{
printf("s size in function f: %d\n", sizeof(s));
}
int main()
{
char s[] = "hello";
char *p, *mp;
int n;
char str[100];
printf("s size: %d\n", sizeof(s));
p = s;
printf("p size: %d\n", sizeof(p));
printf("n size: %d\n", sizeof(n));
printf("str size: %d\n", sizeof(str));
mp = malloc(100);
printf("mp size: %d\n", sizeof(mp));
f(str);
return 0;
}
sizeof是是长度运算符, 获得数据类型或是变量的长度,如果是数据类型,
则返回数据类型大小,如果是用数组,则返回数组所占空间大小
s size:6 s是自动分配的数组,根据所给字符串长度,编译器自动分配空间,(h,e, l, l, o, \0)
p size:4 p是char*,通常,指针长度和计算机CPU的位数相等,此计算机为32位,即4字节
str size:100 返回数组长度,str是用户自定义长度的数组
mp size:4 同上 p size
s size in function f:4 f函数属于传参操作,即指针传递,没有开辟新空间,函数对s做指针处理。
2.判断与改错:
#include <stdio.h>
void upper(char *s)
{
while (*s != '\0')
{
if (*s >= 97 && *s <= 122)
*s -= 32;
s++;
}
}
void lower(char *s)
{
while (*s != '\0')
{
if (*s >= 65 && *s <= 90)
*s += 32;
s++;
}
}
int main ()
{
char str[100];
char *p, *q;
printf("Input a string with uppercase, lowercase or digits: \n");
gets(str);
printf("Original: %s\n",str);
p = str;
upper(p);
printf("Uppercase: %s\n",p);
q = str;
lower(q);
printf("Lower: %s\n",q);
return 0;
}
错误原因:
p,q两个指针指向了同一个数据源str,对p,q的操作会直接改变str的内容,
printf函数必须在每次数据改变时,分别打印到屏幕,否则只能输出3行同样的str数据。
/*编写一个你自己的strlen函数,输入一个字符串,返回它的长度,
并在一个完整的程序中验证它。提示:字符串的结尾为 ‘\0’*/
void main ()
{
char buffer[61] = "How long am I?";
int len;
len = strlen( buffer );
printf( "'%s' is %d characters long\n", buffer, len );
}
int strlen(const char * str) {
int length = 0 ;
while (*str++ )
++ length;
return length;
}
/*指针数组最频繁的用处是存放具有不同长度的字符串。
试用指针数组对输入的n个长度不等的字符串进行排序,
升序。字符串的比较可以用标准库中的strcmp函数。*/
#include <stdio.h>
void BubbleSort(char* pt[1024],int count);
void main()
{
char buffer[1024];
char *pBuffer;
char *pt[1024];
int i, ch;
printf( "Do over please input '0'\n" );
printf( "Before:\n" );
/* Read in single line from "stdin": */
for( i = 0; (i < 1024) && ((ch = getchar()) != EOF)
&& (ch != '0'); i++ )
buffer[i] = (char)ch;
/* Terminate string with null character: */
buffer[i] = '\0';
int pl=0;
pt[pl] = buffer;
pBuffer = buffer;
while (*pBuffer++)
{
if(*pBuffer == '\n')
{
++pl;
*pBuffer = '\0';
pBuffer++;
pt[pl] = pBuffer;
}
}
BubbleSort(pt,pl);
printf( "After:\n" );
for(i=0;i<pl;i++)
{
printf( "%s\n", pt[i]);
}
}
void BubbleSort(char* in[1024],int count)
{
char* temp;
for(int y=0;y<count-1;y++)
{
for(int x=1;x<count-y;x++)
{
if((in[x][0])<(in[x-1][0]))
{
temp=in[x-1];
in[x-1]=in[x];
in[x]=temp;
}
}
}
}
/*编写一个带有命令行参数的程序showletter*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
printf("showletter [start] [end]\nstart\t a~z\nend\t0~99\n");
int start=0,end=0;
if(argc == 1)
{
start = 'a';
end = 'z';
}
else if(argc == 2)
{
start = (int)argv[1][0];
end = 'z';
}
else if(argc == 3)
{
start = (int)argv[1][0];
end = start+atoi(argv[2]);
}
else
{
printf("The command parameter error!\n");
}
for(int i=start; i<end; i++)
{
if(i>'z')
{
printf("\n");
end-=26;
i='a';
}
printf("%c",i);
}
printf("\n");
return 0;
}