C 指针 数组

 //1  数组名称 与指针
 int a[5]={1,2,3,4,5};
 int *ptr=(int *)(&a+1);
 printf("%d,%d",*(a+1),*(ptr-1)); // 2,5

 //说明: &g+1的意思是数组类型的常量指针加一 即 数组长度加一

 printf("%0x %0x \n", (a+1), (&a+1));
 // a+1   :代表数组的值 第几个 数组下标(即 数组第二个值的地址)
 // &a + 1: &取地址之后就代表这个地址的属性是一个数组长度为单位的
 //         即 数组首地址之后 4*5个字节 后的地址, eg. 如下 0x00000111 的地址
 // 0x00000001 0x00000010 0x00000011 0x00000100 0x00000101 0x00000111 

 //这个例子 很特殊:
 printf("%d \n", *(*(&a+1)-1)); // 5
 // A = &a+1 : 数组第五个数后面的地址 用A代表(& 作用是告诉编译器,这是个数组类型的指针)
 // *(A)         :这里看打印仍然是个地址,*的作用是转化为普通的指针??
 // 
   
 // B = (*(A)-1) : int* 往前挪动一个值(4byte)
 // *(B)         : 取出这个地址的值

/* 总结如下:
   : a 数组名 是常量 指针, 类型同 数组元素的类型
   : &a 指向数组的指针, 类型是 数组类型(长度:数组的元素类型长度 × 数组元素长度)
   : sizeof(a) = 数组的元素类型长度 × 数组元素长度
*/

printf("%0x",a); //数组的首地址
printf("%0x",*a); //数组的第一个值 1
printf("%0x",a[0]); //数组的第一个值 1
printf("%0x",*(&a[0])); //数组的第一个值 1
//2字符串翻转
void rev(char *p_rev)
{
char *p_start = p_rev;
char *p_end = p_rev;
char temp;

while(*(++p_end+1) != '\0');

while(p_start < p_end)
{
   temp = *p_start;
   *p_start++ = *p_end;
   *p_end-- = temp;
}
}
//3 一下为windows 32 下的C程序 计算sizeof的值:
char str[] = "Hello";
char *p = str;
int n = 1088;

cout << sizeof(str) << endl;             //   6
cout << *str << endl;                       //    H
cout << str << endl;                         //   Hello
cout << *p << endl;                         //     H
cout << p << endl;                          //    Hello                       
cout << &str << endl;                     //    0013FF68(地址)
cout << &p << endl;                         //    0013FF64(地址)
cout << sizeof(str) << endl;            //     6           
cout << sizeof(p) << endl;              //     4
cout << sizeof(n) << endl;              //      4
//4 c_itoa 函数
void itoa(int *p_num,char *str)
{
char *p_str = str;
char *p_rev = str;

int num = *p_num;
int i = 0;

if(num < 0)
{
   *p_str++ = '-';
   p_rev = p_str;
   num = 0 - num;
}

if(num == 0)
{
   *p_str++ = '0';
}

while(num > 0)
{
   p_str[i++] = num%10 + '0';
   num = num / 10;
}

rev(p_rev);

p_str[i] = '\0';
}

 

 

char* data = NULL;
data = "str123";

双引号做了3件事:
1.申请了空间(在常量区),存放了字符串
2. 在字符串尾加上了’/0’
3.返回地址

char a[10] = “hello”; //这样可以,这种情况是c语言初始化所支持的,和a[0] = ‘h’ a[1] = ‘e’…是一个道理,和普通数组初始化一致
用变量a给出下面的定义 
a) 一个整型数(An integer) 
b) 一个指向整型数的指针(A pointer to an integer) 
c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer) 
d) 一个有10个整型数的数组(An array of 10 integers) 
e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers) 
f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers) 
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer) 
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer ) 答案是: 
a) int a; // An integer 
b) int *a; // A pointer to an integer 
c) int **a; // A pointer to a pointer to an integer 
d) int a[10]; // An array of 10 integers 
e) int *a[10]; // An array of 10 pointers to integers 
f) int (*a)[10]; // A pointer to an array of 10 integers 
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer 
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer


关于f:
typedef int tdArr[10];
typedef tdArr* tdpArr;
tdpArr pArr;

eg.
int a[10];
pArr = &a;
(*pArr)[1] = 12; //  不能把括号去掉 *pArr[1] = 12;


关于gf:
typedef int (tdFun)(int); //不能写成 typedef int ()(int)  tdFun;
typedef tdFun* tdpFun;
tdpFun a[10];

eg.
int fun(int para)
{
  printf("para=%d \n", para);
  reutrn 0;
}

a[1] = fun;
(a[1])(12);


#include <stdio.h>
#include <assert.h>
#include <string.h>

void fun(void)
{
	printf( " this is a fun \n");
} 

//typedef void(*pFun)(void);
typedef void(Fun)(void);
typedef Fun* pFun;

int main(void)
{
	//void(*p)(void);
	pFun p;
	p= fun;
	(*p)();
	(*(void(*)(void))0x400566)();

	//printf( " this is a fun %p \n", p);

	return 0;
}


//
void * ( * (*fp1)(int))[10];
float (*(* fp2)(int,int,int))(int);
int (* ( * fp3)())[10]();

1.void * ( * (*fp1)(int))[10];   fp1是一个指针,指向一个函数,这个函数的参数为int型,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个void*型指针。

2.float (*(* fp2)(int,int,int))(int);   fp2是一个指针,指向一个函数,这个函数的参数为3个int型,函数的返回值是一个指针,这个指针指向一个函数,这个函数的参数为int型,函数的返回值是float型。

3.int (* ( * fp3)())[10]();   fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是int型
#include <stdio.h>
int main()
{
	char *s[] = { "abcde", "efg", "hijkl", "mnopq" };
	char **ps[] = { s + 3, s + 2, s + 1, c };
	char ***pps = ps;
	printf("%s\n", **++pps);  //hijkl
	printf("%s\n", *--*++pps + 3);  //de
	printf("%s\n", *cpps[-2] + 3);  //pq
	printf("%s\n", cpps[-1][-1] + 1); //fg
        return 0;
}


//printf("%s\n", **++pps);  //pps是指向 ps 的指针

//printf("%s\n", *--*++pps + 3);  // ++pps 指向 s+1的位置,*++p代表的是 s的第二个位置("efg"),所以 --(*++p)代表的"abcde"的位置指针地址,*--*++pps就代表s第一个字符串的地址

//printf("%s\n", *pps[-2] + 3);  //pps[-2]是s+1前面两个位置(=s+3),加一个*代表,"mnopq"首地址,+3,代表pq

//printf("%s\n", pps[-1][-1] + 1); //pps[-1][-1]: pps[-1]代表 s+2位置,再加上[-1]代表s元素(“hgjkl”)向前移动一个
int main()
{
	int array[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int *ptr1 = (int *)(&array + 1);
	int *ptr2 = (int *)(*(array + 1));
	printf("%d  %d\n", *(ptr1 - 1), *(ptr2 - 1));
 
	return 0;
}

//int *ptr1 = (int *)(&array + 1); //&array代表的是整个数组的长度
//int *ptr2 = (int *)(*(array + 1)); //array是二级指针 +1 就指向 6 的位置,
printf("%d  %d\n", *(ptr1 - 1), *(ptr2 - 1)); //10 5

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值