———Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ———
一、数组
1、 数组的定义
类型 数组名[元素个数];
数组元素是有序的,每个元素都有一个唯一的下标,下标从0开始。
2、 数组的初始化
int count = 5;
int ages[count];
ages[0] = 1;
ages[1] = 2;
如果想在定义数组的同时进行初始化,数组元素的个数必须是常量,或不写。
正确写法:
int ages[5] = {1, 2, 3};
int ages[5] = {[3] = 3, [4] = 4};
int ages[] = {1, 2, 3};
错误写法:
int ages[];
int ages[count] = {1, 2, 3};
int ages[5];
ages = {1, 2, 3};
3、计算元素个数
int count = sizeof (ages) / sizeof (int);
4、数组的内存分析
数组的内存分配是从高地址到低地址进行的,但一个数组内部元素又是从低到高进行的。
(低地址分配低下标元素,高地址分配高下标元素)
int ages[5] = {1, 2, 3, 4, 5};
输出数组的地址(即首元素的地址):
//数组名代表数组地址,不用&符号
printf("%p\n", ages);
输出数组各元素地址:
for (int i = 0; i < 5; i++)
{
printf("ages[%d]的地址是:%p\n", i, &ages[i]);
}
5、 数组当做函数参数
数组作为函数参数时,元素个数可以省略不写。
把数组名作为实参传递给函数,传递给形参的是数组所在的首地址,是地址传递。
在函数内部修改数组的元素内容,会影响函数外部的数组内容。
6、 二维数组
类型 数组名[行数][列数];
二维数组是一个特殊的一维数组,它的元素是一维数组。
例: int a[2][3] = {{1, 2, 3},{4, 5, 6}};
/*小明从2006年1月1日开始,每三天结识一个美女两天结识一个帅哥,编程实现当输入
2006年1月1日之后的任意一天,输出小明那天是结识美女还是帅哥(注意润年问题)*/
#include <stdio.h>
int main()
{
printf("请输入日期,并以-隔开:\n");
int year, month, day, days;
scanf("%d-%d-%d",&year, &month, &day);
// 将相差年数对应天数加入总天数中
for(int i = 1, i <= year - 2006, i++)
{
// 判断是否为润年
if((2006 + i) % 4 == 0 && (2006 + i) % 100 != 0 || (2006 + i) % 400 == 0)
days += 366;
else
days += 365;
}
// 定义整型数组,存储每月天数
int monthdays[] = {31,28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (year % 4 == 0 && year % 100 != 0 || year %400 == 0)// 当输入的年份为润年时,该年2月为29天
monthdays[1] = 29;// 将相差月数对应天数加入总天数中
for (int j = 1; j <= month - 1; j++)
days += monthdays[j];// 将相差天数加入总天数中
days += day;
// 当总天数能被6整除时,说明小明结识的是帅哥和美女
if (days % 6 == 0)
printf("小明结识的是帅哥和美女\n");// 若能被2整除,则结识的是帅哥
else if (days % 2 == 0)
printf("小明结识的是帅哥\n");// 若能被3整除,则结识的是美女
else if (days % 3 == 0)
printf("小明结识的是美女\n");// 若上面条件都不满足,则小明没有结识到任何人
else
printf("小明没有结识到任何人\n");
}
return 0;
}
7、字符数组与字符串
(1)字符数组:
char name[] = {'j' + 'a' + 'c' + 'k};
存放的元素是字符类型char的数组。
(2)字符串
char name[] = "jack";
同样是存放元素是字符类型char的数组,但是最后隐含一个字符’\0‘为字符串的结束标志。
也就是说这个数组的元素个数比字符数组大1。
'\0'的作用:
1> %s是以\0为结束标志的字符串输出格式。而且'\0'是不会输出的。
2> \0 也是一个字符,占一个字节。
(3)strlen函数
计算字符串的长度。
// strlen函数声明在string.h中1> 计算的是字符数,并不是字数
2> 计算的字符不包括'\0'
3> 一个汉字算3个字符长度
4> strlen函数计算字符串,直到遇到'\0'为止。
#include <string.h>
#include <stdio.h>
int main()
{
char name[] = "itcast";
char name2[] = {'0', '6'};
int size = strlen(name2);
//输出结果为8,name2中无\0,继续计算name中字符数,直到遇到\0为止
printf("%d\n", size);
return 0;
}
8. 字符串数组
char names[2][10] = {"hehe", "haha"};
存放的元素是字符串的数组。
二、指针
1. 指针的定义
类型 *变量名;
类型是指针变量所指向的数据的数据类型,变量名为指针变量的名称。
定义指针变量的*仅仅是一个象征,没有其他特殊含义。
指针变量只能存放地址值
作用:通过指针变量存储的地址值,访问对应的存储空间。
一元运算符*是间接寻址或间接引用运算符,当它作用于指针时,将访问指针所指向的对象。
任何指针都占用8个字节的存储空间。
sizeof()函数的返回值类型是unsigned long;
int a = 10;
int *p;
p = &a; //指针变量p指向了变量a
*p = 10; //a = 10;
p = null; //清空指针,不能再间接访问其他存储空间
2、使用注意
(1)int *p只能指向int类型的数据
//错误写法
double a = 10.0;
int *p = &a;
(2)指针变量未经初始化,不能拿来间接访问其他存储空间
//错误写法
int *p;
printf("%d\n",*p);
(3)指针变量只能存储地址
//错误写法
int *p;
p = 200;
3、指向指针的指针
类型名 **变量名;
int *p;
int **pp = &p;
首先p要先是一个指针,之后pp才需要两个*来定义指向p的指针。
#include <stdio.h>
int main()
{
int a = 10;
//int *
int *p = &a;
//int **可以当做一个类型:指向指针的指针。
int **pp = &p;
//修改a的两种间接方法:
*p = 20;
// **pp == *p == a
**pp = 30;
return 0;
}
4、指针和数组
数组的访问方式:
1> 数组名[下标]
2> 指针变量名[下标]
3> *(p+i)
#include <stdio.h>
void change( int array[] )
int main()
{
int ages[5] = {1, 2, 3, 4, 5};
// change( ages ); ages为首元素地址值
change( &age[2] );
return 0;
}
void change (int *array)
{
// printf("%d\n", array[2]);
printf("%d\n", *(array + 2));
}
5、指针与字符串
定义字符串的2种方式:
1> 利用数组(字符串变量)
char name[] = "hello";
特点:字符串里面的字符是可以修改的。
使用场合:字符串的内容需要经常修改。
2> 利用指针(字符串常量)
char *name = "world";
特点:里面的字符是不能够修改的。
使用场合:这个字符串是经常用到的,并且长期在内存中。
6、返回指针的函数
类型名 *函数名(参数列表)
#include <stdio.h>
char *test()
int main()
{
//用来返回字符串
char *name = test();
return 0;
}
//返回指针类型
char *test()
{
return "jack";
}
7、
指向函数的指针
在C语言中,函数名就代表着函数的地址。
定义的格式:
返回值类型 (*指针变量名)(形参1, 形参2, ...)
指向函数的指针的2个作用:
1> 间接调用函数
2> 将函数作为参数进行参数传递
//(*p)固定写法,代表指针变量p将来肯定是指向函数的
//左边的void:指针变量p指向的函数没有返回值
//右边的():指针变量p指向的函数没有形参
void(*p)();
void sum()
{
}
//p = 函数的地址
p = sum;
//(*p)();利用指针变量间接调用sum函数
p();
———Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ———