C语言程序与指针
1.数组
构造数据类型之一
数组是具有一定顺序关系的若干个变量的集合,组成数组的各个变量称为数组的元素。
数组中各元素的数据类型要求相同,用数组名和下标确定。数组可以是一维的,也可以是多维的。
在科学计算中,许多重要的应用都是基于数组的。
2.一维数组定义:所谓一维数组是指只有一个下标的数组。它在计算机的内存中是连续存储的。
3.数组编译时分配连续的内存,内存的字节数是数组维数
4.数组引用中需注意的事项: 数组必须先定义后使用;只能逐个引用数组,不能一次引用整个数组
5. 数组不初始化,其元素值为随机数
对static数组元素不赋初值,系统会自动赋以0值
只给部分数组元素赋初值
当全部数组元素赋初值时,可不指定数组长度
int a[5]={1,2,3,4,5};定义的时候进行初始化
6.冒泡排序
排序过程:
(1)比较第一个数与第二个数,若为逆序a[0]>a[1],则交换;然后比较第二个数与第三个数;依次类推,直至第n-1个数和第n个数比较为止——第一趟冒泡排序,结果最大的数被安置在最后一个元素位置上
(2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在
(3)第n-1个元素位置
(3)重复上述过程,共经过n-1趟冒泡排序后,排序结束
7.选择排序
排序过程:
(1)首先通过n-1次比较,从n个数中找出最小的, 将它与第一个数交换—第一趟选择排序,结果最小的数被安置在第一个元素位置上
(2)再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录,将它与第二个数交换—第二趟选择排序
(3)重复上述过程,共经过n-1趟排序后,排序结束
8.二维数组:按元素排列顺序初始化(内存是一维的)
9.int a[3][4] 包含3个元素a[0],a[1],a[2]//每个元素a[i]由包含4个元素的一维数组组成
10.二维数组初始化:int a[][3]={1,2,3,4,5};
11.字符数组char c[10], ch[3][4]
初始化:逐个字符赋值,用字符串常量 char ch[6]={“Hello”}; char ch[6]=“Hello”;char ch[]=“Hello”
char a[]={'h','e','l','\0','l','o','\0'};//用“%s”输出时遇‘\0’结束;scanf中%s输入时,遇空格或回车结束
12.二维字符数组初始化char fruit[][7]={“Apple”,”Orange”, ”Grape”,”Pear”,”Peach”};
13.hello共5个字符,在内存占6个字节(包括\0) , 字符串长度5
14.数组中有多个‘\0’时,遇第一个结束
15.Strcpy字符数组1必须足够大拷贝时‘\0’一同拷贝不能使用赋值语句为一个字符数组赋值
16.strcat(字符数组1,字符数组2)字符数组1必须足够大连接前,两串均以‘\0’结束;连接后,串1的‘\0’取消 新串最后加‘\0,
17.Strcmp比较规则:对两串从左向右逐个字符比较(ASCII码),
18. 直到遇到不同字符或‘\0’为止
19.返值:返回int型整数,a. 若字符串1< 字符串2, 返回负整数 b. 若字符串1> 字符串2, 返回正整数 c. 若字符串1== 字符串2, 返回零说明:字符串比较不能用“==”,必须用strcmp
20.strlen(返回字符串实际长度,不包括‘\0’,遇到’\0’结束)在内
21.指针:内存(内部存储器)单元的地址称为指针,专门用来存放地址的变量,称为指针变量(pointer variable)。在不影响理解的情况中,有时对地址、指针和指针变量不区分,通称指针
22.内存中每个字节有一个编号-----地址,编译或函数调用时为其分配
内存单元,变量是对程序中数据存储空间的抽象
23.&含义: 取变量的地址,*含义: 取指针所指向变量的内容
24.i_pointer-----指针变量,它的内容是地址量
*i_pointer----指针的目标变量,它的内容是数据
&i_pointer---指针变量占用内存的地址
25.所谓空指针就是指针变量的内容为零的状态,注意:空指针并不是指针存储器为空或没有的概念,而是指针存放着特定的值—零值
26.指针变量:char *pName指针的存储类型是指针变量本身的存储类型。
指针说明时指定的数据类型不是指针变量本身的数据类型,而是指针目标的数据类型。简称为指针的数据类型。
具有相同存储类型和数据类型的指针可以在一个说明语句中说明
27.指针变量初始化:int a, *pa=&a ;
28.
29.两指针相减的结果值不是地址量,而是一个整数值,表示两指针之间相隔数据的个数
30.指针与地址:一维数组的数组名为一维数组的指针
31.指针变量和数组的指针(或叫数组名)在本质上不同,指针变量是地址变量,而数组的指针是地址常量
32.指针与字符串
char数据类型的指针变量称为字符指针变量
33.在程序中,初始化字符指针是把内存中字符串的首地址赋予指针,并不是把该字符串复制到指针中。 另外,向字符指针赋给一个字符串常量时,指针应该指向一个存储空间。
34.指针与数组
在C语言中,数组的指针是指数组在内存中的起始地址,数组元素的地址是指数组元素在内存中的起始地址。
一维数组的数组名为一维数组的指针(起始地址)。 例如double x[8];因此,x为x数组的起始地址。
数组a为起始地址,指针保存内存单元的地址,所以P和a等同p[0],p[1]...
a[i] <=>p[i],*(a+i)<=>*(p+i)
设指针变量px的地址值等于数组指针x(即指针变量px指向数组的首元数),则:
x[i] 、*(px+i)、*(x+i) 和px[i]具有完全相同的功能:访问数组第i+1个数组元素。
注意:指针变量和数组在访问数组中元素时,一定条件下其使用方法具有相同的形式,因为指针变量和数组名都是地址量。但指针变量和数组的指针(或叫数组名)在本质上不同,指针变量是地址变量,而数组的指针是地址常量
所谓指针数组是指由若干个具有相同存储类型和数据类型的指针变量构成的集合。
指针变量数组的一般说明形式:
<存储类型> <数据类型> *<指针变量数组名>[<大小>];
指针数组名就表示该指针数组的存储首地址,即指针数组名为数组的指针。
若说明一个指针数组://指针数组二维:数组的首地址赋值:
main()
{ int b[2][3],*pb[2];
pb[0]=b[0];
pb[1]=b[1];
……..
}
初始化:
main()
{ int b[2][3],*pb[ ]={&b[0],&b[1]};
……..
}
double *pa[2] ;
把一维数组a[0]和a[1]的首地址分别赋予指针变量数组的数组元数pa[0]和pa[1]:
pa[0]=a[0] ; // 等价pa[0] = &a[0][0];
pa[1]=a[1]; // 等价pa[1] = &a[1][0];
则pa[0]和pa[1]两个指针分别指向了两个一维数组a[0]和a[1]。这时我们可以通过两个指针pa[0]和pa[1]对二维数组中的数据进行处理。
指针与二维数组(二维数组从a[0][0],a[0][1],a[0][2]...开始往下存储)
(1)a是数组名,包含三个元素 a[0],a[1],a[2]
(2)每个元素a[i]又是一个一维数组,包含4个元素
a[0]+1=*(a+0)+1//代表a[0][1]
*(a[0]+1) = *(*(a+0)+1)//数组名做指针用*(a+0)代表a[0]
字符指针与字符串
在程序中,初始化字符指针是把内存中字符串的首地址赋予指针,并不是把该字符串复制到指针中。 另外,向字符指针赋给一个字符串常量时,指针应该指向一个存储空间。
在C编程中,当一个字符指针初始化为指向一个字符串常量时,不能对字符指针变量的目标赋值。
指针总结
1.指针保存地址
2.指针即地址(内存单元的地址)
Char *p = &a;
*表示指针标志
Char a[10];
Char *p = a;
a[1];*(a+1),*(p+1)
3指针和二位数组
数组指针: char (*p)[10];//着重点指针
Char a[10][10];
P = a;
*(*(p+1)+1) *(p[1]+1) a[1]a[1]//一个指针对应一个方括号
指针数组:char *p[10];//着重点数组
所谓指针数组是指由若干个具有相同存储类型和数据类型的指针变量构成的集合
Char *p[2]={“abc”,”def”};
pa[0]=a[0] ; // 等价pa[0] = &a[0][0];
pa[1]=a[1]; // 等价pa[1] = &a[1][0];
4指针数组赋值与初始化
赋值:
main()
{ int b[2][3],*pb[2];
pb[0]=b[0];
pb[1]=b[1];
……..
}
初始化:
main()
{ int b[2][3],*pb[ ]={&b[0],&b[1]};
……..
}
函数指针和指针函数
初始化:
main()
{ int b[2][3],*pb[ ]={&b[0],&b[1]};
……..
}
5.我们把一个指向指针变量的指针变量,称为多级指针变量
二级指针变量的说明形式如下:
<存储类型> <数据类型> ** <指针名>
6.const型指针:const <数据类型>*<指针变量名称>[= <指针运算表达式>] ;
const类型修饰符可以将指针变量常量化
常量化指针目标是限制通过指针改变其目标的数值。
<数据类型> *const <指针变量名称>= <指针运算表达式>;
常量化指针变量,使得<指针变量>的地址值不能修改。但可以通过 *<指针变量名称> 可以修改指针所指向变量的数值
常量化指针变量及其目标表达式
一般说明形式如下:
const <数据类型> * const <指针变量名> = <指针运算表达式> ;
常量化指针变量及其目标表达式,使得既不可以修改<指针变量>的地址,也不可以通过*<指针变量名称>修改指针所指向变量的值
7.Void 型指针
void型的指针变量是一种不确定数据类型的指针变量,它可以通过强制类型转换让该变量指向任何数据类型的变量或数组。在没有强制类型转换之前,void型指针变量不能进行任何指针的算术运算
一般形式为:
void *<指针变量名称>
8.函数指针//指针函数
函数指针是指向函数的指针变量
C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址
有了指向函数的指针变量后,可用该指针变量调用函数
函数指针有两个用途:调用函数和做函数的参数。
数据类型标志符(指针变量名)(形参列表);不过注意,指向函数的指针变量没有++和-- -运算,用时要小心
#include <stdio.h>
void say_hello(const char *str)
{
printf("Hello %s\n", str);
}
int main(void)
{
void (*f)(const char *) = say_hello;
f("Guys");
return 0;
}
题目:通过编程实现,统计0~n有多少个9 (0~n逐个判断有多少9)
提示:n通过参数传入
#include <stdio.h>
int main()
{
int m;
scanf ("%d",&m);
int i;
int temp;
int count = 0;
for (i = 0; i < =m; i++)
{
temp = i;
while (temp)
{
if (temp % 9 == 0)
{
count++;
}
temp = temp / 10;
}
}
printf("count = %d\n",count);
return 0;
}
//冒泡(一对对进行比较)
//例子:9 8 7 6 5第一次比较结果8 7 6 5 9共比较4次(每次对尾找到最大的那个数)
//1 19 7 8 4 其排序结果 1 7 8 4 19
#include <stdio.h>
#define N 5
int main()
{
int a[N] ;
int i;
for (i = 0; i < N; i++)
{
scanf("%d",&a[i]);
}
int t;
int j;
for (i = 0; i < N-1; i++)//N-1为循环次数
{
for (j =0;j < N-1-i;j++)//循环次数
{
if (a[j] > a[j+1])
{
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
for (i = 0; i < N; i++)
{
printf("%d\t",a[i]);
}
return 0;
}
//选择排序
#include <stdio.h>
int main()
{
int a[10];
int i;
for (i = 0; i<10;i++)
{
scanf("%d",&a[i]);
}
int j;
int min;
for (i = 0; i < 9; i++)
{
int temp;
min = i;
for (j = i+1; j<10;j++)
{
if (a[min] > a[j])
{
min = j;
}
}
if (min != i)
{
temp = a[min];
a[min] = a[i];
a[i] = temp;
}
printf("第i趟排序结果:\n");
int k;
for (k =0; k < 10; k++)
{
printf("%4d",a[k]);
}
}
for (i =0; i < 10; i++)
{
printf("%4d",a[i]);
}
printf("\n");
return 0;
}