Embedded c language interview questions summary

Pointer definition

A pointer to a pointer, the pointer it points to is an integer
int **a;
an array of 10 pointers, the pointer is an
int *a[10] that points to an integer ;
a pointer has 10 A pointer to an array of integers
int (*a)[10]
A pointer to a function that has an integer parameter and returns an integer
int *a( int ){}
An array of 10 pointers, The pointer points to a function that has an integer parameter and returns an integer number
int (* a[10])( int) //Similar to this definition should be done by decomposition. First define a single function pointer int (*a)(int), and then an array of 10 pointers int (*a[10])(int)

What is the purpose of the keyword static?


1) In the function body, a variable declared as static maintains its value unchanged during the process of calling the function (the variable is stored in the static variable area).
2) In the module (but outside the function), a variable declared as static can be accessed by functions used in the module, but not by other functions outside the module. It is a local global variable.
3) In a module, a function declared as static can only be called by other functions in this module. That is, this function is restricted to the local scope of the module where it is declared

Keyword const


const int a; constant a
int const a; constant a
const int *a; The content pointed to by the pointer cannot be modified, but the address pointed to by the pointer can be modified.
int * const a; The place pointed to by the pointer cannot be changed, but the content of the pointed address can be changed.
int const * const a; The contents of the address pointed to by the pointer and the address pointed to by the pointer cannot be modified.

The first one sets bit 3 of a, the second one clears bit 3 of a


a |= 1 << 3
a &= 0 << 3
或BIC a,a,#0x3

Signed and unsigned numbers


8. What is the output of the following code and why?
void foo(void)
{ unsigned int a = 6; int b = -20; (a+b> 6)? puts("> 6"): puts("<= 6"); } is greater than 6. A signed number is converted to an unsigned number. Unsigned number: There is no difference between positive and negative, all bits are used to represent the number itself. Signed number: The highest bit is used to indicate the positive and negative of the number, the highest bit is 1 to indicate a negative number, and the highest bit is 0 to indicate a positive number. 1. Convert an unsigned number to a signed number: see if the highest bit of the unsigned number is 1, if it is not 1 (ie 0), the signed number is directly equal to the unsigned number; 2. If the unsigned number is The most significant bit is 1, the unsigned number is complemented, and the number obtained is a signed number. 3. Convert a signed number to an unsigned number: to see if the highest bit of the signed number is 1, if it is not 1 (ie 0), the unsigned number is directly equal to the signed number; 4. If there is a signed number The highest bit of is 1, then the signed number will be complemented, and the number obtained is an unsigned number, so 6-20 = -14, because the result has overflowed as an unsigned number, so 65536 is added and the result becomes one A positive number is 65522 -5 corresponds to a positive number 5 (00000101) → all bits are inverted (11111010) → plus 1 (11111011)












\0Question

void test1()
{ char string[10]; char* str1 = "0123456789"; strcpy( string, str1 ); } //Overflow and \0




void test2()
{ char string[10], str1[10]; int i; for(i=0; i<10; i++) { str1[i] ='a'; } strcpy( string, str1 ); } str1 has no \0 terminator and the program crashes.








void test3(char* str1)
{ char string[10]; if( strlen( str1) <= 10) { strcpy( string, str1 ); } } is changed to strlen( str1) <10 This method will not report an error, but It will cause hidden serious bugs and modify the data in the memory.





Please calculate the value of sizeof and the value of strlen.


void func ( char *str )
{
sizeof( str ) = ?
}
char str[10] = “hello”;
strlen(str);
10和5

Macro definition problem

#include "stdafx.h"
#define SQR(X) X*X
int main(int argc, char* argv[])
{
    int a = 10;
    int k = 2;
    int m = 1;
    a /= SQR(k+m)/SQR(k+m);
    printf("%d\n",a);
    return 0;
}
a =a/ (k+m*k+m/k+m*k+m)

How to judge whether an operating system is 16-bit or 32-bit when writing a program in C? The sizeof() function cannot be used.


int a = ~0;//把位数全部设为1
if( a>65536 )  
{
  cout<<"32 bit"<<endl;
}
else
{
  cout<<"16 bit"<<endl;
}

Without using third-party parameters, exchange the values ​​of the two parameters.


a = a + b;
b = ab;
a = ab;
someone
a = a ^ b;
b = a ^ b;
a = a ^ b;

Pointer operation

unsigned short array[]={1,2,3,4,5,6,7};
int i = 3;
*(array + i) =? The
result is 4.

main()
{ int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1);// (&a+1) points to the next one-dimensional array printf ("%d,%d",*(a+1),*(ptr-1)); } Solution: int *ptr=(int *)(&a+1);&a means to get the first of the storage area of ​​array a Address, plus 1 to indicate the address of the storage area of ​​array a, which makes the ptr pointer point to the address of the storage unit after the last element of the array, and after ptr is subtracted by 1, data access is performed, and the access is ptr The value of the previous storage unit of the pointer, all the final answer is 2, 5 (int *)(&a+1) The pointer type is forced to be converted.







What is the difference between #include <filename.h> and #include "filename.h"?


<> will go directly to the system to traverse
"" will first traverse the header file in the current project, if it does not exist, go to the system traverse.
<> can be changed to "", but "" must not be changed to <>

The parameter types that cannot be used as switch() are:


Only integers can be used as parameters

Can local variables have the same name as global variables?


Can have the same name. Local variable names will override global variable names. C++ can use scope to distinguish.
Can global variables be defined in header files that can be included by multiple .C files? why?
No! But it can be declared. This involves the issue of strong symbols and weak symbols. For details, please refer to the following blog.
In C language, functions and initialized global variables (including initialization to 0) are strong symbols, and uninitialized global variables are weak symbols.
For them, the following three rules are used:
① There can only be one strong symbol with the same name, otherwise the compiler will report a "duplicate definition" error.
② One strong symbol and multiple weak symbols are allowed, but the definition will select the strong symbol.
③ When there are multiple weak symbols that are the same, the linker chooses the one that occupies the largest memory space.

One sentence realizes the judgment of whether x is a power of 2.


if (x & (x-1) == 0)
    printf("is a power of 2");
  else printf("is not a power of 2");

pow(x,y), calculate the y power of
x sqrt(x), find the square root of the floating-point number x
fabs(x), find the absolute value of the floating-point number x

char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
What's wrong?


Constant area does not allow to modify the content, the result remains unchanged. AAA

#define MAX 256
int main()
{
unsigned char A[MAX],i;
for (i=0;i<MAX;i++)
A[i]=i;
}


Char is one byte, eight bits, and the largest integer that can be represented is 255, so there is an endless loop here.

35.struct name1
{
char str;
short x;
int num;
}
struct name2
{
char str;
int num; 
short x; 
}
typedef struct 
{
    int a;
    char b[3];
    short d;
    int c;
 } node;
sizeof(struct name1)=8
sizeof(struct name2)=12
sizeof(node) = 16


Byte alignment

int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}


No memory is allocated for a, and a is a character variable. The memory is out of bounds.

Address and variable size operations

unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000; may
I ask p1+5 = 0x801005; p2+5 = 0x810014;
the value of the output p1+5 is 801005 , Because the value character pointed to by the pointer variable, plus one means that the pointer moves backward by one byte, then add 5 means move backward by 5 bytes, so
the value of input 801005 p5+5 is 801016, because the pointer variable points to the long integer Yes, adding one means that the pointer moves backward by 4 bytes, then adding 5 means moving backward by 20 bytes, so input 810014, (in hexadecimal when output), if it is decimal, it is 810020 

There is an array definition int a[2][2]={ {1},{2,3}}; then the value of a[0][1] is 0. // For
int (*ptr) (), ptr is the name of a one-dimensional array. // Function pointer The
pointer can perform >, <,>=, <=,== operations under any circumstances. //Unknown, so
c in the switch(c) statement can be of type int, long, char, float, unsigned int. //wrong. Can only be an integer, float excluded.
Without using library functions, write the function int strcmp(char *source, char *dest) which returns 0 if it is equal, and returns -1 if it is not;
write a function int fun(char *p) to determine whether a string is a palindrome, and return 1 if it is a palindrome , Instead of returning 0, return -1 on error

Static variable operation

#include<stdio.h>
int sum(int a)
{
int c=0;
static int b = 3;//静态
c+=1;
b+=2;
return(a+b+c); 
}
int main()
{
int I;
int a=2;
for(I=0;I <5;I++)
{
printf("%d,", sum(a));
}
return 0;
}
8,10,12,14,16,

The one that must be able to print "hello" is 134, and the error is 2


char *GetHellostr(void);
int main(void)
{
char *ps;
ps= GetHellostr( );
if(ps != NULL)
{
printf(ps);
}
return 0;
}
(1)
char *GetHellostr(void)
{
char *ps=“hello”;
return ps;
}
(2)
char *GetHellostr(void)
{
char a[]=“hello”;
return (char *)a;  内存已经被释放了
}
(3)
char *GetHellostr(void)
{
static char a[]=“hello”;
return (char *)a;
}
(4)
char *GetHellostr(void)
{
char *ps;
ps = malloc(10);
if(NULL ==ps) return NULL;
strcpy(ps,”hello”);
return ps;
}

String function

char* strcpy(char* strDest,const char* strSrc)
{
    assert(strDest!=NULL && strSrc!=NULL);
    char* strTmp = strDest;
    while(*strSrc!='\0')
    {
        *strDest++ = *strSrc++;
    }
    strDest = '\0';
    return strTmp;
}

int strlen(const char*strSrc)
{
    assert(strSrc!= NULL);
    int len = 0;
    while((*strSrc++)  != '\0')
        ++len;
    return len;
}

char* strcat(char* strDest,const char* strSrc)
{
    assert((strDest != NULL) && (strSrc != NULL));
    char* strTmp = strDest;
    while(*strDest != '\0')
        ++strDest;
    while(*strDest++ = *strSrc++);
    *strDest++ = '\0';
    return strDest;
}

Double pointers and pointer references

void foo(char **p)//双指针
{
    *p = "after";
}
int main()
{
    int *p = "befor";
    foo(&p);
    cout << p << endl;//输出的为after
    return 0;
}

void foo(char *&p)//pointer reference
{     p = "after"; } int main() {     int *p = "befor";     foo(p);     cout << p << endl;//output For after     return 0; }








Reasons for using assembly language:


First: The execution speed of assembly language is higher than that of c language.
Second: startup code, when writing bootloader and kernel, it is mainly used when initializing cpu and memory. Because there is still no environment written in C language (the stack has not been established) at this time, the C language cannot be used.

#ifndef X
#define X
...
#endif


Prevent header files from being repeatedly included and compiled.

The difference between pointer and array.


The first different array of storage methods is the stored member content itself. The pointer stores the first address.
The second is the difference in calculation methods. The array name is a constant that cannot be incremented or decremented, while the pointer is a variable, which can be incremented and decremented.
The third is the operation of assignment operation. The array can be initialized, but the overall assignment cannot be done through the assignment statement, and the pointer can point to another statement.

Why does strcpy return char*


The value returned by the strcpy function can be used as the actual parameter of another function to achieve chain operation.

IIC introduction:


Start signal: When SCL is high, SDA jumps from high to low and starts to transmit data.
End signal: When SCL is high level, SDA jumps from low level to high level, ending the data transmission.
Response signal: After receiving the 8bit data, the IC receiving the data sends a specific low-level pulse to the IC sending the data to
indicate that the data has been received. After the CPU sends a signal to the controlled unit, it waits for the controlled unit to send a response signal.
After receiving the response signal , the CPU determines whether to continue to transmit the signal according to the actual situation. If no response signal is received, it is judged that the
controlled unit is faulty.

//IIC sends a byte
//returns whether the slave
has an answer //1, has an answer
//0, no answer
void IIC_Send_Byte(u8 txd)
{ u8 t; SDA_OUT(); IIC_SCL=0;//Lower the clock Start data transmission for(t=0;t<8;t++) { IIC_SDA=(txd&0x80)>>7; txd<<=1; delay_us(2); //For TEA5767 these three delays are all necessary IIC_SCL =1;delay_us(2); IIC_SCL=0; delay_us(2); } } //Read 1 byte, when ack=1, send ACK, ack=0, send nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SDA_IN();//SDA is set as input for(i=0;i<8;i++) { IIC_SCL=0; delay_us(2); IIC_SCL=1; receive<<=1; if (READ_SDA)receive++;























delay_us(1);
}
if (!ack) IIC_NAck();//Send nACK
else IIC_Ack(); //Send ACK
return receive;
}

Guess you like

Origin blog.csdn.net/qq_38531460/article/details/103326672