赞
踩
0和1更准确的应该是高电平和低电平
10111000 00000001 00000000 00000101 00000001 00000000 //表示1+1
MOV AX,1 ADD AX,1 //表示1+1
1+1 //表示1+1
为什么要学习C语言
C语言程序是由函数组成的
C语言程序启动时,系统会自动调用名称叫做main的函数
C语言规定了函数定义的固定格式
int main()
{
return 0;
}
//main函数的其他写法
void main()
#include <stdio.h>//告诉系统去哪找到printf函数
int main()
{
printf("Hello World!\n");
return 0;
}
在C语言中,内存分为5个区,堆、栈、自由存储区、全局/静态存储区和常量存储区
文档、照片、视频
运行某个软件(程序)时,整个程序就会被加载到内存中
因为内存访问速度比硬盘快N倍,所以不会把所有的应用程序都加载到存储空间大的硬盘中
//计算各数据类型占多少字节byte
#include <stdio.h>
void main()
{
printf("%d\n",sizeof(int));
return 0;
}
//输出结果为4(byte)
1;2;3;
3.14;6.66;//双精度
10.1 f;2.31 f;//单精度 356 f与356.是等价的
‘a’; ‘1’; ‘.’;
‘ab’; ‘12’; ‘曾’; //错误
‘\n’; ‘\t’; //正确,特殊情况(转移字符)
2.1e5(等于2.1*10^5)
“a”; “ab”; “12”; “曾”;
#define 标识符(一般用大写字母) 常量
#include <stdio.h>
#define PRICE 30;
void main()
{
int num,total;
num=10;
total=num*PRICE;
printf("total=%d\n",total);
return 0;
}
内存中以二进制存储
一个字节BYTE=8位bit
sizef()计算字符类型的字节数
int a;
float b;
double c;
char d;
#include<stdio.h>
void main()
{
short int a,b;
a=32767;
b=a+1;
printf(%d,%d\n",a,b);
}
输出结果:a=32767,b=-32767
出现了数据溢出
#include<stdio.h>
void main()
{
float a,b;
a=123456.789e5;//属于double的范围
b=a+20;
printf("%f\n",a);
printf("%f\n",b);
}
输出结果:12345678848.0000
12345678848.0000
#include<stdio.h>
void main()
{
char a,b;
a=120;
b=121;
printf("%c,%c\n",a,b);
printf("%d,%d\n",a,b);
}
输出结果:x,y
120,121
#include<stdio.h>
void main()
{
int i=8;
printf("%d\n",++i);
printf("%d\n",--i);
printf("%d\n",i++);
printf("%d\n",i--);
}
输出结果:9 8 8 9
赋值运算符(自右向左)具有右结合性
变量=表达式
类型转换
实型赋予整型,舍去小数部分
逗号运算符和逗号表达式
#include<stdio.h>
void main()
{
int a=2,b=4,c=6,x,y;
y=(x=a+b),(b+c);
printf("y=%d,x=%d",x,y);
}
输出结果:y=10,x=6
头文件:#include<stdio.h>
在显示器上输出单个字符
putchar(‘A’);
putchar(‘\101’);(也是输出A)
putchar(‘\n’);(输出换行)
getchar();
char c;
c=getchar();
按用户指定的格式从键盘上把数据输入到指定的变量中
scanf(“格式控制字符串”,地址列表);地址列表:&a,&b
scanf()函数的返回值:如果两个数被读入,返回值为2;如果只有一个数被读入,返回值为1;0个数就是0;若遇到错误或遇到end of file,返回值为EOF(在C语言中是-1)
比较两个量的运算符称为关系运算符
< | 小于 |
---|---|
<= | 小于或等于 |
> | 大于 |
>= | 大于或等于 |
== | 等于 |
!= | 不等于 |
&&和||为双目运算符具有左结合性,!为单目运算符具有右结合性
优先级关系:!>&&>||
如果表达式的值为真,则执行其后的语句,否则不执行该语句
#include<stdio.h> //比较两个数的大小
void main()
{
int a,b,max;
printf("\n input two numbers: ");
scanf("%d%d",&a,&b);
max=a;
if(max<b)
max=b;
printf("max=%d",max);
}
#include<stdio.h>
void main()
{
int a,b,max;
scanf("%d%d",&a,&b);
if(a>b)
printf("max=%d",a);
else
printf("max=%d",b);
}
前两种形式一般适用于两个分支的情况,当有多个分支选择时,可采用if-else-if形式
if(表达式1)
语句1;
else if(表达式2)
语句2;
……
else
语句n;
#include<stdio.h> //输入三个数a b c,要求按从小到大的顺序输出 void main() { int a,b,c,d; scanf("%d %d %d",&a,&b,&c); if(b>a) { d=b; b=a; a=d; } else if(c>a) { d=c; c=a; a=d; } else if(c>b) { d=c; c=b; b=d; } printf("%d,%d,%d",a,b,c); }
表达式1?表达式2:表达式3
条件语句:
if(a>b)
max=a;
else
max=b;
条件表达式:
max=(a>b)?a:b
如a>b为真,则把a赋予max,否则把b赋予max
switch(表达式)
{
case常量表达式1:语句1;break;
case常量表达式2:语句2;break;
……
case常量表达式n:语句n;break;
default :语句n+1;
}
若没有break,所有语句都将实行
在使用switch语句应注意:
- 在case后的各常量表达式的值不能相同
- 在case后,允许有多个语句,可以不用{}括起来
- 各case和default子句的先后顺序可以变动,而不会影响程序执行结果
- default子句可以省略
#include<stdio.h> //输入三个整数,输出最大数和最小数 void main() { int a,b,c; scanf("%d,%d,%d",&a,&b,&c); switch() { case 1(a>b>c) { printf("max=%d,min=%d",a,c); break; } case 2(b>c>a) { printf("max=%d,min=%d",b,a); break; } case 3(a>c>b) { printf("max=%d,min=%d",a,c); break; } case 4(b>a>c) { printf("max=%d,min=%d",b,c); break; } case 5(c>a>b) { printf("max=%d,min=%d",c,b); break; } case 6(c>b>a) { printf("max=%d,min=%d",c,a); break; } } }
循环结构是程序中一种很重要的结构,在给定条件成立时,反复执行某程序段,直到条件不成立为止。
goto语句是一种无条件转移语句
goto 语句标号:
goto语句通常不用,主要是因为它将使程序层次不清,且不易读,但在多层嵌套退出时,用goto语句则比较合理
#include<stdio.h> //用goto语句和if语句构成循环来计算1+2+……+100的值
void main()
{
int i,sum=0;
i=1;
loop:if(i<=100)
{
sum+=i;
i++;
goto loop;
}
printf("%d\n",sum);
}
while(表达式)语句
表达式是循环条件,语句为循环体
如果表达式的值一开始就为0,则语句一次也不会被执行
#include<stdio.h> //while语句构成循环来计算1+2+……+100的值
void main()
{
int i=1,sum=0;
while(i<=100)
{
sum+=i;
i++;
}
printf("%d",sum);
}
#include<stdio.h> //统计从键盘输入一行字符的个数
void main()
{
int n=0;
while(getchar()!='\n')
{
n++;
}
printf("%d",n);
}
do
语句
while(表达式);
与while的区别在于:它先执行循环中的语句,再判断表达式是否为真,为真继续循环,若假则终止循环。
do-while至少执行一次循环语句
for(表达式1[循环变量赋初值];表达式2[循环条件];表达式3[循环变量增量])语句;
- 先求解表达式1
- 求解表达式2,若其值为真,则执行for语句中指定的内嵌语句,然后执行第3步;若为假,结束循环转到第5步
- 求解表达式3
- 转回上面第2步,继续执行
- 循环结束,执行for语句下面的程序
eg:
for(i=1;i<=100;i++)
{
sum+=i;
}
注意
表达式1/2/3都可以省略,但==;==不能省略
省略表达式1,表示不对循环控制变量赋初值
省略表达式2,则不做其他处理时该循环变成死循环
省略表达式3,则不对循环控制变量进行操作,可在语句中加入修改循环控制变量的语句
3个表达式都可以省略
for(; ; ;)
相当于while(1)语句
#include<stdio.h>
void main()
{
int i,j;
for(j=1;j<=6;j++)
{
printf("\n");
for(i=1;i<=j;i++)
{
printf("*");
}
}
}
break语句:
break语句用来从循环体中跳出循环体,提前结束循环
break只能用于switch语句和循环语句
在多层循环中,一个break语句只向外跳一层
continue语句
作为结束本次循环,跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判断
区别:
continue只结束本次循环,而不是终止整个循环的执行
break语句是结束整个循环过程,不再判断循环的条件是否成立
#include<stdio.h> //显示输入字符,如果按Esc,则退出循环;如果按Enter键,则不做任何处理 #include<conio.h> //后边getch函数和putch函数需要 void main() { char ch; for(;;) { ch=getch(); //字符输入函数 if(ch==27) //Esc键的ACSII码为27 break; if(ch==13) //Enter键的ACSII码为13 continue; putch(ch); //显示输入字符 } getch(); //让程序停一下,按任意键继续 }
定义方式
int a[10]; //定义了一个整型数组,数组名为a,此数组有10个元素,10个元素都是整型变量
int a,b,c=2,d,k1[10],k2[20]; //同一数据类型,可直接定义多个数组和多个变量
int n;
scanf("%d",&n); //在程序中临时输入数组的大小
int a[n];
引用方式
a[0]=a[5]+a[7]-a[2*3];
a[i+j];
a[i++];
例:
#include <stdio.h>
int main()
{
int i,a[10];
for(i=0;i<=9;i++) //给数组a[10]中每个元素赋值
{
a[i]=i;
}
for(i=9;i>=0;i--)
{
printf("%d",a[i]); //倒序输出数组
}
}
输出结果:9 8 7 6 5 4 3 2 1 0
#include <stdio.h> #define N 10 int main() { int temp,i,a[N]; for(i=0;i<N;i++) { scanf("%d",&a[i]); } for(i=0;i<N-1;i++) { if(a[i]>a[i+1]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; } } for(i=0;i<N;i++) { printf("%d",a[i]); } return 0; }
一维数组的初始化
在定义数组的同时,给元素赋值
int a[10]={0,1,2,3,4,5,6,7,8,9};
int a[10]={0,1,2,3,4};
int a[10]={0,0,0,0,0,0,0,0,0,0};
int a[5]={1,2,3,4,5};
例:
有10个数,要求对它们按由小到大的顺序排列。(起泡法:大数沉淀,小数气泡)
#include <stdio.h>
#define N 10
int main()
{
int a[N],temp,i;
}
二维数组的定义
float a [3] [4],b [5] [10]; //定义a为3*4的数组,b为5*10的数组
可以把二维数组看成是一种特殊的一维数组,如a有三个元素a[0],a[1],a[2],每个元素又是一个包含4个元素的一维数组
在实际硬件储存器中是连续编址的,就是储存器单元是按一维线性排列的
衍生:多维数组的定义
定义三维数组:float a[2] [3] [4];
多维数组元素在内存中的排列顺序:第一维的下标变化最慢,最右边的下标变化最快
二维数组的引用和初始化
四种方法
- 直接分行给二维数组赋初值:int a [3] [4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
- int a [3] [4]={1,2,3,4,5,6,7,8,9,10,11,12};
- 可以对部分元素赋初值:int a [3] [4]={{1},{5},{9}};//这样初始化的元素是每一行的第一个
或者 int a [3] [4]={{1},{0,6},{0,0,11}};
- 如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的不可省int a [] [4]={1,2,3,4,5,6,7,8,9,10,11,12};
例题
学习小组有5个人,有三门课的考试成绩,求全组分科的平均成绩和总平均成绩
张 | 王 | 李 | 赵 | 周 | |
---|---|---|---|---|---|
Math | 80 | 61 | 59 | 85 | 76 |
C | 75 | 65 | 63 | 87 | 77 |
English | 92 | 71 | 70 | 90 | 85 |
#include<stdio.h> void main() { int a[5][3]={{80,75,92},{61,65,71},{59,63,70},{85,87,90},{76,77,85}}; int i,j,s=0,average,v[3]; for(i=0;i<3;i++) //外循环递增慢 { for(j=0;j<5;j++) //内循环递增快 { s+=a[j][i]; } v[i]=s/5; s=0; } average=(v[1]+v[2]+v[3])/3; printf("Math:%d\nC:%d\nEnglish:%d\n",v[1],v[2],v[3]); printf("average:%d\n",average); }
二分法
利用数组进行数据查找——二分法(折半查找法)
在一批有序数据中查找某数
选定这批数据中居于中间位置的一个数与所查找数比较,看是否为所查找数,若不是,利用数据的有序性,可以决定所查找的数是在选定的数之前还是之后——缩小一半查找范围
#include<stdio.h> #define M 10 //宏定义 viod main() { static int a[M]={-12,0,6,16,23,56,80,100,110,115}; int n,low,mid,high,found; low=0; high=M-1; found=0; printf("Input a number to be searched:"); scanf("%d",&n);//以上程序为预处理 while(low<high) { mid=(low+high)/2; if(n==a[mid]) { found=1; break;//找到该数,结束循环 } else if(n<a[mid]) { low=mid+1; } else high=mid-1; } if(found=1) { printf("The index of %d is %d",n,mid); } else { printf("There is not %d",n); } }
一个较大的程序可以分为若干个程序模块,每个模块用来实现一个特定的功能
由主函数调用其他函数,其他函数也可以互相调用,同一个函数可以被一个或多个函数调用多次
eg:
#include<stdio.h> void main() { void printstar(); //函数声明 void print_message(); printstar(); //调用函数 print_message(); printstar(); //同一个函数可以调用多次 } void printstar() //定义函数 { printf("**************\n"); } void print_message() { printf("Hello world!\n"); }
从用户使用的角度看,函数有两种:①标准函数(库函数)由系统提供,不用自己定义(如printf()等)②用户自己定义的函数,用以解决用户的专门需要
从函数形式看,分为两类:①无参数函数(如printstar())主函数不向被调用函数传递数据,一般用来执行指定的一组操作。②有参数函数主调函数在调用被调用函数时,通过参数向被调用函数传递数据,一般情况下执行被调用函数时会得到一个函数值,供主函数使用
定义无参数函数的一般形式:
类型标识符 函数名()
{
声明部分
语句部分
}
定义有参数函数的一般形式:
类型标识符 函数名(形式参数表列)
{
声明部分
语句部分
}
int max(int x,int y);
{
int z; //函数体中的声明部分
z=x>y?x:y;
return z;
}
定义空函数的一般形式:
类型标识符 函数名()
{ }
int dummy()
{}
该函数没有任何实际作用,在主函数中写上一个空函数,表明“这里要调用一个函数”,等以后扩充函数功能时补充上
#include<stdio.h>
void main()
{
int max(int x,int y);//形参
int a,b,c;
scanf("%d,%d",&a,&b,);
c=max(a,b);//实参
printf("Max is %d",c);
}
int max(int x,int y);
{
int z;
z=X>y?x:y;
return z;
}
希望通过函数调用使主调函数能得到一个确定的值,这就是函数的返回值
- 函数的返回值是通过函数中return语句获得的:
return语句将被调用函数中的一个确定的值带回主调函数中去;一个函数可以有一个或以上的return语句,执行到哪个语句,哪个语句起作用;return后面还可以是表达式
- 函数的返回值应属于某个确定的类型
- 在定义函数时指定的函数类型一般应该和return语句中的表达式类型一致,若不一致,则以函数类型为准
- 不带回值的函数,应当用void(在这种函数体内不能出现return语句)
函数名(实参表列)
多个实参,用逗号隔开,此时对实参求值的顺序并不确定,有自左向右也有自右向左
#include<stdio.h> void main()//stdcall(自右向左) { int f(int a,int b); int i=2,p; p=f(i,++i); printf("%d\n",p); } int f(int a,int b) { int c; if(a>b) { c=1; } else if(a==b) { c=0; } else c=-1; return c; }
根据输出结果来判断函数调用实参的顺序,输出结果为0,则为自右向左调用;输出结果为-1,则为自左向右
按函数在程序中出现的位置来分,有三种函数调用方式
定义一个函数时,其函数体内又包含另一个完整的函数定义但C语言不能嵌套定义函数,只可以嵌套调用函数
main()
{
a();
}
a()
{
b();
}
b()
{
return;
}
#include<stdio.h> //计算s=1^2!+2^2!+3^2! long square(int x) //计算平方的函数 { int a; a=x*x; return a; } long factorial(int y) //计算阶乘的函数 { int b=1,i; for(i=1;i<=y;i++) { b=b*i; } return b; } void main() { long square(int x); long factorial(int y); int m=1,s=0; for(m=1;m<=3;m++) { s=s+factorial(square(m)); } printf("s=1^2!+2^2!+3^2!=%d",s); }
在调用一个函数的过程中又出现直接或间接地调用该函数本身,成为函数的递归调用
int f(int x)
{
int y,z;
z=f(y);
return (2*z);
}
递归必须要有一个退出的条件
例题:汉诺塔问题
有个老和尚想把64个盘子从A移到C,但每次只能移动一个盘子,且在移动过程中在ABC都保持大盘在下小盘在上,要求编程序打印出移动的步骤
移动3个盘子的步骤为:A->C,A->B,C->B,A->C,B->A,B->C,A->C
将n个盘子从A移到C可以分解为:
#include<stdio.h> void hanoi(int n,char A,char B,char C) { void move(char x,char y); if(n==1) { move(A,C); } else { hanoi(n-1,A,C,B); move(A,C); hanoi(n-1,B,A,C); } } void move(char x,char y) { printf("%c-->%c\n",x,y) } void main() { void hanoi(int n,char A,char B,char C); int m; printf("input the number of the plates:"); scanf("%d\n",&m); printf("the staps to move plates from A to B is") hanoi(m,'A','B','C'); }
数组可以作为函数的参数使用,进行数据传送。
①把数组元素作为实参使用
②把数组名作为函数的形参和实参使用,不是进行值传递,而是址传递
#include<stdio.h>//数组元素作为实参的例子 void main() { int a[10]={1,2,3,4,-1,-2,-3,-4,2,3}; int i; for(i=0;i<10;i++) { test(a[i]); } printf("\n"); } void test(int x) { if(x>0) { printf("%d",x); } else { printf("%d",0); } }
数据的传送
数组名就是数组的首地址,在数组名作为函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名
形参数组名取得首地址之后,也就等于有了实在的数组,实际上是形参数组和实参数组为同一个数组,共同拥有同一段内存空间
#include<stdio.h> //数组名作函数参数的例子 void test(int b[10]); void main() { int a[10]={2,4,6,8,10,12,14,16,18,20}; test(a); putchar('\n'); } void test(int b[10]) { int i=0; for(;i<10;i++) { printf("%d",b[i]); } }
在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,在函数外不可使用该变量
- 主函数中定义的变量也只能在主函数中使用,主函数不可以使用其他函数定义的变量
- 不同的函数可以使用名称相同的变量,彼此互不干扰
- 形参也是局部变量
- 在一些函数内部,可以在复合语句中定义变量,这些变量只在复合语句中有效(for(int i;i<10;i++))也可称为分程序块和程序块
在函数外定义的变量是全局变量(全程变量),可以被本文件中的函数所共用,它的有效范围是从定义变量的位置开始到本源文件结束
建议不必要时不要使用全局变量
从变量值存在的时间角度来分,可以分为静态存储方式和动态存储方式
静态存储方式在程序运行开始时由系统分配固定的存储空间的方式
动态存储方式在程序运行期间根据需要进行动态的分配存储空间的方式
每个变量和函数有两个属性:数据类型和存储类别
包括:自动的(auto),静态的(static),寄存器的(register),外部的(extern)
一般情况下,变量(包括静态存储方式和动态存储方式)的值是存放在内存中的。
为提高执行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取。
外部变量即全局变量,有时需要用extern来声明外部变量,以扩展外部变量的作用域
内存的每一个字节有一个编号,这就是“地址”。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元
在C语言中,对变量的访问有两种方式:一种是直接访问,一种间接访问
直接访问:a=5;
间接访问:scanf(“%d”,&a); 先把地址保存到一个单元中,在把从键盘接收到的数据储存的地址保存到a变量中
在C语言中,指针是一种特殊的变量,它是存放地址的。假设我们定义了一个指针变量int i_pointer用来存放整型变量i的地址可以通过语句:i_pointer=&i;
*:叫做取值操作符
&:叫做取址操作符
知道了一个变量的地址,就可以通过这个地址来访问这个变量,因此,又把这个变量的地址称为该变量的指针
C语言中可以定义一类特殊的变量,这些变量专门用来存放变量的地址,指针变量
指针变量中存放的值是地址,这个地址就是指针
定义一个指针变量“*”
float *pointer_3;
char *pointer_4;
可以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向一个变量
若pointer_1=pointer_2;则在pointer_1中存放的就不是&i而是&j
指针变量的引用“&”
指针变量中只能存放地址(指针)不要将一个整数(或其他非地址类型的数据)赋值给一个指针变量,否则编译器也会把该值当成一个地址来处理
进一步说明
如果已执行pointer_1=&a
&和*的优先级相同,但按照自右向左结合,先进行 *pointer_1的运算,就是变量a,再执行&运算,因此&*pointer_1与&a相同,即变量a的地址
先进行&a的运算,得到a的地址,再进行*运算,即&a所指向 的变量,也就是变量a, &a和pointer_1的作用是一样的
#include<stdio.h> //输入a和b两个整数,按先大后小的顺序输出a和b void main() { int *p1,*p2,*p,a,b; scanf("%d %d",&a,&b); p1=&a; p2=&b; if(a<b) { p=p1; p1=p2; p2=p; } printf("a=%d,b=%d\n",a,b); //ab的值不变,p1,p2指向的值不同 printf("max=%d,min=%d\n",*p1,*p2); }
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址
指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)
数组元素的指针就是数组元素的地址
p=&a[0]; 把a[0]元素的地址赋给指针变量p,也就是使p指向a数组的第0号元素
下标法,a[i]的形式
指针法,*a(a+i) 或 *(p+i)
数组名即为第一个元素的地址
eg.输出数组中的全部元素
假设有一个a数组,整型,有10个元素。要输出各元素的值有三种方法
(1)下标法
#include<stdio.h>
void main()
{
int a[10];
int i;
for(i=0;i<10;i++)
{
scanf("%d",&a[i]);
}
printf("\n");
for(i=0;i<10;i++)
{
printf("%d",&a[i]);
}
}
(2)通过数组名计算数组元素的地址,找出元素的值
#include<stdio.h>
void main()
{
int a[10];
int i;
for(i=0;i<10;i++)
{
scanf("%d",&a[i]);
}
printf("\n");
for(i=0;i<10;i++)
{
printf("%d",*(a+i));
}
}
(3)用指针变量指向数组元素
#include<stdio.h> void main() { int a[10]; int i; int *p; for(i=0;i<10;i++) { scanf("%d",&a[i]); } printf("\n"); for(p=a;p<(a+10);p++) { printf("%d",*p); } }
多维数组的指针比一维数组的指针要复杂一些
内存中数据存放
表示形式 | 含义 | 地址 |
---|---|---|
a | 二维数组名,指向一维数组a[0],即0行首地址 | 2000 |
a[0],*(a+0), *a | 0行0列元素地址 | 2000 |
a+1,&a[1] | 1行首地址 | 2016 |
a[1],*(a+1) | 1行0列元素a[1] [0]的地址 | 2016 |
A[1]+2,*(a+1)+2,&a[1] [2] | 1行2列元素a[1] [2]的地址 | 2024 |
*(a[1]+2), *( *(a+1)+2),a[1] [2] | 1行2列元素a[1] [2]的值 | 元素值为13 |
指向多维数组元素的指针变量
把二维数组a分解为一维数组a[0],a[1],a[2]之后,设p为指向二维数组的指针变量。可定义为:*int( p)[4]
它表示p是一个指针变量,它指向包含4个元素的一维数组。若指向第一个一维数组a[0],其值等于a,a[0],或&a[0] [0]等。
而p+i则指向一维数组a[i]
*(p+i)+j是二维数组i行j列的元素地址,而==*( *(p+i)+j)==则是i行j列元素的值
类型说明符 (*指针变量名)[长度]
通过输入指定行数和列数打印出二维数组对应任一行任一列的值
#include<stdio.h> void main() { int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4],i,j; p=a; printf("i="); scanf("%d",&i); while(i>2||i<0) { printf("i="); scanf("%d",&i); } printf("j="); scanf("%d",&j); while(j>3||j<0) { printf("j="); scanf("%d",&j); } printf("a[%d][%d]=%d",i,j,*(*(p+1)+j)); }
char *string=‘I love u’
可以用下标法,也可以用指针的方法
下标法举例
将字符串a复制为字符串b
#include<stdio.h> void main() { char a[]="I love u!",b[40]; int i; for(i=0;*(a+i)!='\0';i++) { *(b+i)=*(a+1) } *(b+i)='\0'; printf("String a is:%s\n",a); printf("String b is:"); for(i=0;b[i]!='\0';i++) { printf("%c",b[i]); } }
指针法举例
将字符串a复制为字符串b
#include<stdio.h> void main() { char a[]="I love u!",b[40],*p1,*p2; int i; p1=a; p2=b; for(;*p1!='\0';p1++,p2++) { *p2=*p1; } *p2='\0'; printf("String a is :%s",a); printf("String b is:"); for(i=0;b[i]!='\0';i++) { printf("%c",b[i]); } }
字符数组和字符指针变量都能实现字符串的存储和运算,但二者之间是有区别的
对应任一行任一列的值
#include<stdio.h> void main() { int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4],i,j; p=a; printf("i="); scanf("%d",&i); while(i>2||i<0) { printf("i="); scanf("%d",&i); } printf("j="); scanf("%d",&j); while(j>3||j<0) { printf("j="); scanf("%d",&j); } printf("a[%d][%d]=%d",i,j,*(*(p+1)+j)); }
char *string=‘I love u’
可以用下标法,也可以用指针的方法
下标法举例
将字符串a复制为字符串b
#include<stdio.h> void main() { char a[]="I love u!",b[40]; int i; for(i=0;*(a+i)!='\0';i++) { *(b+i)=*(a+1) } *(b+i)='\0'; printf("String a is:%s\n",a); printf("String b is:"); for(i=0;b[i]!='\0';i++) { printf("%c",b[i]); } }
指针法举例
将字符串a复制为字符串b
#include<stdio.h> void main() { char a[]="I love u!",b[40],*p1,*p2; int i; p1=a; p2=b; for(;*p1!='\0';p1++,p2++) { *p2=*p1; } *p2='\0'; printf("String a is :%s",a); printf("String b is:"); for(i=0;b[i]!='\0';i++) { printf("%c",b[i]); } }
字符数组和字符指针变量都能实现字符串的存储和运算,但二者之间是有区别的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。