c language - an array of pointers face questions

Reproduced

Note: All topics are summarized in the network as well as interview questions I've ever seen, please add!

No special cases described below are all questions s mesh linux 32 bit C under program.

 First to a few simple warm up.

1, sizeof the calculated value.

char str1 [] = { 'A', 'B', 'C', 'D', 'E'}; 
char str2 [] = "ABCDE"; 
char * PTR = "ABCDE";
char Book [] [80 ] = { "Fundamentals of computer application", "C language", "C ++ programming", a "data structure"};

sizeof(str1)=?   

sizeof(str2)=? 

sizeof(ptr)=?

sizeof(book)=?

sizeof(book[0])=?

analysis:

sizeof (str1) = 5, is 5 * sizeof (char) = 5;

sizeof (str2) = 6, are based on the string '\ 0' end, the number of bytes occupied by 6;  

sizeof (ptr) = 4, ptr is a pointer, on the size of the platform 32 is 4 bytes;

sizeof (book) = 320, book is a two-dimensional array, a 4 * 80 *

sizeof (book [0]) = 80, book [0] is the first dimension of the array, because the 80 * 1

The number of array elements required sizeof is also very simple, take the first, is to sizeof (str1) / sizeof (char).

 

2, the above calculation is seeking the number of bytes occupied by them, let's look at how the actual length of a string or array demand. Strlen value calculated below.

char  arryA[] = {'a','b','c','\0','d','e'};
char  arryB[] = {'a','b','c','d','e'};
char  arryC[6] = {'a','b','c','d','e'};
char *str = "abcde";

analysis:

strlen (arryA) = 3, strlen encounter '\ 0' will return, no matter how many characters back;

strlen (arryB) length can not be determined, no one write '\ 0', strlen will continue until the calculated found at the end, the result is unknown;

strlen (arryC) = 5, specifies the size of the array, the compiler will automatically add the spare areas '\ 0', which in fact with the char arryC [6] = { 'a', 'b', 'c', 'd' , 'e', ​​'\ 0'}; equivalent.

strlen (str) = 5, not including the trailing '\ 0'.

 From the above two we look at the difference between sizeof and strlen:

(1), sizeof is a C language unary operator, similar ++ - like;

    The type of data, sizeof (type), such as sizeof (int)

    A variable, sizeof (var_name)

    Note: sizeof function type can not be used, or incomplete type bit field. Incomplete type refers to the data storage size of an unknown type, such as an array type storage of unknown size,

       Unknown content structure or union type, void type. For example: sizeof (max), if this time variable is defined as max int max (); sizeof (char_v), this time char_v

       It is defined as char char_v [MAX] and MAX is unknown.

(2), strlen is a function, which is a prototype unsigned int strlen (char * s);

     Calculated streln must rely on the character sequence '\ 0', determines the character by character sequence is ended.

 

3, Bluff char str [] and char * str

(1) The following operations it legitimate? Wrong, would be at that stage? Compile-time or run time?

STR char [] = "Hello"; 
STR [0] = 'S'; // legitimate it 

char * STR = "Hello"; 
P [0] = 'S'; // What legitimate

analysis:

Both can be successfully compiled, but the second section will errors at run time. Let's analyze:

First, "hello" is a string constant, stored in the static data area (data segment), which is determined at compile time to. The first is to assign a string constant to a variable (global variable in the data segment, the local variable stack area), the string constants are actually copied to the memory variable, and therefore only the modified STR [] of the variable value.

The second is to assign the first address of the string constant to p, p-operation is to modify the string constants! So there have been mistakes.

 (2) understand the above knowledge, judgment about the following true or false?

Copy the code
char str1[] = "abc";
char str2[] = "abc";

const char str3[] = "abc";
const char str4[] = "abc";

const char *str5 = "abc";
const char *str6 = "abc";

char *str7 = "abc";
char *str8 = "abc";

cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
Copy the code

 analysis:

The result: 0011

First understand str1, str2, str3, str4, what are they? They are the name of the array, which is the address of the first element of the array! "Str1 == str2" essentially address comparing two arrays are not the same. We said above, the compiler assigns them a new storage space to copy the string "abc", in memory of these variables are independent of each other, so their addresses certainly different!

Then understand str5, str6, str7, str8, what are they? They are pointers, their value is the string constant address! They point to static data area "abc" is located, so they are equal.

(3) deeper: The following program has a problem? Where any problem lies in? How to modify?

Copy the code
#include <stdio.h>
char *returnStr() {   char p[]="hello world!";   return p; } int main() {   char *str = NULL;   str = returnStr();   printf("%s\n", str);   return 0; }
Copy the code

analysis:

p is a local variable, but the string "hello word!" carried a copy of the local variables are stored in the stack when the function exits, the stack is empty, p will be released, and therefore returns a has been released memory address, this is wrong.

It can be modified as follows:

Copy the code
#include <stdio.h>
char *returnStr() {   char *p = "hello world!";   return p; }
int main() {   char *str = NULL;   str = returnStr();   printf("%s\n", str);   return 0; }
Copy the code

Written so there is no problem, because the "hello world!" Static data stored in the area, the home address assigned to the pointer p and return, even if returnStr function exits, it would not be a string constant memory location recovery, it is possible to access the string constant.

Of course, you could be so modified:

Copy the code
#include <stdio.h>
char *returnStr() {   static char p[] = "hello world!";   return p; }
int main() {   char *str = NULL;   str = returnStr();   printf("%s\n", str);   return 0; }
Copy the code

Use the keyword static, static local variable will be modified on the data segment, even if returnStr function exits, it will not recover the memory space.

 

 4, the array as a function of transmission parameters

 We tend to put the array as a function of the parameters, so what's the problem look at the following function:

Copy the code
int func(int a[])
{ int n = sizeof(a)/sizeof(int); for(int i=0;i<n;i++)
   { printf("%d ",a[i]); a[i]++; } }
Copy the code

Only to find that the value of n is always 1! Why is this so? This is because in C, when the array is passed to a function that can not be passed by value, but will automatically degenerate as a pointer. In fact, the wording of the following three are equivalent:

"Int func (int a [20]);" equivalent to "int func (int a []);" equivalent to "int func (int * a);".

 

5, the number of those pits two exchange 

The following codes would like to achieve two number exchange, what is the problem?

Copy the code
void swap(int* a, int* b)  
{  
    int *p;  
    p = a;  
    a = b;  
    b = p;  
} 
Copy the code

 analysis:

Run the program to call the function, the argument on the stack push and Assigning new space, passed in at this time is actually a copy, as shown below:

With a value of b is the address of the exchange values ​​of a and b, but the two exchanged addresses only, it said just change the address of a copy of it, the address pointed to an object did not change! .

The correct way is this:

Copy the code
void swap(int* a, int* b)  
{  
    int tmp;  
    tmp = *a;  
    *a = *b;  
    *b = tmp;  
} 
Copy the code

Although a and b are copies, but directly inside the function changes the value of the object at that address, the corresponding argument to follow changes.

 In fact, the nature and value of passing a pointer value is passed passed passed by value is passed to a copy of the variable transmission. Copied, and the address of the argument parameter does not have any contact address, changes to the parameter address does not affect the argument, but changes to the parameter address of the object pointed able to directly reflected in the argument, which parameter is because the object points is the object argument. For this reason, we pass a pointer as a parameter, use const be modified parameter is to prevent the address from being accidentally modified.

 

6, should be taken as a pointer function parameters

What's wrong with the following code? Run what will happen?

Copy the code
void GetMem(char *p)
{
    p = (char*)malloc(100);   
}

void main()
{
    char *str = NULL;
    GetMem(str);
    strcpy(str, "hello word!");

    printf(str);
}
Copy the code

 analysis:

program crash. In the above it has been analyzed, with GetMem to transfer only a copy of the parameter, modify the parameter p does not bother address argument str. So that str or str, still NULL, then the copy to an empty string constants address, will inevitably lead to a crash. The following methods can solve this problem:

Copy the code
void GetMem (char ** P) 
{ 
    * P = (char *) the malloc (100);    
} 

void main () 
{ 
    char * STR = NULL; 
    GetMem (& STR); 
    strcpy (STR, "Hello Word!"); 
    the printf (STR); 
   free (STR); // not cause a memory leak free }
Copy the code

It seems a bit obscure, in fact well understood. Essentially let the pointer variable str points to the first address of the new malloc memory, which is assigned to the first address to the pointer variable str. We have said before, is essentially passing a pointer value is passed, in order to modify the value of str Functions, must pass a pointer to point to str, and therefore sub-functions to be transferred is the address of str, so by modifying the value of the pointer str way the malloc memory first address assigned to str.

 

7, an array of pointers doubts

(1) tell the meaning of the following expressions?

int *p1[10];
int (*p2)[10];

 The first is a pointer to an array, first of all he is an array, the elements are pointers.

The second is an array of pointers, first of all he is a pointer to an array.

Image below can clearly explain:

(2) write the following program running results

int a[5] = { 1, 2, 3, 4, 5 };  
int *ptr = (int *)(&a + 1);  
printf("%d,%d", *(a + 1), *(ptr - 1)); 

analysis:

答案是2,5。本题的关键是理解指针运算,”+1“就是偏移量的问题:一个类型为T的指针移动,是以sizeof(T)为单位移动的。

a+1:在数组首元素地址的基础上,偏移一个sizeof(a[0])单位。因此a+1就代表数组第1个元素,为2;

&a+1:在数组首元素的基础上,偏移一个sizeof(a)单位,&a其实就是一个数组指针,类型为int(*)[5]。因此&a+1实际上是偏移了5个元素的长度,也就是a+5;再看ptr是int*类型,因此"ptr-1"就是减去sizeof(int*),即为a[4]=5;

a是数组首地址,也就是a[0]的地址,a+1是数组下一个元素的地址,即a[1];  &a是对象的首地址,&a+1是下一个对象的地址,即a[5]。

 

8、二级指针疑问

给定声明 const char * const *pp;下列操作或说明正确的是?

(A)pp++  (B)(*pp)++  (C)(**pp)=\\c\\;  (D)以上都不对

分析:

答案是A。

先从一级指针说起吧: 
(1)const char p  :  限定变量p为只读。这样如p=2这样的赋值操作就是错误的。 
(2)const char *p : p为一个指向char类型的指针,const只限定p指向的对象为只读。这样,p=&a或  p++等操作都是合法的,但如*p=4这样的操作就错了, 因为企图改写这个已经被限定为只读属性的对象。 

(3)char *const p : 限定此指针为只读,这样p=&a或  p++等操作都是不合法的。而*p=3这样的操作合法,因为并没有限定其最终对象为只读。 
(4)const char *const p :两者皆限定为只读,不能改写。 
再来看二级指针问题: 
(1)const char **p : p为一个指向指针的指针,const限定其最终对象为只读,显然这最终对象也是为char类型的变量。故像**p=3这样的赋值是错误的, 而像*p=? p++这样的操作合法。 

(2)const char * const *p :限定最终对象和 p指向的指针为只读。这样 *p=?的操作也是错的,但是p++这种是合法的。 
(3)const char * const * const p :全部限定为只读,都不可以改写

 

9、*p++、 (*p)++、 *++p、 ++*p

    int a[5]={1, 2, 3, 4, 5};

int *p = a;

*p++ 先取指针p指向的值(数组第一个元素1),再将指针p自增1

cout << *p++; // 结果为 1

cout <<(*p++); // 1

(*p)++ 先去指针p指向的值(数组第一个元素1),再将该值自增1(数组第一个元素变为2
cout << (*p)++; // 1
cout <<((*p)++) // 2
*++p 先将指针p自增1(此时指向数组第二个元素),* 操作再取出该值

cout << *++p; // 2
cout <<(*++p) // 2

++*p 先取指针p指向的值(数组第一个元素1),再将该值自增1(数组第一个元素变为2)
cout <<++*p; // 2
cout <<(++*p) // 2

 

参考博客:

1、《C语言中sizeof 与strlen 区别 》:http://www.cnblogs.com/kungfupanda/archive/2012/12/24/2831273.html

2, "Why the constant string is located in static memory? ": Https: //blog.csdn.net/ebw123/article/details/51388340

3, "the value of transfer, transfer pointer, passed by reference difference": https: //blog.csdn.net/koudan567/article/details/51298511

4, cattle off network mlc answer: https:? //Www.nowcoder.com/test/question/done tid = 16211084 & qid = 1409 # summary

Guess you like

Origin www.cnblogs.com/cyyz-le/p/11514477.html