指针笔记与结构体初探

指针

1.未初始化和非法的指针
下面的代码段说明了一个极为常见的错误:
int *a;

*a = 12;
这个申明创建了一个名为a的指针变量。但是a究竟指向哪里?我们申明了一个变量,但却没有对他初始化,所以我们没有办法预测12这个值将会存储与什么地方。
指针变量和其他变量没有区别。如果变量是静态的,那么它会被初始化为0.但如果变量是自动的,它根本不会被初始化。无论哪种情况,申明一个指向整形的指针都不会“创建”用于存储整形值的内存空间。

如果程序执行赋值操作,如果运气好的话,a会被分到一个非法地址,这样赋值语句就会出错,程序会终止。在Unix系统上这个错误被称为“segmentation violation” 或者”memory fault”,在windows的PC上,对未初始化或非法指针进行间接访问操作是一般保护性异常的根源之一。

更加严重的情况是:这个指针可能包含了一个合法的地址,接下来的事很简单:那个位置上的值会被修改,虽然你可能无意修改它,但是这种类型的错误很难捕捉。
在对指针间接访问之前,必须非常小心,确保它们已经被初始化!

注意:

指针基本操作:
使用指针前先让指针变量指向所需指向的变量再使用该指针变量,也就是不仅要定义还要初始化。
赋值=(只能赋兼容类型的值),取值*,加减法运算(指针加减法时必须指向同一数组,且操作时候注意不能超过数组大小)
指针减法时候差值为两个指针指向元素间距离,指向数组时候即为元素之间的个数,而不是两个元素之间字节数。

说明:
指针类型变量中存储的是地址;
指针变量存放的是内容(值);
指针变量在使用前必须指向相应的地址。
指向:指针变量指向本身保存的内容(地址或者指针)所表示的内存单元。

使用指针之前应该会的:
取地址运算符&(获得某个变量的地址且只能取内存中变量的地址,也就是不能取常量或者表达式的地址);
取值运算符*(获得某个地址中存放的数据且只能取得指针所指向的变量的值)。

指针的指针
int a = 12;
int *b = &a;
int **c = &b;
c就是一个指向指针的指针。这是合法的,指针变量和其他变量一样,占据内存中的某个特定的位置。所以用&操作符取它的地址是合法的(申明为register的变量除外,具体看C语言存储类型)。

NULL指针
NULL指针是一种特殊的指针变量,不指向任何东西。
要使一个指针为NULL指针,可一个它赋值0。判断一个指针变量是不是NULL指针,可以将它和0比较,这是一种源代码约定。就机器内部而言,NULL指针的实际值可能与此不同,编译器负责0值和内部值的转化。

NULL指针的概念很有用,它给你一种方法去表示特定的指针不指向任何东西。例如,假如某个函数的目的是查找数组中是否有某个值,如果数组不包含这个特定的值,那么返回值可以为NULL。这样的技巧允许函数的返回值包含两个不同片段的信息。首先,有没有找到元素? 如果找到了,元素是哪个?(这个技巧在C语言中用得很多,但是这违背了软件工程的原则,用一个单一的值表示两个不同的意思是一件危险的事,因为将来很容易无法弄清楚哪个才是它的用意。更好的方法是让函数返回两个独立的值:首先是个状态值,用于提示是否成功;其次是个指针,当状态值提示查找成功时,指针指向的值就是要查找的元素。)

对NULL 指针的解引用操作是违法的。在有些机器上,它会访问内存位置0,机器不会妨碍你访问或修改这个位置,这会造成难以寻找的错误。在其他机器上,这会应引发一个错误,并终止程序(linux系统上会返回segmentation fault)。

对所有指针变量进行显示的初始化会是一个很好的做法,如果你知道这个指针变量指向哪里,就把它初始化为该地址,否则就指向NULL。

结构体

… void test(){
// 结构体是一种构造类型
// 构造类型:可以存放其他类型的那么一种类型
// 数组:它只能存放一种数据类型的多个数据
int nums[] = {1,3,4};
Person(人) 年龄(int) 身高(float) 名字(char *)
int Person[3] = {10,2.1,“巨人”};
printf("%d,%d,%d",Person[0],Person[1],Person[2]);
结构体定义格式:
struct 结构体类型名称{
数据类型 成员名称;

};

struct Person{
    int age;//此处也是分号
    float height;
    char *name;
    
};//此处必须以分号结尾

数据类型 变量名称
结构体类型 结构体变量名称
结构变量的定义
struct Person p;
//    p.age = 10; //通过.访问结构变量中成员
//    p.height = 2.1f;
//    p.name = "姚明二代";

printf("age = %d,heigth = %.2f,name = %s\n",p.age,p.height,p.name);

}

结构体多种初始化方式

struct Person{
    int age;
    float height;
    char *name;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值