#include
<stdio.h>
#include
<stdlib.h>
int
main()
{
int
a[5] = { 1, 2, 3, 4, 5 };
int
* ptr1 = (
int
*)(&a + 1);
int
* ptr2 = (
int
*)((
int
)a + 1);
printf(
"%x,%x"
, ptr1[-1], *ptr2);
//ptr1 &a 得到数组首元素地址,+1 ->元素5后面,-1得到5
// a->得到a的地址,转换为int型后,得到4651752,+1->4651753,
//转换为int* 后,得到33554432(我也不知道为什么) 再转为十六进制输出可得
system(
"pause"
);
return
0;
}
#define
_CRT_SECURE_NO_WARNINGS 1
#include
<stdio.h>
#include
<stdlib.h>
int
checkSystem()
{
union
check
{
int
i;
char
ch;
} c;
c.i = 1;
return
(c.ch == 1);
}
int
main()
{
//void* p;
//p++;
//p += 1;
//未知大小 引深为不知道内存目的地址的确切值
//int* pint=NULL;
//pint++; //ANSI:正确
//printf("%d\n", pint);
//void* memcpy(void* dest, const void *src, size_t len);
//void* memset(void* buffer, int c, size_t num);
//int IntArray_a[100];
//memset(IntArray_a, 0, 100 * sizeof(int)); //将 IntArray_a 清 0
//for (int i = 0; i < 100; i++)
//{
// printf("%d ", IntArray_a[i]);
//}
//void 不能代表一个真实的变量,因为在定义变量时,要为变量分配一定的空间,但是
//void型,不能知道它的数据类型大小
/*char * Func(void)
{
char str[30];
…
return str;
}
*/
//str位于栈内存中,在出了作用域后,便被释放。
//return ;什么也不做,什么也不返回
//const 修饰的是只读变量 具有不可变性
//const 修饰的只读变量必须在定义的同时初始化,因为具有不可变性,如果没有在初始化
//的时候进行初始化,那么在后面点操作中,便不能修改它的值。
/*int i = 0;
const c = 3;
scanf("%d", &i);
switch (i)
{
case 1:
;
break;
case 2:
break;
case c:
break;
}*/
//case 后面只能是常量值,不能是const修饰的只读变量
/*const 定义的只读变量从汇编的角度来看, 只是给出了对应的内存地址, 而不是象#define
一样给出的是立即数,所以,const 定义的只读变量在程序运行过程中只有一份拷贝(因为
它是全局的只读变量,存放在静态区) ,而#define 定义的宏常量在内存中有若干个拷贝。
#define 宏是在预编译阶段进行替换,而 const 修饰的只读变量是在编译的时候确定其值。
#define 宏没有类型,而 const 修饰的只读变量具有特定的类型。*/
/*const 修饰一般变量时,放在签名和后面都没有关系
int const i = 2; 或 const int i = 2;*/
//int a = 1;
//int b = 2;
//const int *p=a; // p 可变,p 指向的对象不可变
p = b;
//printf("%d\n", p);
//int const *p; // p 可变,p 指向的对象不可变
//int *const p; // p 不可变,p 指向的对象可变
//const int * const p; //指针 p 和 p 指向的对象都不可变
//struct 的成员默认情况下属性是 public 的,而 class 成员却是 private 的。
/*int ret=checkSystem();
printf("%d\n", ret);*/
system(
"pause"
);
return
0;
}
#include
<stdio.h>
#include
<stdlib.h>
int
main()
{
int
a[5] = { 1, 2, 3, 4, 5 };
int
* ptr1 = (
int
*)(&a + 1);
int
* ptr2 = (
int
*)((
int
)a + 1);
printf(
"%x,%x"
, ptr1[-1], *ptr2);
//ptr1 &a 得到数组首元素地址,+1 ->元素5后面,-1得到5
// a->得到a的地址,转换为int型后,得到4651752,+1->4651753,
//转换为int* 后,得到33554432(我也不知道为什么) 再转为十六进制输出可得
system(
"pause"
);
return
0;
}
#include
<iostream>
using
namespace
std;
int
main()
{
//编译器的确会将注释剔除,但不是简单的剔除,而是用空格代替原来的注释
//C 语言里以反斜杠(\)表示断行。编译器会将反斜杠剔除掉,跟在反斜杠后面的字符
//自动接续到前一行。但是注意:反斜杠之后不能有空格,反斜杠的下一行之前也不能有空格。
//左移不管有没有符号位,全部补零
//右移时,符号位随同移动,为正时,补0,负数时 补1
system(
"pause"
);
return
0;
}
一维数组做参数时,将一维数组解析为指向数组首元素地址的指针,
char* (*fun1)(char* p1, char* p2); 函数指针,指向一个函数的指针
例:
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
char
* fun(
char
*
p1
,
char
*
p2
)
{
int
i = 0;
i = strcmp(
p1
,
p2
);
if
(0 == i)
{
return
p1
;
}
else
{
return
p2
;
}
}
int
main()
{
char
* (*pf)(
char
* p1,
char
* p2);
pf = &fun;
//pf = fun; //也是可以的,因为函数名在编译时,其实就是个地址
//创建一个函数指针pf,pf指向fun,(*pf)("aa", "bb")调用函数
(*pf)(
"aa"
,
"bb"
);
system(
"pause"
);
return
0;
}
#include
<stdio.h>
#include
<stdlib.h>
void
Function()
{
printf(
"Call Function!\n"
);
}
int
main()
{
//void(*p)()定义一个指针p 参数列表和返回值全为空,&p求指针变量p的地址,强转为int*
//类型,表示将地址强制转换成指向 int 类型数据的指针,,Function为函数的首地址,
//多以这段代码的意思是,将函数Function的入口地址强制强转为int类型后,在赋值给
//指针变量p
void
(*p)();
*(
int
*)&p = (
int
)Function;
(*p)();
system(
"pause"
);
return
0;
}
(*(void(*)())0)()分析
1.void(*)() 是一个函数指针,函数列表为空,返回值为空,
2.void(*)() 0 ,将0转换为一个函数类型的指针,0是一个地址,将函数存放在首地址为0的地方
3.(*(void(*)())0) ,将首地址0中的内容取出来,
4.(*(void(*)())0)() ,函数调用
静态区: 保存自动全局变量和static变量(包括static全局和static局部),静态区的内容在整个生命周期都存在,内容有编译器在编译的时候分配,只初始化一次,
栈: 保存局部变量,栈上的内容只在函数范围内存在,当出了函数的作用域时,会被自动销毁,特点:效率高,空间大小有限
堆:有malloc/new 分配空间,有free/delete释放,注意配对使用,容易出错。
#include
<stdio.h>
#include
<stdlib.h>
int
main()
{
int
a[5] = { 1, 2, 3, 4, 5 };
int
* ptr1 = (
int
*)(&a + 1);
int
* ptr2 = (
int
*)((
int
)a + 1);
printf(
"%x,%x"
, ptr1[-1], *ptr2);
//ptr1 &a 得到数组首元素地址,+1 ->元素5后面,-1得到5
// a->得到a的地址,转换为int型后,得到4651752,+1->4651753,
//转换为int* 后,得到33554432(我也不知道为什么) 再转为十六进制输出可得
system(
"pause"
);
return
0;
}
#define
_CRT_SECURE_NO_WARNINGS 1
#include
<stdio.h>
#include
<stdlib.h>
int
checkSystem()
{
union
check
{
int
i;
char
ch;
} c;
c.i = 1;
return
(c.ch == 1);
}
int
main()
{
//void* p;
//p++;
//p += 1;
//未知大小 引深为不知道内存目的地址的确切值
//int* pint=NULL;
//pint++; //ANSI:正确
//printf("%d\n", pint);
//void* memcpy(void* dest, const void *src, size_t len);
//void* memset(void* buffer, int c, size_t num);
//int IntArray_a[100];
//memset(IntArray_a, 0, 100 * sizeof(int)); //将 IntArray_a 清 0
//for (int i = 0; i < 100; i++)
//{
// printf("%d ", IntArray_a[i]);
//}
//void 不能代表一个真实的变量,因为在定义变量时,要为变量分配一定的空间,但是
//void型,不能知道它的数据类型大小
/*char * Func(void)
{
char str[30];
…
return str;
}
*/
//str位于栈内存中,在出了作用域后,便被释放。
//return ;什么也不做,什么也不返回
//const 修饰的是只读变量 具有不可变性
//const 修饰的只读变量必须在定义的同时初始化,因为具有不可变性,如果没有在初始化
//的时候进行初始化,那么在后面点操作中,便不能修改它的值。
/*int i = 0;
const c = 3;
scanf("%d", &i);
switch (i)
{
case 1:
;
break;
case 2:
break;
case c:
break;
}*/
//case 后面只能是常量值,不能是const修饰的只读变量
/*const 定义的只读变量从汇编的角度来看, 只是给出了对应的内存地址, 而不是象#define
一样给出的是立即数,所以,const 定义的只读变量在程序运行过程中只有一份拷贝(因为
它是全局的只读变量,存放在静态区) ,而#define 定义的宏常量在内存中有若干个拷贝。
#define 宏是在预编译阶段进行替换,而 const 修饰的只读变量是在编译的时候确定其值。
#define 宏没有类型,而 const 修饰的只读变量具有特定的类型。*/
/*const 修饰一般变量时,放在签名和后面都没有关系
int const i = 2; 或 const int i = 2;*/
//int a = 1;
//int b = 2;
//const int *p=a; // p 可变,p 指向的对象不可变
p = b;
//printf("%d\n", p);
//int const *p; // p 可变,p 指向的对象不可变
//int *const p; // p 不可变,p 指向的对象可变
//const int * const p; //指针 p 和 p 指向的对象都不可变
//struct 的成员默认情况下属性是 public 的,而 class 成员却是 private 的。
/*int ret=checkSystem();
printf("%d\n", ret);*/
system(
"pause"
);
return
0;
}
#include
<stdio.h>
#include
<stdlib.h>
int
main()
{
int
a[5] = { 1, 2, 3, 4, 5 };
int
* ptr1 = (
int
*)(&a + 1);
int
* ptr2 = (
int
*)((
int
)a + 1);
printf(
"%x,%x"
, ptr1[-1], *ptr2);
//ptr1 &a 得到数组首元素地址,+1 ->元素5后面,-1得到5
// a->得到a的地址,转换为int型后,得到4651752,+1->4651753,
//转换为int* 后,得到33554432(我也不知道为什么) 再转为十六进制输出可得
system(
"pause"
);
return
0;
}
#include
<iostream>
using
namespace
std;
int
main()
{
//编译器的确会将注释剔除,但不是简单的剔除,而是用空格代替原来的注释
//C 语言里以反斜杠(\)表示断行。编译器会将反斜杠剔除掉,跟在反斜杠后面的字符
//自动接续到前一行。但是注意:反斜杠之后不能有空格,反斜杠的下一行之前也不能有空格。
//左移不管有没有符号位,全部补零
//右移时,符号位随同移动,为正时,补0,负数时 补1
system(
"pause"
);
return
0;
}
一维数组做参数时,将一维数组解析为指向数组首元素地址的指针,
char* (*fun1)(char* p1, char* p2); 函数指针,指向一个函数的指针
例:
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
char
* fun(
char
*
p1
,
char
*
p2
)
{
int
i = 0;
i = strcmp(
p1
,
p2
);
if
(0 == i)
{
return
p1
;
}
else
{
return
p2
;
}
}
int
main()
{
char
* (*pf)(
char
* p1,
char
* p2);
pf = &fun;
//pf = fun; //也是可以的,因为函数名在编译时,其实就是个地址
//创建一个函数指针pf,pf指向fun,(*pf)("aa", "bb")调用函数
(*pf)(
"aa"
,
"bb"
);
system(
"pause"
);
return
0;
}
#include
<stdio.h>
#include
<stdlib.h>
void
Function()
{
printf(
"Call Function!\n"
);
}
int
main()
{
//void(*p)()定义一个指针p 参数列表和返回值全为空,&p求指针变量p的地址,强转为int*
//类型,表示将地址强制转换成指向 int 类型数据的指针,,Function为函数的首地址,
//多以这段代码的意思是,将函数Function的入口地址强制强转为int类型后,在赋值给
//指针变量p
void
(*p)();
*(
int
*)&p = (
int
)Function;
(*p)();
system(
"pause"
);
return
0;
}
(*(void(*)())0)()分析
1.void(*)() 是一个函数指针,函数列表为空,返回值为空,
2.void(*)() 0 ,将0转换为一个函数类型的指针,0是一个地址,将函数存放在首地址为0的地方
3.(*(void(*)())0) ,将首地址0中的内容取出来,
4.(*(void(*)())0)() ,函数调用
静态区: 保存自动全局变量和static变量(包括static全局和static局部),静态区的内容在整个生命周期都存在,内容有编译器在编译的时候分配,只初始化一次,
栈: 保存局部变量,栈上的内容只在函数范围内存在,当出了函数的作用域时,会被自动销毁,特点:效率高,空间大小有限
堆:有malloc/new 分配空间,有free/delete释放,注意配对使用,容易出错。