您的位置:首页 > 编程语言 > C语言/C++

黑马程序员——C语言——数组和指针

2015-01-08 18:11 246 查看
———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};

// 当输入的年份为润年时,该年2月为29天

if (year % 4 == 0 && year % 100 != 0 || year %400 == 0)

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函数

计算字符串的长度。

1> 计算的是字符数,并不是字数

2> 计算的字符不包括'\0'

3> 一个汉字算3个字符长度

4> strlen函数计算字符串,直到遇到'\0'为止。

// strlen函数声明在string.h中

#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培训、期待与您交流! ———



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: