C language pointer length and type deep analysis _c language

Source: Internet
Author: User
Tags arithmetic assert

The pointer is the essence of C language, this paper analyzes the length and type of C language in detail in the form of examples. It has a good reference value for beginners to understand C language programming in depth. The specific analysis is as follows:

In general, if you consider application compatibility and portability, the length of the pointer is a problem, on most modern platforms, the length of the data pointer is usually the same, regardless of the pointer type, although the C standard does not stipulate that all types of pointers have the same length, but this is usually the case. However, the function pointer length may be different from the length of the data pointer.

The length of the pointer depends on the machine and compiler used, for example: On modern windows, the pointer is 32-bit or 64-bit long

The test code is as follows:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stddef.h>
struct p{
  int n;
  float F;
};
int main ()
{
  struct P *sptr;
  printf ("sizeof *char:%d\n", sizeof (char*));
  printf ("sizeof *int:%d\n", sizeof (int*));
  printf ("sizeof *float:%d\n", sizeof (float*));
  printf ("sizeof *double:%d\n", sizeof (double*));
  printf ("sizeof *struct:%d\n", sizeof (SPTR));
  return 0;
}

The results of the operation are shown in the following illustration:

Predefined types related to pointers:

①size_t: used to safely represent length
②ptrdiff_t: for handling pointer arithmetic operations
③intptr_t: for storing pointer addresses
④uintptr_t: for storing pointer addresses

It is described as follows:

I. Type of size_t

The size_t type is defined in the standard C library and should be unsigned int, which is a long unsigned int in a 64-bit system. In the C language, this type is in the header file stddef.h. It is a machine-related unsigned type that is large enough to guarantee the size of objects in storage memory, and its purpose is to provide a portable way to declare the length consistent with addressable memory areas in the system:

Because the C + + standard defines only a minimum number of digits, not the required number of fixed digits. And in memory, the logarithmic high alignment storage or low alignment storage systems are different. In order to improve the portability of code, it is necessary to define such a data type. Generally this type will be defined as it occupies a few memory and so on. Of course, some are compilers or systems that have been defined well. The test found that the size_t was 4 bytes in a 32-bit system, while in 64-bit systems, size_t was 8 bytes, so that the type could be used to enhance the portability of the program.

The size_t type is used as the return type for the sizeof operator and is also a parameter type for many functions, including malloc and strlen

It is good practice to declare a length variable such as a character number, or an array index, and it is often used for loop counters, array indices, and sometimes for pointer arithmetic operations. size_t

Print the value of the size_t type carefully, this is an unsigned value, and if you choose the wrong format specifier, you may get unreliable results, the recommended format specifier is%zu, and in some cases you may consider using%u or%lu instead

Ii. type of ptrdiff_t

Ptrdiff_t is a machine-related data type defined in the C99 standard library, defined within the Stddef.h file. ptrdiff_t type variables are typically used to hold the results of two pointer subtraction operations.
ptrdiff_t is usually defined as a long int type, size_t is a unsigned type, and ptrdiff_t is a signed integral type.
The differences between the two types reflect their respective uses: The size_t type is used to indicate the length of the array, it must be a positive number, and the ptrdiff_t type should be sufficient to hold the gap between the two pointers in the same array, which may be negative.

#include <stdio.h>
#include <stddef.h>
#include <string.h>
int main (void)
{
  Char str[] = "Hello world!";
  char *pstart = str;
  Char *pend = str + strlen (str);
  ptrdiff_t difp = Pend-pstart;
  printf ("%d\n", difp);
  return 0;
}

Iii. intptr_t and uintptr_t types

The intptr_t and uintptr_t types are used to hold pointer addresses, which provide a portable and secure method for declaring pointers, and are useful for converting pointers to integers in the same length as the pointers used in the system. uintptr_t is an unsigned version of intptr_t

The type definitions for intptr_t are as follows:

/* Types for ' void * ' pointers. * *
#if __wordsize = =
ifndef __intptr_t_defined
typedef long int        intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned long int  uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int          intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned int    uintptr_t;
#endif

As you can see from the definition, intptr_t is not the same on different platforms, always the same number of address digits, so it is used to store addresses.

Conceptually, although the address is a pointer, memory management is often better done using an unsigned integer type; The kernel treats physical memory as a large array, and the memory address is just an array index. Further, a pointer is easy to dereference; When dealing directly with memory access, you almost never want to dereference this way. Using an integer type avoids this dereference, thus avoiding bugs. As a result, the usual memory addresses in the kernel are often unsigned long, taking advantage of the fact that pointers and long integers are always the same size, at least on all platforms currently supported by Linux. The C99 standard defines the intptr_t and uintptr_t types to give an integer variable that can hold a pointer value

Test code:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdint.h> #include < string.h> #include <assert.h> #define ID_STR_LEN #define NAME_STR_LEN typedef struct Student {char ID
  [Id_str_len];
  Char Name[name_str_len];
uint8_t age;

}student;
  Student * Create_student () {Student *stu = (student *) malloc (sizeof (student));
  if (stu = null) return null;
  memset (Stu, 0, sizeof (student));
return Stu;
  } void *free_student (student *stu) {if (Stu) free (STU);
return 0;
  } static void Init_student (Student * stu) {assert (STU);
  const char *id = "2013112210";
  const char *name = "Anker";
  uint8_t age = 21;
  memcpy (Stu->id, ID, strlen (ID));
  memcpy (stu->name, Name, strlen (name));
Stu->age = age;
  The static int handle_student (intptr_t handle) {if (handle = = 0) {return-1;
  } Student *stu = (student*) handle;
  printf ("ID:%s\n", stu->id);
  printf ("Name:%s\n", stu->name); printf ("Age: %u\n ", stu->age);
return 0;
  int main (void) {student *stu;
  Stu = Create_student ();
  Init_student (Stu);
  Converts a pointer to a intptr_t type intptr_t handle = (intptr_t) Stu;
  Handle_student (handle);
  Free_student (Stu);
return 0;

 }

I hope that the examples described in this article will help you with the learning of C programming.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.