入职培训笔记记录--day2续二(1、控制语句 2、数组3、二维数组 4、字符串处理函数 5、指针)

 

1、控制语句
while(表达式)
{
语句块;
}

do
{
语句块;
}while(表达式);
while先判断再执行,do while先执行,再判断,while最少一次也不执行
do while至少执行一次

break:用来跳出当前循环
continue:结束本次循环,继续下一次循环
goto:无条件跳转语句
格式:goto 语句标号;其中语句标号遵循标识符的命名规则

2、数组 --- 构造数据类型
概念:由相同数据类型组成的集合
变量定义:存储类型 数据类型 变量名;
定义:存储类型 数据类型 数组名[元素个数];
存储类型:决定了系统给数组的元素分配内存空间时的位置
数据类型:数组中每个元素的数据类型
数组名:集合的名字,遵循标识符的命名规则,数组名不能和其他变量重名
数组名:1、代表整个数组(sizeof(a)求整个数组在内存当中的字节数)

插一个打印数组 的另一种写法

printf("&d",i[a]);    //a[i]

2、数组的首地址(数组首元素的地址),为地址常量
注意:打印地址 %p
元素个数:集合中一共有多少个相同数据类型的数据
必须是一个确定的数(最好用常量)
系统给数组分配内存空间的大小:sizeof(数据类型)*元素个数
总结:数组的特点:
1、元素的数据类型相同
2、内存是连续的
数组元素的引用:数组名[下标]; 注意:下标从0开始
>>>数组的初始化
注意:数组如果是局部变量,没有初始化,该数组所有元素的值为随机值
如果用static修饰,没有初始化,其值为0
数组如果是全局变量,没有初始化,其值为0
====满数初始化
int a[5] = {1,2,3,4,5}; //a[0] = 1, a[1] = 2,a[2] = 3, a[3] = 4, a[4] = 5;
满数初始化时,元素个数可以省略
====部分初始化
int a[5] = {1,2,3}; //a[0] = 1,a[1] = 2, a[2] = 3, a[3] = 0, a[4] = 0
部分初始化时,元素个数不能省略
====赋为0
int a[5] = {0};
数组的赋值:
int a[5];
a[5] = {1,2,3,4,5}; //error a[5]为数组元素,并且不存在
a = {1,2,3,4,5}; //error a为地址常量
只能依次对每个元素赋值
练习:定义一个有10个int类型元素的数组,通过键盘给数组元素赋值,
求这个数组所有元素的和,并打印结果
冒泡排序:(一定要会)
100 88 76 98 10
第一趟:
第一次:88 100 76 98 10
第二次:88 76 100 98 10
第三次:88 76 98 100 10
第四次:88 76 98 10 100
88 76 98 10 100
第二趟:
第一次:76 88 98 10
第二次:76 88 98 10
第三次:76 88 10 98
76 88 10 98 100
第三趟:
第一次:76 88 10
第二次:76 10 88
76 10 88 98 100
第四趟:
第一次:10 76
最终结果:10 76 88 98 100

int i, j;
for(i = 0; i < N-1; i++)
{
for(j = 0; j < N-1-i; j++)
{
if(a[j] > a[j+1])
{
int tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}
字符数组初始化:
满数初始化:
char a[5] = {'a','b','c','d','\0'};
char a[5] = "abcd";
部分初始化:
char a[5] = "abc"; //a[3] = '\0', a[4] = '\0';
字符数组的赋值:
scanf("%s", a); 在输入结束时,在字符串结尾自动加‘\0’
注意:通过scanf给字符数组赋值时,不做越界检查,所以输入时应输入n-1个字符
(n为数组元素的个数)
printf("%s\n", a);//打印字符串时,遇到‘\0’输出结束
字符串输入输出函数:
char a[5]; //gets(a);
gets(数组名); //可以给字符数组赋值,也不做越界检查,用时要注意不要越界
puts(数组名); //输出字符数组的内容,遇到'\0'结束
注意:scanf以空格、回车作为结束符,但是gets只以回车作为结束符
求数组元素个数:
sizeof(数组名)/sizeof(数据类型);
或sizeof(数组名)/sizeof(a[0]);

(其实用man查看函数功能就可以了)

3、二维数组:在内存中是一维的,内存连续
可以理解为:数组的数组
存储类型 数据类型 数组名[行][列];
int a[2][3];
理解:数组a有2个元素,分别是a[0]和a[1],a[0]、a[1]又分别是两个一维的数组
并且这两个一维数组都有3个int类型的元素
总结:行号表示二维数组有几个一维数组
列号表示每个一维数组有几个元素
a为数组名,是数组首元素的地址,并且a与a[0]的值是相同的,都是&a[0][0]的地址
二维数组的初始化:
满数初始化:
int a[2][3] = {{1,2,3},{4,5,6}};
a[0][0] = 1, a[1][2] = 6
注意:行号可以省略,列号不能省略

int a[2][3] = {1,2,3,4,5,6};
部分初始化:
int a[2][3] = {{1,2}, {4}}; //a[0][0] = 1, a[0][2] = 0
int a[2][3] = {1,2,3,4}; //a[0][2] = 3, a[1][0] = 4, a[1][1] = 0
二维数组的赋值:依次对每个元素赋值
字符数组:
char a[2][10] = {"helloworl", "abcdefgh"};

4、字符串处理函数
操作的对象是字符串:1、字符串常量 eg:“hello”
2、字符数组
strlen:求字符串长度,不包含'\0'
函数原型:size_t strlen(const char *s);
参数:要操作的字符串
返回值:字符串的长度

1、字符串连接函数
头文件:#include <string.h>
函数原型:char *strcat(char *dest, const char *src);
strcat(目标字符数组, 源字符串);
函数功能:将src(源)字符串连接到dest(目标)字符串后,
连接完成后目标字符串后的'\0'就被覆盖掉了
char *strncat(char *dest, const char *src, size_t n);
功能:将源字符串的前n个字符连接到目标字符串后
注意:保证目标字符数组足够长
2、字符串拷贝函数
函数原型:char *strcpy(char *dest, const char *src);
strcpy(目标字符数组, 源字符串);
功能:将源字符串拷贝到目标字符数组中去,并且连同'\0'一同拷贝
注意:目标字符数组要足够长
char *strncpy(char *dest, const char *src, size_t n);
功能:将源字符串前n个字符拷贝到目标字符数组中去
注意:1、目标字符数组要足够长
2、目标字符数组中只是前n个字符是源字符串的,其余不变
3、字符串比较函数
比较两个字符串大小
比较规则:对两个字符串从左至右逐个字符进行比较(ASCII值),直到遇到不同的字符或者
遇到'\0'结束

函数原型:int strcmp(const char *s1, const char *s2);
strcmp(字符串1, 字符串2);
比较结果:
返回值:大于0 字符串1 > 字符串2
小于0 字符串1 < 字符串2
等于0  字符串1 == 字符串2
 int strncmp(const char *s1, const char *s2, size_t n);
 功能:比较字符串1与字符串2的前n个字符
 比较规则同上
 注意:比较字符串大小时,只能使用strcmp,不能str1 > str2
 

5、指针
地址:内存的基本单元是字节,每个字节都有一个编号,这个编号就称为地址
指针:地址也称为指针
地址就是指针,指针就是地址
指针变量:专门用来存放地址的变量
在不影响理解的情况下,指针、地址、指针变量统称为指针
定义:存储类型 数据类型 *指针变量名; 

存储类型:auto register static extern
指针变量的存储类型
数据类型:指针变量所指向的变量的数据类型
指针的类型:数据类型*
指针变量名:遵循标识符的命名规则
不管什么类型的指针在内存中都占4个字节(32位操作系统)
int a = 10;
int *p = &a;
&----地址运算符
*----指针运算符---取指针变量所指向的变量的内容
直接访问:直接变量名
间接访问:通过指针变量
>>>指针的初始化
int *p = NULL;
NULL:空指针,对应的是0号地址
表明:该指针并未指向任何对象
野指针:不知道指向哪儿
int *p;
*p = 5;//error,在定义的时候初始化为NULL
p = &a;

char b;
char *p = &b;
>>>指针的运算:本质为地址的运算
算术运算 关系运算
===算术运算 + - ++ --
p+1:相对于p,向地址增大的方向移动了一个数据
实际地址值的变化:p+sizeof(数据类型)
p+n:相对于p,向地址增大的方向移动了n个数据
实际地址值的变化:p+sizeof(数据类型)*n
p-n:相对于p,向地址减小的方向移动了n个数据
实际地址值的变化:p-sizeof(数据类型)*n
p++:p向地址增大的方向移动了一个数据,p++的值是p没自加之前的值
++p:p向地址增大的方向移动了一个数据,++p的值为p自加后的值
p--:p向地址减小的方向移动了一个数据
--p:p向地址减小的方向移动了一个数据
p-q:注意:p和q的类型必须相同
两个指针之间相隔的数据元素的个数
实际值:(p-q)/sizeof(数据类型);
总结:指针的算术运算,只有在操作连续的内存空间才有意义,所以
一般指针的算术运算用于操作数组
====关系运算
if(NULL == p)

if(NULL != p)

>>>>const修饰的指针
const----修饰的变量为只读变量
int a = 10;
//p int*类型 *p int
const int *p = &a;//const修饰*p,p可以修改,*p不能修改,a可以被修改
int *const p = &a;//const修饰p,p不能被修改,*p可以修改,a可以被修改
const int *const p = &a;//p与*p都不能被修改,a可以被修改
int b;
修饰p:p = &b;
修饰*p:*p的值不能被修改 *p = 20 error;a = 20;
规律:左数右指
>>>>void修饰的指针
int *p;
void *p; //p的类型是void*类型
*((int *)p) = 7;
void *的指针使用之前必须进行强制类型转换,因为通过指针变量操作内存空间时,不知道该操作的
范围有多大
一般void *的指针作为函数形参以及函数的返回值
void a;//error,系统不知道要给a分配多大的内存空间
>>>>二级指针:指针的指针
定义:存储类型 数据类型 **指针变量名;
存储类型:指针变量的存储类型
数据类型:指针变量所指向的指针指向的变量的类型
数据类型*:指针所指向的类型
指针变量类型:数据类型**
int **pp;//pp的类型int**

2、指针与数组
1、指针与一维数组
int a[5];
访问数组元素:a[i] <==> *(a+i)
a是数组的首地址,是地址常量,但当a遇到*及&,可以当做变量使用
int *p = a;//p指向a[0]
访问数组元素:p[i] <==> *(p+i)
总结:a[i] <==> *(a+i )<==> p[i] <==> *(p+i) <==>i[a] <==>i[p],但是a和p的本质不同,a为数组名,是地址常量,不能作为左值,并且不能进行自加自减运算
p为地址变量,可以进行这些运算  关于指针 我记录下一下这个大神http://blog.csdn.net/mikayong/article/details/7515358 

posted @ 2017-02-22 11:02  AAAron  阅读(248)  评论(0编辑  收藏  举报