20100410140103
1、有20级台阶,一次可以迈一级或者两级,则爬完次楼梯有几种方法或者方式?
算法:设爬n级台阶则共有C(n)种方法,则C(1)=1,C(2)=2
C(n)=C(n-1)+C(n-2) (n>=3)
#include <iostream>
using namespace std;
int main()
{
int factorial(int );
int n;
char s;
loop:
{cout<<"please input a n(台阶数):"<<endl;
cin>>n;
cout<<"走完"<<n<<"级台阶的方法有"
<<" "<<factorial(n)<<"种"<<endl;}
cout<<"你想运算过一种台阶数吗?"
<<"输入y继续,输入n,退出"<<endl;
cin>>s;
if(s=='y') goto loop;
else cout<<"gameover"<<endl;
return 0;
}
int factorial(int n)
{
if(n==1)
{
return 1;
}
else if(n==2)
{
return 2;
}
else return(factorial(n-1)+factorial(n-2));
}
2、 编写一个程序从键盘读入一个整数,然后将这个指数的所有正因子输出
#include <iostream>
using namespace std;
int main()
{
void multi(int );
int n;
cout<<"please input a postive integer:\n";
cin>>n;
multi(n);
return 0;
}
void multi(int n)
{
int d;
for(d=1;d<=n;d++)
{
if(n%d==0)
cout<<d<<" ";
}
}
3、 1+11+111+……+111111111=
2+22+222+……+222222222=
…………
9+99+999+……+99999999+
请用程序完成
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
int i,j,k;
long p,s;
cout<<"请输入一个个位数来组成这个最后最大的n位数:\n";
scanf("%d",&k);
for(i=1;i<=9;i++)
{for(j=1,p=0,s=0;j<=k;j++)
{
p = p*10 +i;
if(j ==k ) printf("%ld=",p);
else printf("%ld+",p);
s+=p;
}
printf("%ld\n",s) ;
}
return 0;
}
4、由“#”开始的命令是C预处理程序的命令。
#define 是宏定义命令,其一般形式为:
#define string1 string2 表示要把源代码中出现在该行之后的每一个string1 都用string2 来代替
宏定义 必须是写在第一次使用该宏定义的代码之前;
宏定义不是以分号为结束的
#define、string1、string、之间至少要有一个空格
string1称为宏,string2称为宏扩展;
宏名用大写字母表示是一个传统的习惯;
使用宏定义的好处:
1) 简化程序的书写
2) 提高程序的可读性
3) 便于程序的修改
4) 提高程序的可移植性。
预处理程序将不替换字符串中或用单引号括起来的字符常量的“宏”。
Example:
#include "stdio.h"
#define HELLO "bonjour\n"
#define A 'B'
void main()
{
printf(HELLO);
printf("%c\n",A);
}
#define 宏名(参数表) 字符串 其中字符串中要包含参数表中指定的参数。
Example:
#include "stdio.h"
#define N 2
#define M N+1
#define NUM (M+1)*M/2
void main()
{
int i,n;
for(i=1,n=0;i<=NUM;i++)
n++;
printf("最后n等于%2d\n",n);
}//字符串是不能进行算术运算的
带有参数的宏替换
Example:重点啊
在定义带有参数的宏替换时,要用圆括号将宏扩展部分括起来
正确的是:
#include "stdio.h"
#define square(n) (n*n)
void main()
{
printf("%f\n",27.0/square(3.0));
}
运行截图:
错误的程序:
#include "stdio.h"
#define square(n) n*n
void main()
{
printf("%f\n",27.0/square(3.0));
}
运行截图:
带参数的宏调用和函数调用时完全不同的,
宏调用时在编译之前完成的,函数调用时在编译之后实现的。
Example:带参数的宏调用
#include "stdio.h"
#define square(n) (n*n)
void main()
{
int i=1;
while (i<=10)
printf("%d\n",square(i++));
} //the program is run in vc instead of tc
运行截图:
When in tc the output is:
因为在带有参数的宏调用中,是做一个生效一个,而不是像函数调用那样要等待循环一次,因为这个宏调用在编译之前就已经完成,所以结果是:1*2=2;3*4=12;5*6=30;7*8=56;9*10=90;
函数调用:
#include "stdio.h"
void main()
{
int square(int );
int i=1;
while(i<=10)
{
printf("%d\n",square(i++));
}
}
int square(int n)
{
return (n*n);
}
运行截图:
共用了22个B空间,函数调用10*2B=20B,主函数用了2个B,
最好将每个形参也用圆括号括起来:
取消已有的宏定义命令:#undef 宏名
作用:在#undef 行后面出现的“宏名”将不被扩展
Example:
#include "stdio.h"
#define P 3
void main()
{
float r = 2.0;
printf("%f\n",P*r*r);
#undef P
{
int P = 10;
printf("%d\n",P);
}
}
运行截图:
文件包含:是指一个源文件可以将另外一个源文件的全部内容包含进来。其一般的形式为:#include“文件名”/#include<filename>
Function(功能):把指定文件的内容插入到该#include命令所在之处。
其中“文件名”:首先在当前目录中找文件。如果找不到,再到一系列系统预先设定的目录中去找。
<文件名>:则不在当前目录中寻找,而是径直到系统预先设定的目录中去寻找该文件。
建议:#include“filename”这种格式更好用一些,也更好一些。
条件编译:有时希望其中的一部分只有在满足一定条件时才进行编译,否则不编译。
条件编译有以下几种方式:
1)#if 常量表达式
程序段
#endif
作用:如果常量表达式为真(非零),则相应的程序被编译。否则跳过它。如:
#include "stdio.h"
#define MAX 100
void main()
{
#if MAX>99
printf("arraylength>99\n");
#endif
}
因为MAX>99 所以就输出了arraylength>99。
2) #if 常量表达式
程序段1
#else
程序段2
#endif
Example:
#include "stdio.h"
#define ENGLISH 0
void main()
{
#if ENGLISH
printf("HELLO!\n");
#else
printf("你好!\n");
#endif
}//此时ENGLISH 是一个零,所以就会输出“你好!”
3)
4)ifdef 宏名
程序段
#endif
作用:如果定义了相应的“宏名”,则编译相应的程序段,否则跳过它;
16讲2011年7月11日 17:57:25
数组:是按一定格式排列起来的一系列具有同一属性的项目
数组名:表示群体的共性(具有同一数据类型)
下表:表示群体的个性(各自占有独立的单元)
一维数组的定义方式:
类型说明符int 数组名 Nicolas 【常量表达式】
int a【10】
数组名遵循标识符命名原则(主要要是见名知意)
常量表达式表示元素的个数 即数组长度。
数组元素的表达形式:数组名【小标】。
其中:小标:是整型常量或整型表达式。对于任何数组,小标都从0开始。
用标准输入输出函数来输入输出一个数组的一个例子:
#include "stdio.h"
void main()
{
int a[10];
int i;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(i=0;i<10;i++)
printf("a[%d]=%d ",i,a[i]);
}
用起泡法进行排序:(或言之“冒泡法”)
必学排序无论学什么语言,还是学数据结构
理解掌握起泡法对计算机专业的学生很是重要!
#include "stdio.h"
void main()
{
int a[6],i,j,t;
for(i=0;i<6;i++)
scanf("%d",&a[i]);
printf("the original array is:\n");
for(i=0;i<6;i++)
printf("a[%d]=%d ",i,a[i]);
printf("\n");
printf("the sorted array is:\n");
for(j=0;j<6;j++)
for(i=0;i<6-j;i++)
if(a[i]>a[i+1])
{
t= a[i];
a[i]=a[i+1];
a[i+1]=t;
}
for(i=0;i<6;i++)
printf("a[%d]=%d ",i,a[i]);
}
用选择法进行排序:
#include <iostream>
using namespace std;
int main()
{void select_sort(int array[],int n);
int a[10],i;
cout<<"enter the originl array:"<<endl;
for(i=0;i<10;i++)
cin>>a[i];
cout<<endl;
select_sort(a,10);
cout<<"the sorted array:"<<endl;
for(i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
void select_sort(int array[],int n)
{int i,j,k,t;
for(i=0;i<n-1;i++)
{k=i;
for(j=i+1;j<n;j++)
if(array[j]<array[k]) k=j;
t=array[k];array[k]=array[i];array[i]=t;
}
}
二维数组的一般定义:
类型说明符 数组名 【常量表达式】【常量表达式】
例如:float a【2】【3】
二维数组元素的表示形式:
数组名【下标1】【下标2】
下标1:称为行下标 下标2:称为列坐标
一个新算法:已知有一有序序列,现在要插入一个数保证数列仍然有序……
将4*4的矩阵转置并输出。
#include "stdio.h"
void main()
{
int t,i,j;
int a[4][4];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
scanf("%d",&a[i][j]);
for(i=0;i<4;i++)
{for(j=0;j<4;j++)
printf("%6d",a[i][j]);
printf("\n");
}
printf("下面来进行转置\a\a\n");
for(i=1;i<4;i++)
for(j=0;j<4;j++)
{
t=a[i][j];
a[i][j]=a[j][i];
a[j][i]=t;
}
for(i=0;i<4;i++)
{for(j=0;j<4;j++)
printf("%6d",a[i][j]);
printf("\n");
}
}
1.同一个数组中的所有元素占用一组连续的存储空间;
2.数组的存储分配按行进行;
3.数组名字表示该数组的首元素地址。
· 对于一维数组而言,各元素按下标次序依次存放,
如a[0],a[1],a[2],…等等。且有:
&a[0]:
&a[1]:
&a[2]:
数组中任一元素a【i】的地址可以表示为:&a【i】=a+sizeof(元素类型)
其中sizeof(元素类型):求每个元素占用的存储空间的字节数。
认识多维数组时,要懂得降维数
· C中的二维数组可以看作是一种特殊的一维数组。
· 例如float a[3][4];
a[0] a[0][0] a[0][1] a[0][2] a[0][3]
a- a[1] a[1][0] a[1][1] a[1][2] a[1][3]
a[2] a[2][0] a[2][1] a[2][2] a[2][3]
· 二维数组元素a[i][j]的地址可以这样得到:
&a[i][j]=a[i]+j*sizeof(a[0][0])
=a+i*sizeof(a[0])+j*sizeof(a[0][0])
=a+i*16+j*4
· 例:&a[1][2]=a+1*16+2*4=a+24
· C语言规定只有静态存储类(static)和外部存储类(extern)的数组才能初始化。例如:static int a[10]={0,1,2,3,4,5,6,7,8,9};
· 这里必须将各数组元素的初值放在一对花括号内。编译程序按数组元素的存放顺序依次对其赋值。
· 也可以对数组中的部分元素初始化,对静态数组而言,没有初始化的数组元素,系统会将它自动置0。
· 利用数组来球fibonaccia数列
#include "stdio.h"
main()
{ int i;
static int a[20]={1,1};
for(i=2;i<20;i++)
a[i]=a[i-2]+a[i-1];
for(i=0;i<20;i++)
printf("%d\n",a[i]);
}
http://www.ccea.zju.edu.cn/clearn/
1. puts(字符串)
将给定字符串输出到标准输出设备上。在输出时将字符串结束标志‘\0’转换成‘\n’,即输出完字符串后换行。
2. gets(字符串)
从标准输入设备上读入一个字符串到字符数组中,并且返回一个函数值,该函数值是字符数组的起始地址。
example:
/* Note:Your choice is C IDE */
#include "stdio.h"
#include"math.h"
void main()
{
printf("%f\n",sin(90));
puts("you are a good teacher!!!!");
putchar('a');
puts("you are a good teacher!!!!");
int n;
static char month[][14]={
"illegal month",
"January",
"February",
"March",
"December"};
scanf(" %d",&n);
printf("%s\n",(n<1||n>12)?month[0]:month[n]);
char s[10];
printf("please input a string\n");
scanf("%s",gets(s));
puts(s);
}
3. strlen(字符串)
用以测试字符串的长度。函数值是字符串中字符的个数,不包括‘\0’在内。
4. strcpy(字符串1,字符串2)
把字符串2拷贝到字符串1中去。例如:
static char str1[]=“student”,str2[]=“china”;
strcpy(str1,str2);
执行后str1的值是“china\0t\0”。
5. strcat(字符串1,字符串2):连接两个字符串
· 把字符串2接到字符串1的后面,结果放在字符数组1当中。函数调用后得到一个函数值——字符数组1的地址。例:
static char str1[30]=“People’s Republic of”;
static char str2[]=“China”;
puts(strcat(str1,str2));
输出为:People’s Republic of China
· 对于strcat(s1,s2),只要串s1的长度允许且s1和s2两个串不重叠,可以用库函数strcpy这样实现:
strcpy(s1+strlen(s1),s2)
6. strcmp(字符串1,字符串2):比较字符串1和字符串2。
对两个字符串自左至右逐个字符比较,直到出现不同的字符或遇到‘\0’为止。
如果全部字符相同,则认为相等;若出现不相同的字符,则以第一个不同的字符的比较结果为准。比较的结果由函数值带回。
当字符串1=字符串2时,函数值为0;
当字符串1>字符串2时,函数值为一正整数;
当字符串1<字符串2时,函数值为一负整数。
比较的是ascii值
7. strlwr(字符串)
将字符串中的大写字母转换成小写字母。
8. strupr(字符串)
将字符串中的小写字母转换成大写字母
· 运算符&只能作用于在内存中体现地址的对象(在内存中为该对象分配了存储空间),如变量,数组元素等。而形如&(x+3)和&5则是非法的。
· 取寄存器(register)变量的地址也是非法的。
· 单目运算符*将它的操作数作为最终目标的地址来对待,并根据那个地址取得相应的内容。
2011年7月13日 17:59:56
下面的内容是重中之重:指针
delete(s,i,n)
char s[];
int i,n;
{
if (i>=0&&n>0&&n+i<=strlen(s))
{
s[i]='\0';
strcat(s,s+i+n);
return 1;
}
else
return 0;
}
指针变量定义的一般形式为:数据类型 *变量名;
例如:
int *ptr_int;
float *point_1;
其中:
&ptr_int: 表示取地址
&point_1:
运算符*和&的优先级与!,++,--等相同,是自右到左结合的。
指针变量可以出现在表达式中。
y=*px+3与y=x+3功能相同
d=sqrt((double)*px)是把px的平方根保存在d中。下面这些表达式都是合法的:
*px+=6 与x+=6 功能相同
(*px)++与x++相同
*px++ 与(*px)++不同,而是等价于*(px++)
&*px 与&x 功能相同
*&x与x等价
指针作为函数参数
swap(x,y) main()
int x,y; { int a,b;
{ int temp; a=10;
temp=x; b=20;
x=y; swap(a,b);
y=temp; printf(“%d,%d”,a,b);
} }
&*px 与&x 功能相同
*&x与x等价 这两个得格外注意
学习c的目的就是为了学习指针,不懂指针就等于没有学习c语言
[例7.9] 编写一个程序从键盘上读入一行,并统计在该行里的白空字符和小写字母的个数。
#include <stdio.h>
int get(ws,lc)
int *ws,*lc;
{int c;
*ws=*lc=0;
while((c=getchar())!=EOF)
switch(c) { case ‘’:
case ‘\t’: (*ws)++; break;
case ‘\n’: return 1;
default: if(c>=‘a’&&c<=‘z’) (*lc)++;
}
return 0;
}
main()
{int ws,lc;
if(get(&ws,&lc))
{printf(“There are %d whitespace
characters”,ws);
printf(“\nand %d lowercase letters\n”,lc);
}
else printf(“unexpected end-of-file\n”);
}
切记:指针变量在引用之前一定要先赋值,否则其所指的地址不定,所引用的是垃圾数据。而对未赋值指针变量所指地址中赋值更会产生灾难性的后果。
如果在主函数中将ws和lc定义为int *ws,*lc,应该如何调用get函数?
数组名和指针变量是有区别的:
1.非形参数组名是指针常量,而不是指针变量,
pa=a和pa++等都是有意义的操作;
a=pa,a++或p=&a之类的表达式都是非法的。
2.形参数组名是(指针)变量
例如:fun(x,y)
int x[],y[][4];
这时 x[]等价于*x, y[][4]等价于(*y)[4]
则 x++,y+=1 是有意义的操作
用气泡法单向排序
main()
{ int i,a[]={3,4,2,5,1};
sort(a,5);
for(i=0;i<5;i++)printf(“%d”,*(a+i));
}
sort(p,n)
int *p,n;/*或 int p[],n */
{ int i,t,*pj;
for(i=1;i<n;i++)
for(pj=p+n-1;pj>p+i-1;pj--)
if(*(pj-1)>*pj) {t=*pj;*pj=*(pj-1);*(pj-1)=t;}
}
指针与多维数组。例:
float y[4][3],(*py)[3],*p;则有:
&y[i][j]=y[i]+j=*(y+i)+j
*&y[i][j]=*(y[i]+j)=*(*(y+i)+j)=y[i][j]
由 y[i]=*(y+i) 则有
&y[i]=&*(y+i)=y+i
说明:
&y[i]和y[i]的值相同,但意义不同
&y[i]指向行
*(&y[i]+j)=*(y+i+j)=y[i+j]
y[i]指向列
*(y[i]+j)=*(*(y+i)+j)=y[i][j]
指针与多维数组。例:
float y[4][3],(*py)[3],*p;则有:
&y[i][j]=y[i]+j=*(y+i)+j
*&y[i][j]=*(y[i]+j)=*(*(y+i)+j)=y[i][j]
由 y[i]=*(y+i) 则有
&y[i]=&*(y+i)=y+i
说明:
&y[i]和y[i]的值相同,但意义不同
&y[i]指向行
*(&y[i]+j)=*(y+i+j)=y[i+j]
y[i]指向列
*(y[i]+j)=*(*(y+i)+j)=y[i][j]
float y[4][3],(*py)[3],*p;
py=y; 则有:
py[i][j]=*(py[i]+j)=*(*(py+i)+j)
若有:p=y 则有
*p=*(p+0)=y[0][0] *(p+6)=y[2][0]
*(p+1)=y[0][1] *(p+7)=y[2][1]
*(p+2)=y[0][2] *(p+8)=y[2][2]
*(p+3)=y[1][0] *(p+9)=y[3][0]
*(p+4)=y[1][1] *(p+10)=y[3][1]
*(p+5)=y[1][2] *(p+11)=y[3][2]
矩阵转置
main()
{float a[4][4],t;
int i,j
for(i=0;i<4;i++)
for(j=0;j<4;j++)
scanf(“%f”,&a[i][j]);
for(i=1;i<4;i++)
for(j=0;j<i;j++)
{t=a[i][j];a[i][j]=a[j][i];
a[j][i]=t;}
for(i=0;i<4;i++)
{for(j=0;j<4;j++)
printf(“%f”,a[i][j]);
printf(“\n”);
[例7.2]将4×4的矩阵转置并输出。
把某月的第几天转换为这年的第几天,返过来将某年的第几天转换为日期
#include "stdio.h"
void main()
{
int computingdays(int ,int ,int );
int days, year,month,day;
printf("please input year,month and day\n");
scanf("%d%d%d",&year,&month,&day);
printf("you input the year:year%d,month%d,day%d",year,month,day);
days=computingdays(year,month,day);
printf("是你所输入年份year%d的%d天",year,days);
}
int computingdays(int year,int month,int day)
{int i,leap;
static int day_tab[][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}};
leap=((year%4==0&&year%100!=0)||year%400==0);
for(i=1;i<month;i++)
day+=day_tab[leap][i];
return day;
}
反过来将某年的第几天换算为该年的日期
这个得动脑筋思考(下面的源程序有错误,得改正)
采用参数传递方式传递数组day_tab
main()
{ static int day_tab[][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}};
printf(“%d\n”,day_of_year(day_tab,1999,9,9));
}
day_of_year(day_tab,year,month,day)
int year,month,day,(*day_tab)[13];
{
int i,leap;
leap=(year%4==0&&year%100||year%400==0);
for(i=1;i<month;i++)
day+=day_tab[leap][i];
return(day);
}
[例7.12]有3个学生各学4门课,计算总平均分数, 以及第3个学生的成绩。程序如下:
一个数组的元素都是指针类型的数据,就称这个数组是指针数组。指针数组的定义形式为
类型标识 *数组名[元素个数];
例如:int *p[4];
由于[]比*优先级高,因此p先与[4]结合,形成p[4]形式,这是一个含有4个元素数组。然后再与p前面的*结合,*表示此数组是指针类型的,每个数组元素都可指向一个整型变量。
注意:不要写成int (*p)[4],这里p是指向一维整型数组的指针变量。
字符串本身就是由字符型数组构成的
感觉康辉c语言中的很多代码在现在的turbo3.0上和vc6.0中都执行不了啊,可能是c语言没有规范的缘故啊
指针很难理解,一碰到只指针的程序应该努力去理解,而不是一味的的逃避。
2011年7月23日 18:17:24 已经听完了27讲
编写一个函数,打印一个杨辉三角形
[例7.14] 编写一个函数,打印如图所示的杨辉三角形。
1 1
1 1 1 1
1 2 1 1 2 1
1 3 3 1 1 3 3 1
1 4 6 4 1 1 4 6 4 1
思路:a[i][0]=a[i][i]=1;
a[i][j]=a[i-1][j]+a[i-1][j-1];
sourcecode:
#include "stdio.h"
void main()
{
int a[5][5],i,j;
for(i=0;i<5;i++)
{for(j=0;j<=i;j++)
{
if(j==0||j==i)
{
a[i][j]=1;
}
else
a[i][j]=a[i-1][j]+a[i-1][j-1];
printf("%3d",a[i][j]);
}
printf("\n");
}
}
例如:
main()
{
char *string=“This is a string!”;//等价于将字符串的首地址赋给了指针变量//string
printf(“%s\n”,string);
}
其中:char *string=“This is a string!”,等价于下面两行:
char *string;
string=“This is a string!”;
字符串输入时要注意:
字符串输入可以用scanf函数。当在scanf中使用%s时,它跳过空字符直到遇见第一个非空字符,然后读进字符,直到碰见一个空字符结束。例如:输入不超过10个字符的字符串
定义的字符数组长度是11,但在此例中输入的字符串长不能超过10,否则就会出问题。最好采用%10s来限制输入字符串的长度。下面是用字符指针重写的程序。
main()
{ char *str;
str=malloc(11);
printf(“Enter a string:”);
scanf(“%10s”,str);
printf(“The string is:%s\n”,str);
}
否则当输入了超过长度的字符时出现意外:
用指针写strcpy(s,t)函数,将字符串t复制到字符串s中去:
strcpy(char s[],char t[])
{
int i=0;
while((s[i]=t[i])!='\0')
i++;
}
或者:
基本的要求得用指针写string里面常用的函数strcpy、strcmp,strcat、strlen等!
2011年7月24日 11:07:24 看到第三十讲(没有看完)
注意:
*p两侧的括号不可省略,表示p先与*结合,即p是指针变量,然后再与后面的括号结合,表示此指针变量指向函数。
最前面的类型说明用于指明函数的返回值类型。
指针变量p不是固定指向哪一个函数,而是专门用来存放函数的入口地址的。在程序中把哪一个函数的地址赋给它,它就指向哪一个函数。
在一个程序中,一个函数指针变量可以先后指向不同的函数。正如数组名代表该数组的首地址一样,函数名也代表了该函数的入口地址。
double fun(int a,int *p)
{ ··· ··· }
main()
{double (*fp)(int,int *),y;
int n;
fp=fun;
⋮
y=(*fp)(56,&n);
⋮
}
在给函数指针变量赋值时,只需给出函数名而不必给出参数,因为是将函数入口地址赋给指针变量,而不牵涉到实参与形参结合的问题 。
当用函数指针变量调用函数时,只需用(*p)代替函数名即可(p为函数指针变量名)。
应当注意的是,对指向函数的指针变量,象p+n,p++,p--等运算是无意义的 。
指向指针的指针:指向指针数据的指针变量。
例如:char **p;
p就是指向指针型数据的指针变量。
p前面有两个*号。由于*运算符是从右到左结合的,因此**p相当于*(*p)。
*p是指针变量的定义形式,**p表示指针变量p是指向一个字符指针变量的。
指向指针的指针
/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
int **p,*q,x;
x = 5;
q = &x;
p = &q;
printf("%d\n%d\n%d\n",x,*q,**p);
}
利用指针可以创建动态数组定义
当main开始执行时,可使用两个参数。
第一个参数:被调用程序所具有的命令行参数的个数;
第二个参数:指向这些参数字符串的字符串数组,每个字符串对应一个指向其首字符的字符指针。
习惯上把这两个参数记为argc和arg
C语言最重要的是指针和数组
指针小结
一、有关指针的数据类型
int *p; p为指向整型数据的指针变量
int a[n]; 定义整型数组a,它有n个元素
int *p[n]; 定义指针数组p,它有n个指向整型数据的
指针元素组成
int (*p)[n]; p为指向含n个元素的一维数组的指针变量
int f(); f为返回整型函数值的函数
int *p(); p为返回一个指针的函数,该指针指向整型数据
int (*p)();p为指向函数的指针,该函数返回一个整型值
int **p; p是一个指针变量,它指向一个指向整型数据的指针变量
二、指针运算
指针变量加(减)一个整数
例如:p++,p--,p+i,p-i,p+=i,p-=i等。
C语言规定,一个指针变量加(减)一个整数并不是简单地加(减)一个整数,而是将该指针变量的值和它指向的变量所占用的内存字节数相加(减)。
指针变量赋值
将一个变量地址赋给一个指针变量。如:
p=&a; (将变量a的地址赋给p)
p=array; (将数组array的首地址赋给p)
p=&array[i]; (将数组array第i个元素的地址赋给p)
p=max; (max为已定义的函数,将max的入口地址赋给p)
p1=p2; (p1和p2都是指针变量,将p2的值赋给p1)
指针变量可以有空值,即该指针变量不指向任何变量,可以这样表示:p=NULL;
实际上NULL是整数0,它使p的存储单元中所有二进制位均为0,也就是使p指向地址为0的单元。系统保证该单元不作它用,即有效数据的指针不指向0单元。
实际上,#define NULL 0是在头文件stdio.h中定义的。
任何指针变量或地址都可以与NULL作相等或不相等的比较。
两个指针变量可以相减
如果两个指针变量指向同一个数组的元素,则两个指针变量之差是两个指针之间的数组元素个数。但两个指针变量之和没有意义。
两个指针变量比较
若两个指针指向同一个数组的元素,则可以进行比较。指向前面元素的指针变量“小于”指向后面元素的指针变量。
注意,如果两个指针变量指向不同的数组,则比较运算没有意义。
/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
static int *p, a[] = {2,3,4,1,5,6},
b = 10;
p = a;
p+=3;
a[3] =b;
printf("%d\n",*p);
}//the answer is :10
难题:
#include<stdio.h>
int main()
{
char *p,b[10]="abcdefghi";
int i;
for(i = 0,p=b;i<10;i++)
*p++=&p+1;
p=b+5;
printf("%c",*p);
}//the answer is :H
习题:数组a由p,q,r,三段组成,设计一个程序交换数组a中的元素,使三段次序依次变为r,q,p。