Native C
1) Is there any official documentation for C Programming ?
link - learn.microsoft.com/en-us/cpp/c-language/?view=msvc-170
2) Is C an Interpreted or Compiled language ?
C is Compiled.
This means there is a build/compile step.
The compiler needs to take the code, process it and create a binary executable.
3) Is C a Strongly or Weakly Typed programming language ?
C is Weakly Typed.
It allows implicit type conversion when data types are not compatible.
There is aggressive implicit type conversion.
char letter = 'A'; // ASCII value is 65
int number = 10;
double result;
result = letter + number;
printf("Result: %f\n", result); // Outputs: 75.00
4) Is C a Dynamically or Statically Typed programming language ?
C is Statically Typed.
You must declare a variable's type before using it, and that variable's type can never change during execution.
If you declare a variable to be an int data type, it will always be an int.
int myNumber = 10;
char myLetter = 'A';
double myPrice = 10.35;
5) Is C an Object Oriented or Functional programming language ?
C is neither an Object Oriented nor a Functional programming language.
It is classified as a Procedural programming language which does not support classes or any object oriented principles.
To achieve something similar you create a user defined type (using struct) and define specific functions that operate on that type.
typedef struct {
char name[20];
int age;
} Person;
void Person_Init(Person *P,
const char *name,
int age)
{}
void Person_Method(const Person *p)
{}
// usage
Person P;
Person_Init(&p, "Simon", 20);
Person_Method(&p);
6) What is the latest version of the C Programming language.
This is C23, released in 2024.
7) Do I need to use C++ to create my XLL ?
Some of the SDK files are in C++ but all the changes can be made using C.
The C programming language in 1997 (C89) was very different to the 2024 (C23) version.
The following are now all possible.
mixed declarations and statements
loop local variables
boolean data type
64 bit integer support (long long)
standard threading support and atomics (_Thread_local)
dedicated null pointer (nullptr)
C++ style comments (//--)
8) What is a Header file ?
Header files (such as <stdio.h> or <stdlib.h>) declare built-in functions, constants, and macros.
The #include preprocessor directive tells the compiler to insert the contents of that header file before compiling the code.
9) Can you give some examples of header files ?
#include <assert.h> // Contains the assert macro, detect logical errors and other types of bugs
#include <complex.h> // Contains functions for manipulating complex numbers
#include <ctype.h> // Contains functions for examining and converting individual characters
#include <errno.h> // Contains functions for testing error codes reported by library functions
#include <math.h> // Defines common mathematical functions
#include <stdbool.h> // Defines a boolean data type
#include <stdio.h> // Define score input and output functions
#include <stdlib.h> // Defines numeric conversion functions, random numbers and memory allocation
#include <string.h> // Defines string handling functions
#include <time.h> // Defines date and time handling functions
#include <windows.h> // Includes declarations, constants, structures and other definitions
#include <winhttp.h> // A thread safe, optimised http windows service
10) What is a Pointer ?
Also called a pointer variable, this is a special variable that points to an address in memory.
To declare a pointer you use the dereference operator (or star operator).
int *my_ptr; // this is the preferred syntax
int* my_ptr;
11) Can a pointer refer to a normal variable ?
Yes. To obtain a memory address from a variable you can use the address operator (or ampersand operator).
int myval = 46;
int *myptr = &myval;
int myval2 = *myptr;
12) How do I modify a value using a pointer ?
You can use the dereference operator to read or write the value it points to.
(*myptr = 20) does not change the pointer, it changes the value that the pointer refers to.
int myval = 10;
int *myptr = &myval; // gets the memory address
*myptr = 20 // change the value
printf(*myptr); // prints 20
printf(myval); // prints 20
13) Should I always initialise a pointer ?
Yes. If you do not have a value, then always assign to NULL (which is a safe, invalid address).
int *myval = 10;
int *myval = NULL;
14) What is the main() function ?
The main() function is the only component that has to be included in every C program.
15) What happens if you dereference a pointer that is equal to NULL ?
A segmentation fault will occur.
int *myval = NULL;
if (myval == NULL) {
// not safe
} else {
free(myval)l
}
16) What happens if you dereference an uninitialised pointer ?
An uninitialised pointer contains completely unpredictable random data.
A segmentation fault will occur.
17) What is a segmentation fault ?
A segmentation fault is a runtime crash that occurs when your program tries to read or write to a restricted or invalid memory address.
This frequently happens in C if you dereference a NULL pointer or dereference an uninitialized pointer, or writing past the bounds of an array.
18) What are the C Programming data types ?
| Keyword | Description | Bytes | Range |
| char | character | 1 | -128 to 127 |
| short | short int | 2 | -32767 to 32767 |
| int | integer | 4 | -2,147,483,647 to 2,147,438,647 |
| long | long integer | 4 | -2,147,483,647 to 2,147,438,647 |
| unsigned char | unsigned character | 1 | 0 to 255 |
| unsigned short | unsigned short integer | 2 | 0 to 65535 |
| unsigned int | unsigned integer | 4 | 0 to 4,294,967,295 |
| unsigned long | unsigned long integer | 4 | 0 to 4,294,967,295 |
| float | single precision floating point | 4 | 1.2E-38 to 3.4E38 |
| double | double precision floating point | 8 | 2.2E-308 to 1.8E308 |
19) Is there a boolean data type ?
Yes. In C23 the boolean data type was added alongside the true and false keywords.
However C23 is not used for XLL development.
In C90 you can add #include <windows.h>.
In C99 you can add #include <stdbool.h> and use _Bool (not recommended).
#include <windows.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
20) Is there a string data type ?
No. There is not a built-in data type for storing strings.
A C String is an array of characters (char) that ends with a special marker called the null terminator (\0).
char name[] = "Richard"; // stored as R i c h a r d \0
char greeting[] = "Hello"; // Compiler automatically figures out the size is 6
char name[20] = "Alice"; // Creates a 20-byte buffer, leaves empty spaces at the end
char name[10] = "some text"; // Adding one to the length, to include the string termination character)
21) What is the difference between char* and wchar_t* ?
They are both pointers to strings.
char* text = "Hello";
The char* uses 1 byte and is used for ASCII. Often referred to as a byte string.
This should be used for the actual data being transferred as JSON.
wchar_t* text = L"Hello";
The wchar_t* uses 2 bytes and is used for UNICODE. Often referred to as a wide character string.
This should be used for the registration functions, string literals and windows API calls (not the actual data).
22) How do we do string manipulation ?
Using the standard library functions.
| Byte Strings | Wide Characters Strings |
| strlen - calculates the length of a string | wcslen |
| strchr - search for the first occurrence | wcschr |
| strncat - appends characters to the end | wcscat |
| strncmp - compares two strings | wcscmp |
| strncpy - copy characters from one string to another | wcsncpy |
23) What does LPSTR and LPWSTR stand for ?
This stands for "Long Pointer to String" and is a Windows API data type (not C or C++ specific).
typedef char* LPSTR
typedef wchar_t* LPWSTR;
24) What are these data types ?
| HWND | void* | Handle to a Window |
| UINT | unsigned int | Unsigned Integer |
| UINT_PTR | unsigned __int64 ? | Unsigned Integer Pointer |
| LPVOID | void* | Long Pointer to Void |
| LPXLOPER12 | struct xloper12* | Long Pointer to Excel Operand 12 |
25) What is DWORD ?
This is a windows API data type found in "windows.h".
typedef unsigned long DWORD
26) How can you define a constant ?
Literal constants can change during your program execution.
Symbolic constants cannot change.
// this is a literal constant
float radius = 10;
// this is a symbolic constant
const float radius = 10;
#define RADIUS 10 (no semi-colon)
27) How can you add comments ?
Both single line and multiline comments can be added.
// starts a single line comment
/* Starts a multiline comments and is ended by */
28) What are the operators ?
| Operator | Description | Precedence |
| ++ | Postfix increment (left-to-right) | 1 |
| -- | Postfix decrement (left-to-right) | 1 |
| ++ | Prefix increment (right-to-left) | 2 |
| -- | Prefix decrement (right-to-left) | 2 |
| sizeof | Size of | 2 |
| * | Multiplication (left-to-right) | 3 |
| / | Division | 3 |
| % | Modulo(remainder) | 3 |
| + | Addition (left-to-right) | 4 |
| - | Subtraction | 4 |
| < | Less than (left-to-right) | 5 |
| <= | Less than or equal to | 5 |
| > | Greater than | 5 |
| >= | Greater than or equal to | 5 |
| == | Equal to (left-to-right) | 6 |
| != | Not equal to | 6 |
| = | Direct assignment (right-to-left) | 7 |
| += | Assignment by sum | 7 |
| -= | Assignment by difference | 7 |
| *= | Assignment by product | 7 |
| /= | Assignment by quotient | 7 |
| && | Logical AND | |
| || | Logical OR |
29) What are the malloc and free functions ?
Malloc allocates memory dynamically and should be used when you want a variable to be available outside of a function.
MyType *my_obj = (MyType*)malloc(sizeof(MyType));
Free deallocates (or frees) the dynamically allocated memory. It does not delete the variable, just the data that it points to.
free (my_obj);
30) What is the difference between calloc and malloc ?
Calloc sets all ints to 0, all pointers to NULL and all strings to empty.
This takes 2 arguments. The number of elements and the size of each element.
MyType *my_obj2 = (MyType*)calloc(1, sizeof(MyType));
Malloc does not initialise and therefore requires manual initialisation by copying in the necessary data.
31) What is the difference between the Stack and the Heap ?
Stack is a fast, structured continuous memory space automatically managed by function calls
Heap is a large, flexible memory pool used for manual, dynamic allocation at runtime.
32) What is a function prototype ?
This is a declaration of a function that tells the compiler about the function's name, return type, and parameters.
Sometimes a function is called before it has actually been declared.
When a function has not been declared before it is used you need to include a function prototype above it.
static const char* fn_MyFunction(const char* json);
// code that needs to use this function
static const char* fn_MyFunction(
const char* json)
{}
33) Do my functions with no arguments needs to include void ?
No.In C23 standard, empty brackets () mean the same thing as (void).
void myFunction();
void myFunction(void);
34) Are variables passed by value or by reference ?
Everything is passed by value, by default.
// Passed by Value
void myfunc(int x) {
x = 20;
}
If you want to pass by reference, you need to use a pointer.
35) Can you give an example of passing by reference ?
In C there is no dedicated syntax for passing a value by reference.
However this can be achieved by using a pointer and passing the address of a variable.
int myval = 10;
myfunc(&myval);
printf(myval);
void myfunc(int *x) {
*x = 20; // must have an asterisk to change the value
}
In C++ the syntax is: void myfunc(int& x)
36) How can you define a user defined type ?
Also called a custom data structure.
typedef struct
{
char item1;
} MyUserDefined1
MyUserDefined1 varName1;
37) Why do you use typedef when declaring a custom data type ?
This allows you to create a user defined type and at the same time give it an alias name.
Using an alias name means you do not have to include the struct keyword every time you declare a new variable of this data type.
struct MyUserDefined2
{
char item1;
}
struct MyUserDefined2 varName2;
38) Can you have static variables ?
Yes. This will create a static local variable.
Initialized only once when the program starts. When the function exits, the variable retains its current value. The next time you call the function, it picks up right where it left off.
void countCalls() {
static int counter = 0;
39) What does static infront of a function mean ?
When you put static in front of a global variable or a function at the top-level of a file, it acts as an access modifier.
It limits the visibility of that item to that specific file only.
static int secretData = 100;
static void privateHelper() {
40) What does inline mean infront of a function name ?
This tells the compiler to replace a function call directly with the function's actual code during compilation.
Every time a standard function is called, there is a small amount of overhead, so doing this can increase performance.
This overhead can often take more time than executing the actual function itself.
inline int square(int x)
{
return x * x;
}
41) What are Excel4, Excel12, XLOPER and the XLOPER12 structures?
These are the primary framework callback functions and data structures used to pass data to and from Excel.
Excel4 uses XLOPER and supports 256 columns and 65,536 rows.
Excel12 was introduced with Excel 2007, uses XLOPER12, supports Unicode, and supports 16,384 columns and 1,048,576 rows.
42) What is the difference between xlbitXLFree and xlbitDLLFree with regards to memory handling ?
xlbitXLFree - Set by Excel when it returns a value to your DLL.
xlbitDLLFree - Set by your C function when returning data back to an Excel cell. It then calls xlAutoFree12() hook so my C code can safely free its own memory"
43) Can a C API function be called from background worker threads?
No. The C API is strictly single-threaded on Excel's main thread.
You cannot spawn an arbitrary background thread in C and call back into Excel via Excel12().
44) What functionality was added in Excel 2010 to help with multi threading ?
In Excel 2010 it became possible to declare asynchronous user defined functions.
A native async UDF splits execution into two parts: a synchronous entry point that immediately returns control to Excel's calculation engine (keeping Excel responsive), and an asynchronous worker thread that handles the heavy lifting
The xlAsyncReturn callback specifically so background processes could safely drop results back into Excel's main thread loop once finished.
link - learn.microsoft.com/en-us/office/client-developer/excel/asynchronous-user-defined-functions
45) What is WINAPI ?
__declspec(dllexport) int WINAPI xlAutoOpen
#const WINAPI __stdcall
The WINAPI is just a macro/constant definition
Any function that you want to call from Excel must include the modifier "__stdcall"
46) What is __stdcall ?
int __stdcall xlAutoOpen
This is a windows calling convention that defines stack cleanup, argument passing and symbol naming
This function cleans up the stack automatically.
47) What is __cdecl ?
This is a windows calling convention that defines stack cleanup, argument passing and symbol naming
The function does not clean up the stack and relies on the caller to do it.
This is the default on Win32.
48) What is DWORD ?
This is a windows API data type found in "windows.h".
typedef unsigned long DWORD
49) What is HANDLE ?
This is a Windows defined data type used to refer to a resource that is managed by WIndows.
Examples include threads, processes, files, registry keys
50) What calling convention is used in 64-bit Excel.
__stdcall is the only convention that is used.
pg 93
51) What is __declspec() ?
This is a Microsoft compiler extension (MSVC) and is short for declaration specification.
This line of code is a function declaration designed to create a custom Excel worksheet function inside an XLL.
__declspec(dllexport) LPXLOPER12 WINAPI my_new_function()
52) What is extern "C" ?
This is a C++ compiler directive that can be used to tell the compiler to export this symbol as if it was written in C.
This tells the compilter not to apply C++ name mangling.
extern "C" __declspec(dllexport)
53) What is #pragma ?
This is a C compiler directive that embeds instructions inside the compiled object file (.obj).
# pragma comment(lib, "oleauto32.lib")
A pragma is a special instruction to the compiler.
The program being used on this line is called "comment" which means add this library when the file is compiled
54) What does this mean ?
static const char* MyFunction()
This declares a function that returns a pointer to a string that must not be modified.
The static means that the function is only visible in this particular (.c) file.
55) What does this mean ?
BOOL WINAPI DllMain()
This is a callback function that Windows calls automatically when your XLL is loaded/unloaded and runs before xlAutoOpen.
56) What does this mean ?
if (!work -> response){
free(work);
return 0;
}
The -> operator means dereference a pointer to a struct and then access one of its members.
The ! is the not operator, this is checking if the response pointer is not equal to NULL.
typedef struct {
char *response
} WORK
WORK *work;
57) Write a For loop
for (i=0; i<10; i++) {
}
58) Write a While loop
while (true) {
break / continue
}
59) How do you declare an array ?
Array names are just pointers to the first element in the array.
int arr[3] = { 1 , 2 , 3 };
int *ptr = arr;
int *ptr2 = &arr[0];
60) How do you declare a multi-dimensional array ?
int multi[x][y]
61) How do you loop through an array ?
int arr[3] = { 1 , 2, 3 };
for (int i=0, i<3, i++)
printf(arr[i]);
}
62) Can you have line labels ?
Yes. Using the keyword goto.
goto myLineLabel;
myLineLabel:
63) Can you explain the printf function ?
This function can send formatted text directly to the standard output stream.
This is not type-safe and there is a risk of buffer overrun.
#include <stdio.h>
printf("formt string", arg1, arg2, ..);
%d - signed integer (int)
%i - signed integer (int)
%f - floating point number (float/double)
%c - single character (char)
%s - strings of characters (text)
64) Can you explain the sprintf function ?
This is a function in the <stdio.h> that formats and stores a series of characters and values into a string buffer.
65) What is the difference between sprintf and sprintf_s ?
sprintf only takes the destination buffer and the format string.
If your text is 100 characters long but your buffer is only 10 bytes, it will overwrite adjacent memory.
sprinf_s forces you to pass the maximum size of your buffer as a second argument.
sprintf_s(message, sizeof(message), "I am %d years old.", age);
66) Can you explain the scanf function ?
This function reads input from the standard input stream, which is typically the user's keyboard.
#include <stdio.h>
int main() {
int x;
printf("Enter a number: ");
scanf("%d", &x);
printf("You entered: %d\n", x);
return 0;
}
67) Can you explain the difference between the strcpy and the strcpy_s functions ?
strcpy_s is the modern, bounds-checked alternative introduced to prevent memory corruption and security vulnerabilities.
68) What is the difference between ++i (pre-increment) and i++ (post-increment) ?
Pre-increment (++i) increments the value of i first and then uses the new value in the expression.
Post-increment (i++) uses the current value of i in the expression first and then increments i afterward.
69) Are there any suggested naming conventions ?
lower case - function names
lower case - variables (with underscores)
proper case - Excel functions (no underscores)
70) What does it mean when an argument is prefixed with (void) ?
void MyFunc(int x, int y)
{
(void)x;
printf("%d\n",y);
}
The x argument is being intentionally ignored.
The value of x is being converted to the type void and the result is being discarded.
When working with Windows API some of the callback functions must have a fixed signature.
When your code doesn't use a parameter you should use the (void) syntax to avoid the compiler generating an unnecessary warning.
71) How can you do error handling ?
There is no built-in try-throw-catch mechanism.
BOOL Success;
Success = DoSomething();
if (!Success)
{
return 0;
}
© 2026 Better Solutions Limited. All Rights Reserved. © 2026 Better Solutions Limited TopPrevNext