Practice Pointer articles

 


pointer

If we want chocolate sent to distant friends, that you must have to know that the friend's address.

Program where this data is chocolate, friends from afar is an address data storage.

For example, x = 3,3 (chocolate) will be sent to the memory address of x.

Sometimes, they do not send himself, but entrusted others. We just sent to the address of a business, so that businesses sent to the hands of friends.

In other words, we have two ways to send things:

  • Direct send chocolate, send chocolate;
  • Indirect send chocolate, send a friend's address;

Assignment like x = 3 and the like, in fact, can only be resolved first send method, because it can not address the program is digital Yeah, distinction.

That is how to distinguish between a 3 [data], or a memory address [it]?

From the C language syntax level, object storage into a variable:

  • The basic types of transactions; such as char, int, float
  • Address data type; such as char *, int *, float *

This type of address data, called pointer [].

  • It is the basic data type char a;
  • char * a data address type;

 


Nature pointer

Do a thought experiment:

#include <stdio.h>
int main(void)
{
   int a = 3;
   // 赋值 3 给 a
   
   printf("%p\n",&a);
   // 输出 a 的地址,假设为 0x0060FEAC
   
   printf("%d\n",*(&a));
   // 取 a 地址的数据
   
	 printf("%x\n",*((int*)0x0060FEAC));
	 // 取 a 地址的数据, 因为变量名、函数名、字符串名和数组名在本质上是一样的,它们都是地址的助记符,在内存里是 0x0060FEAC 这样的数字。
	 // &a == (int*)0x0060FEAC, 也就是说,我们既可以通过【地址助记符】(变量名),也可以直接通过地址
	 // 不过,你得预先知道地址,除了QT之外,别的编译器每次都会改变地址,你其实无法预先知道a的地址,所以通过地址取值的写法,很少见。
	 // 此外,地址也要加上类型,因为不同类型占的内存字节数不一样,类型不同解释也就不同
	 
return 0; 
}

Memory address pointers (or pointer constant, that they can not change), is essentially a type of address, such as (int *) 0x0060FEAC.

Essence pointer variable (may change) is, it is possible to store 4-byte (32-bit system), and based on the declared type (e.g., int, char, float) the size of the addressing variables, such as type * a.

 


C language copy only value

Function parameter passing, there are three categories:

  • Copy traditional values, the value of the argument, the argument can not be modified, and created a multi-space;
  • Pass by reference, the argument copy address, it is possible to modify the actual parameters, output parameters can be done;
  • Transfer pointer, copy argument address, it is possible to modify the actual parameters, output parameters can be done;

By value, as different people with the same name, in addition to the name of the same, no two people associate;

Pass by reference, has been dubbed by others, I look like Ma, when I was around people in front of Ma's called, is in fact called me, Ma do things that will affect me;

Pass the pointer, I know the specific address, the address can find me there, then I do things that will affect where.

C language only passed by value, pass a pointer is passed by reference in C ++.

He said the C language textbook, transfer function C language has two kinds of parameters:

  • Copies the value passed is the value;
  • Copy address pointer transfer.

And I am here today to say: C language function of mass participation is only one, is the value of the copy.

Copies the value of the concept: the value of a copy of the variable to another variable.

void swap(int a, int b){
    int temp;  
    temp = a;
    a = b;
    b = temp;
}
swap(x, y);
// 赋值等同 int a = x,int b = y;
// 就是把变量 x 的值拷贝给另一个变量a,所以,这就是值拷贝。

void swap(int *p1, int *p2){
    int temp;  
    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
swap(&a, &b);
// 赋值等同 int *p1 = a,int *p2 = b;
// 就是把变量 a 的值拷贝给另一个变量p1,所以,这也是值拷贝。

Whether it is passed address or pass an ordinary variable, function parameter passing is actually a copy of the value.

Is the process of passing on a nature assignment parameter assignment is to copy the memory. The so-called memory copy means copying data on a memory to other memory ...

 


Pointer constant with constant pointer

E.g,

const int *p;

int const *p;

int * const p;

const int * const p;

int const * const p;

I saw that it was some faint, but fortunately there is a difference between skill.

First, understand the constant and variable.

const type a 代表 a 是常量(不能改), 如 const char a

type a代表变量(可以改), char a

It can be read from right to left, proposed by the inventor of C ++.

Such as, char * const p;

Reading, p is a const pointer to char. (* Read as a pointer to)

Translation, p is a const pointer to characters. (Pointer to not change, but the content can be changed)

Such as, const char * p;

Read, p is a pointer to char const. (Char const and const char is a mean)

Translation, p is a pointer to a constant character pointer variable. (The contents of the pointer can not be changed, but can be changed to point)

There is a rule:

  • const * number appears on the right pointer points can not be changed;
  • const * number appears on the left, the content of the pointer can be changed;
  • const * number appears in the both sides, a pointer to a pointer of the content can be changed;
const int *p;
// 读,p is a pointer to int const
// 译,p 是一个指向整型常量的指针,指针内容不能改,但可以改指向,即指针常量。

// 为什么是指针常量呢?
// 这里有一个语言学的规则:偏正关系,语义偏后一个。
// 如牛奶与奶牛,牛奶最后一个是奶,所以本质是奶;奶牛最后一个是牛,所以本质是牛。
// 又如蜜蜂与蜂蜜。
// 指针常量(指针变量+常量): 指针内容不能改,但可以改指向
// 常量指针(常量指针+变量): 指针指向不能改,但内容可以改

int const *p;
// int const 与 const int 相同,所以同上:指针常量。
// 指针内容不能改:*p = 15(错误写法)
// 但可以改指向:p = &x 

int * const p;
// 读,p is a const pointer to int
// 译,p 是一个指向整型变量的常量指针

const int * const p;
// 读,p is a const to pointer to int const
// 译,p 是一个指向整型常量的常量指针(指向、值都不能修改)

int const * const p;
// int const 、const int 相同,所以同上。

 


Pointer Array array pointers

After a prejudiced relationship Semantic

Array of pointers: a pointer storage array, such as int * p [10].

An array of pointers: pointing to a row of 10 elements each two-dimensional array of pointers, such as int (* p) [10].

P is a pointer to the first difference and who combine:

  • And first [] in combination, is an array;
  • And first () binding is a function;
  • * First and binding, a pointer;

Heap method of applying a two-dimensional array:

#include<stdio.h>
#include<malloc.h>

// 二级指针申请二维数组(返回值版):多个一维指针申请多次,但空间不连续
char **get_memory(int row, int col){

	// 先开辟行
	char **p = (char**)malloc(sizeof(char)*row);
	
	// 再开辟列
	for(int i=0; i<row; i++)
		p[i] = (char*)malloc(sizeof(char*) *col);  
		// *(p+i)等价于p[i]
          
    return p;
}

// 二级指针释放二维数组的方法:
void des_memory( char **p, int row ){
	for(int i=0; i<row; i++)
		free(p[i]);   // 释放列
	free(p);        // 释放行
  p = NULL;       // 防止指针迷途
}

void print( const char**p, int row, int col )
// 加上const,表示指针指向的内容不能修改,保护数据
{
	   for( int i=0; i<row; i++ , putchar(10))
        for( int j=0; j<col; j++ )
            printf("%c ", p[i][j]);
}

int main( )
{
	char **p = NULL;
	p = get_memory(3, 4);
	print(p, 3, 4);
	des_memory(p, 3);  // des_memory释放有些问题,我也不知道为什么
}
#include<stdio.h>
#include<stdlib.h>

// 二级指针申请二维数组(函数传参版):多个一维指针申请多次,但空间不连续
void get_memory(char ** p, int row, int col){

	// 先开辟行
	*p = (char*)malloc(row);
	
	// 再开辟列
	for(int i=0; i<row; i++)
		p[i] = (char*)malloc(sizeof(char *)*col);  
		// *(p+i)等价于p[i]
}

// 二级指针释放二维数组的方法:
void des_memory(char ** p, int row){
	for(int i=0; i<row; i++)
		free(p[i]);   // 释放列
	free(p);        // 释放行
  p = NULL;       // 防止指针迷途
}

void print( const char**p, int row, int col ) // 加上const,表示指针指向的内容不能修改,保护数据
{
	   for( int i=0; i<row; i++ , putchar(10))
        for( int j=0; j<col; j++ )
            printf("%c ", p[i][j]);
}

int main( )
{
	char *p = NULL;
	get_memory(&p, 3, 4);
	print(&p, 3, 4);
	des_memory(&p, 3);  // 这个该怎么释放呢?
}
// 数组指针:二维数组,申请连续的空间,申请简单,释放也简单
void get_memory(char (*p)[3], int row, int col){
	p = ( int(*)[3] )malloc(row * col);
}

Void des_memory(char ** p){
	free(p;)
}

 


Function pointer and function pointer

After a prejudiced relationship Semantic

Function pointer: a pointer variable pointer is the address.

A function always occupy a contiguous area of ​​memory, function names sometimes be converted first address of the memory area for the function resides in an expression, and similar to that array name.

We can put the first address of the function (or entry address) assigned to a pointer variable, the pointer variable points to the memory area where the function, then you can find through a pointer variable and call the function. (Callback function with a lot)

Function pointer appearance, is determined by the way storage function.

The function is:

  • Return Value Type;
  • Parameter Type;
  • The number;

The function prototype int pointer print (int out), and so should be long:

int (*f1) (int) = print; transfer:f1( 传print函数的实参 )

or

typedef int (*F) (int); F f2 = print; transfer:f2( 传print函数的实参 )

Pointer to the function: is a function, the function returns a pointer type.

char *get_memory(int len){
	char *p = (char*)malloc(len);
	return p;                   // 返回一个指针,堆上的内存不会自动清理
}
char *pp = get_memory(1024);  // 获取堆上的内存
Published 124 original articles · won praise 362 · views 60000 +

Guess you like

Origin blog.csdn.net/qq_41739364/article/details/105068779