用变量a给出下面的定义
a) 一个整型数
(An integer) int a
b) 一个指向整型数的指针
(A pointer to an integer) int *a
c) 一个指向指针的的指针,它指向的指针是指向一个整型数
(A pointer to a pointer to an integer) int * *a
d) 一个有10个整型数的数组
(An array of 10 integers) int a[10]
e) 一个有10个指针的数组,该指针是指向一个整型数的
(An array of 10 pointers to integers)int *a[10] //指针的数组
f) 一个指向有10个整型数数组的指针
(A pointer to an array of 10 integers int [10] *a //c语言格式不允许 int (*a) [10]//数组的指针
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数
(A pointer to a function that takes an integer as an argument and returns an integer)
int (*a) int //函数的指针
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数
( An array of ten pointers to functions that take an integer argument and return an integer )
int (*a[10]) int //函数指针的数组
-----------------------------------------------------------------------------------------------------------------------
运行程序的结果:段错误
malloc 堆区开空间
void * malloc (size_t size)
void * 是万能指针,用来返回空间首地址
------------------------------------------------------------------
原因:
主函数中str被定义为char*类型,其初始化为NULL
getmemory(str,100)将str中的NULL传给被调函数中的p
p此时的值是NULL,在被调函数中,p=(char*)malloc(num)在堆区开空间,获得一个具体的地址
但由于str传给p的仅仅只是值传递,所以此时p的地址值不能返回给str,即str中的值仍然为NULL
NULL为0号地址,不可访问, 不能实现字符串“hello”拷贝给str,发生段错位
------------------------------------------------------------------------------------------------------------
改正:
要实现将字符串“hello”拷贝给str,可按照下面代码实现:
getmemory(&str,100),对str取地址,将str的地址传给被调函数中的p
p此时的值是str处的地址值,在被调函数中,p=(char*)malloc(num)在堆区开空间,获得一个新的具体的地址,再进行*p运算
由于str传给p的是地址传递,所以此时p的地址值能返回给str,可实现被调修改主调,即str中的值为p返回来的地址值,实现字符串“hello”拷贝给str
--------------------------------------------------------------------------------------------------------------------------------
str // char &str // char *
str // char * &str // char * *
--------------------------------------------------
定义方式1: char str[10];
char *s = str; //开在栈上
定义方式2: char *s = malloc[10]; //开在堆上
结构体 struct
描述一些 原先 基本数据类型不好描述的 这种复杂数据类型
struct 学生
{
//1.姓名 //chat name[20]
//2.班级 //int classNo
//3.性别 //char sex; //f m
//4.成绩 //float score;
//5.年龄 //int age;
}
struct 汽车
{
//1.姓名 //chat name[20]
//2.班级 //int classNo
//3.性别 //char sex; //f m
//4.成绩 //float score;
//5.年龄 //int age;
}
语法:
struct 结构体类型名
{
数据成员列表;
};
//定义了一个 "数据类型" --- 用户自定义的数据类型
eg:
描述学生这种类型:
struct student
{
//name
char name[20]; //成员变量 各个成员变量之间 用分号隔开
//age
unsigned char age;//0~255 -128~127
//score
float score;
//...
}; //注意: 最后这个分号(;) 表示 --- 结构体类型定义完成
struct student //学生数据类型
==>
int
------------------------------
struct student s; //s这种类型的一个变量
注意:
1.结构体 --- 用来实现 自定义数据类型
2.用结构体
a.先构造出 数据类型
b.用数据类型 定义变量
数组
指针
访问结构体:
. //结构体成员运算符
结构体变量名.成员变量名
s.name //. 的
//定义结构体类型
//定义变量
结构体变量初始化
结构体变量赋值 --结构体不能整体 赋值 {"tom",20,89.5,100};
struct student s;
s = {"tom",20,89.5,100}; // 错误写法
int a = 10; //初始化
int a; //赋值
a = 10;
-> //用于结构体类型的指针变量的
//结构体访问成员的方式2
struct student *s = &s1;
s->name
结构体类型的变量.成员变量名
结构体类型的指针->成员变量名
结构体的对齐规则:
1.在32位的平台上,默认都是按4字节对齐的。 64位的平台 默认是8字节
2.对于成员变量,
各自在自己的自然边界上对齐。
//整个结构体的对齐
3.如果 成员变量中有比4字节大。
此时 整个结构体按照4字节对齐。 //32位的平台
4.如果 成员变量中没有有比4字节大。
此时 整个结构体按照最大的那个成员对齐。
注意:
1.结构体类型,可以定义在 函数里面,但是此时作用域就被限定在改函数中
2.结构体的定义的形式:
//形式1 先定义类型,后定义变量
struct stu
{
...
};
struct stu s;
//形式2 定义类型的同时定义变量
struct stu
{
...
}s1,s2,*s3,s4[10];
struct stu s;
//形式3 省略了类型名 --如果只用一次,可以这样写
struct
{
...
}s1,s2,*s3,s4[10];
------------------------------
自然边界对齐
int -- 4字节 --- 能被4整除的地址编号上
short -- 2字节 --- 能被2整除的地址编号上
char -- 1字节 --- 能被1整除的地址编号上
结构体整体对齐
一般是以结构体 字节最大的变量长度来对齐