一、数组语法
数组特点: 同类型数据的集合。
程序里怎么区分是数组? [ ] 访问连续地址里数据。
数组的注意特点:
1. 数组的名称是数组元素的首地址。(数组的名字就是地址)
2. 数组只能在初始化的时候进行整体赋值。比如: int a[100]={10,20,30};
3. 数组的下标访问是从0开始的。比如: int a[10]; 下标范围: a[0] ~ a[9]
4. 数组名称虽然是地址,但是这个地址是不能偏移、也不能自增自减,也不能改变指向。
int a[10];
int b[10];
a++、a--; *//* *错误的*
a=b; *//* *错误的*
a[0]=b[0]; *//* *正确*
5. 如果数组是局部变量,初始化没有赋值的情况下,成员是随机值。
比如: int a[10]; printf("%d\n",a[0]);
初始化的时给数组进行赋值,那么没有赋值的下标是什么值?
比如: int a[10]={1,2,3}; printf("%d\n",a[6]); //0
6. 数组定义的时候(C89), 数组的下标里的大小只能填常量。 比如:
int a[]; *//* *错误的,定义数组必须填大小*
int size=10; int a[size]; *//* *错误的,定义数组只能填常量。*
int b[100]; *//* *正确*
#define **SIZE** 100 int a[SIZE]; *//正确*
二、冒泡排序:整数数组
字符串特点:
- 字符串本身就是字符数组。比如:char a[10]="123";
- 常规字符串使用双引号括起来的。 比如:char a[10]="123";
- 字符串以'\0' 作为结束符号。
- 字符数组一定是字符串? 不一定。 比如: char a[]={12,3,4,5,5};
#include<stdio.h>
int main()
{
char buff1[10]={'1','2','3','\0','4','5','6','\0','7'};
char buff2[]={'1','2','3','\0'};
char buff3[]="123";
printf("%d\n",sizeof(buff2)); //4
printf("%d\n",sizeof(buff3)); //4
return 0;
}
//1. 计算字符串的长度
//2. 字符串查找函数
//3. 字符串转整数
//4. 字符串拼接
//5. 字符串拷贝
//6. 字符串比较
#include <stdio.h>
#include <string.h>
int main()
{
char buff[100];
int cnt=0;
printf("请键盘上录入字符串:");
scanf("%s",buff); // 不可以录入空格
while(buff[cnt]!='\0')
{
cnt++;
}
printf("cnt=%d\n",cnt);
return 0;
}
三、整数数组的练习作业
-
从键盘上输入10个整数,删除指定下标的数据 比如输入数据: 1,2,3,4,5,6,7,8,9,10 删除第5个下标的数据 输出的结果: 1,2,3,4,5,7,8,9,10
-
从键盘上输入10个整数,在指定下标增加一个新的数据 比如输入数据: 1,2,3,4,5,6,7,8,9,10 从第5个下标增加一个新的数据 888 输出的结果: 1,2,3,4,5,888,6,7,8,9,10
四、指针概念
指针:C语言的灵魂。 指针作用:存放地址。
//结构体的内存空间默认对齐方式: 以出现的最大数据类型的倍数申请空间。最大倍数不超过4.
struct stu
{
int a;
char c;
};
<数据类型> *<变量名称>;
int *a; //整型指针变量。 占4个字节空间。 存放地址数据。
char *b;//字符类型指针变量。占4个字节空间。 存放地址数据。
float *c; //浮点数类型指针变量。占4个字节空间。 存放地址数据。
struct stu *d;//结构体类型指针变量。 占4个字节空间。 存放地址数据。
指针没有申请有效空间的时候,可以不可以用来存放数据?
可以。 使用地址空间存放数据。 int *a; a=123;
<数据类型> <变量名称>;
int a; //整型变量 123 占4个字节空间。
char b; //字符类型变量 123和'A' 占1个字节空间。
float c; //浮点数类型变量 123.345 占4个字节空间。
struct stu d; //结构体类型变量。 占个8字节空间。
五、指针例子
5.1 例子1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *a;
int *p=NULL; //指针本身没有数据空间,只能存放地址。 NULL == (void*)0
p=malloc(4); //申请4个字节空间
*p=123; //对指针指向的空间进行赋值
printf("*p=%d\n",*p); //123
printf("p1=%d\n",p); //地址
free(p); //释放空间
p=NULL; //将指针指向NULL
printf("p2=%d\n",p); //地址
if(p!=NULL)
{
*p=456; //给指针指向的空间进行赋值
printf("*p=%d\n",*p); //123 取出指针指向空间的数据
}
a=(char*)(123456); //强制转换. 欺骗编译器。
printf("a=%d\n",a); //地址
return 0;
}
5.2 各个指针类型之间相互是否可以直接赋值?会不会溢出?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char a=0;
int b=123456;
a=b;
printf("a=%d\n",a);
printf("b=%d\n",b);
char *p_a;
int *p_b;
p_b=malloc(4);
p_a=(char*)p_b;
printf("p_a=%d\n",p_a);
printf("p_b=%d\n",p_b);
return 0;
}
5.3 各类型指针本身最大区别是什么?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
// 指针 本身偏移字节不一样(就是自增/自减)。
char c_buff[]="ABCDEF";
char *c_p=c_buff; //检查等于符号两边类型是否相同。
printf("%c\n",*(c_p+1)); // 'B'
printf("%c\n",*c_p++); // 'A'
printf("%c\n",*c_p); // 'B'
int a_buff[]={1,2,3,5,6,7,8};
int *a_p=a_buff;
printf("%d\n",*(a_p+1)); // 2
printf("%d\n",*a_p++); // 1
printf("%d\n",*a_p); // 2
//每个类型的指针自增、自减的时候 ,指针偏移量和本身类型有关系
return 0;
}
5.4 函数的变量作用域
全局变量、局部变量、静态变量、块变量。 全局变量: 在函数之外定义的变量。 局部变量: 在函数里定义的变量。 静态变量: 修饰关键字: static 也称为局部全局变量。 块变量 : 在代码块里定义的变量。
示例1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int a=100; //全局变量
//static int a; //静态全局变量
void func(void);
int main()
{
int a=200; //局部变量
if(123>30)
{
int a=300; //块变量
printf("a=%d\n",a); //300
}
printf("a=%d\n",a); //200
func();
return 0;
}
void func(void)
{
int a=400; //局部变量
// static int a; //静态局部变量
printf("a=%d\n",a); //400
}
示例2:静态变量
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int a=100; //全局变量
//static int a; //静态全局变量
void func(void);
int main()
{
int a=200; //局部变量
if(123>30)
{
int a=300; //块变量
printf("a=%d\n",a); //300
}
printf("a=%d\n",a); //200
func();
return 0;
}
void func(void)
{
int a=400; //局部变量
// static int a; //静态局部变量
printf("a=%d\n",a); //400
}
5.5 函数传参: 地址问题
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *func(char *p);
int main()
{
char a[]="1234567890";
char *p;
p=func(a);
printf("%s\n",p);//4567890
return 0;
}
//函数的形参是指针类型,返回值是指针类型
char *func(char *p) //p=a;
{
printf("%s\n",p); //1234567890
return p+3; //偏移地址
}
#if 0
/*
数组类型是当做函数的形参,但是不能当做返回值
数组当做形参也有局限性:地址不能自制、自减、访问数据只能使用[ ] ( *(p+1) )
*/
char p[] func(char p[])
{
}
#endif